From 0bfe4fe8a71cf2a0c27f601031d90072da3149b1 Mon Sep 17 00:00:00 2001 From: Jesse Gardner Date: Thu, 18 Mar 2021 18:04:08 -0700 Subject: [PATCH] more documentation --- man.md | 541 +++++++++++++++++++++++++++++++++++++++++++ pandoc_gen_docs | 3 + qq2clone.1 | 601 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1145 insertions(+) create mode 100644 man.md create mode 100755 pandoc_gen_docs create mode 100644 qq2clone.1 diff --git a/man.md b/man.md new file mode 100644 index 0000000..5225650 --- /dev/null +++ b/man.md @@ -0,0 +1,541 @@ +NAME +==== + +qq2clone - Create and manage QEMU/KVM VMs using template machines and +qcow2 images with backing files + +SYNOPSIS +======== + +**qq2clone** \[*OPTION*\]… *COMMAND* \[*ARG*\]… + +DESCRIPTION +=========== + +**qq2clone** is a tool working on top of virsh that makes creating +clones of template QEMU/KVM machines simple. By using the copy on write +feature for which qcow2 is named, clones of an existing virtual machine +can be made without inadvertently altering the original image (with +caveats - read the **LIMITATIONS** section if you aren’t already +familiar with how copy on write works). **qq2clone** makes creating and +managing these clones simple and efficient. + +**qq2clone** supports creating numerous clones of a template and +performing batch operations on them - including the execution of +arbitrary commands with exec. This simplifies workflows involving large +numbers of virtual machines, or the frequent creation/destruction of +virtual machines. + +In addition to virsh, basic linux utilities and QEMU/KVM, qq2clone +requires: + + Bash 4.0+ + qemu-img + libvirt tools: + virt-clone + virt-xml + virt-xml-validate + xmllint (from libxml2) + +If you want to easily establish graphical connections to your virtual +machines, you should have virt-viewer and/or spicy installed and +configure your templates to use Spice graphics. This is not strictly +necessary, and with the use of **qq2clone** **exec** and a small script +of your own you can automate connecting to Spice/VNC clients of your +choice without too much hassle + +OPTIONS +======= + +Not every option has an effect in the context of every command. +Specifying an option that has no effect in the context of the command +being invoked will not produce an error, it simply will not do anything + +Options are parsed left to right, and right-hand options override +left-hand options. The only exception is for -Q/--quieter, which *must* +be the first option listed to work properly. + +-c, --connection \[*URI*\] +Specify a non-default connection URI: sets the value of +LIBVIRT\_DEFAULT\_URI + +-f, --no-spice +Do not attempt to connect to a virtual machine’s Spice graphics. +Overrides USE\_SPICE setting in configuration + +-g, --use-spice +Attempt to connect to a virtual machine’s spice graphics. Overrides +SPICE setting in configuration + +-h, --help +Print basic help information and exit + +-n, --no-run +After making a clone of a template, do not run it. Overrides NORUN +setting in configuration + +-q, --quiet +Suppress most non-error output. Overrides QUIET setting in +configuration. Also suppresses various prompts for user choices, either +exiting with an error or making a safe default choice depending on the +command. Recommended only once familiar with the behavior of +**qq2clone** + +-Q, --quieter +This option is (currently) required to appear immediately following the +invocation of **qq2clone**. Suppresses all output, error message or +otherwise, except when running interactive commands or commands that +require output to be useful. The commands for which output is not +entirely supressed are: config list, config info, list, list-templates, +exec, edit, modify-template edit, and check. Other commands will receive +only an exit code as output. This option is intended for calling +qq2clone from a script. + +-r, --run +Run a clone when creating it. Overrides NORUN setting in configuration + +-s, --storage \[*LOCATION*\] +When creating a clone, place new disk image file(s) at location +specified by \[*LOCATION*\]. \[*LOCATION*\] may be one of an absolute +filepath, or the name of a libvirt directory type storage pool. Also +defines where state files will be saved when using **save** command. +Overrides STORAGE option in configuration + +-S, --spicy +Use spicy rather than virt-viewer when connecting to the spice graphics +of a clone. Overrides SPICY setting in configuration + +-t, --template \[*NAME*\] +Use template of given name as context when executing a clone command +(see TYPES OF COMMAND section above). Overrides TEMPLATE option in +configuration + +-v, --verbose +Enable all output. Overrides QUIET setting in configuration + +-V, --virt-viewer +Use virt-viewer rather than spicy when connecting to the spice graphics +of a clone. Overrides SPICY setting in configuration + +TYPES OF COMMAND +================ + +There are two main classes of commands: commands that operate directly +on templates, and commands that create or operate on clones of +templates. In order to make it less likely that the user may +unintentionally invoke a command of one class when they intended to +invoke one of the other, they use a different syntax. Commands that +operate on templates use the syntax: + +**qq2clone** **command** \[*template-name*\] \[*ARG*\] … + +while commands that operate on clones use the syntax: + +**qq2clone** --template \[*template-name*\] **command** \[*ARG*\] … + +Notice that commands operating on clones work within the context of a +template defined by the option --template/-t. Conversely, commands +operating on templates specify the template as an argument to the +command. There can also be a default template defined by the TEMPLATE +option in the configuration file, allowing the --template option to be +omitted for commands that operate on clones. Commands operating on +templates do not respect this default - the template must always be +explicitly defined, further reducing the likelihood of accidentally +modifying or deleting a template. + +TEMPLATE COMMMANDS +================== + +**copy-template** \[*CURRENT-NAME*\] \[*NEW-NAME*\] +Copy the XML of template *CURRENT-NAME* to a new template with +*NEW-NAME*. The new template will not receive a copy of the old +template’s storage devices - it will point to the same locations + +**delete-template** \[*NAME*\] +Delete the template *NAME*. This operation will succeed only if there +are currently no clones of the template + +**import-template** \[*LIBVIRT-DOMAIN*\] \[*NAME*\], **import-template** +\[*XML-LOCATION*\] \[*NAME*\] : Import a new template from either an +existing libvirt domain, or a fully qualified filepath to a libvirt +domain XML file on disk. If argument *NAME* is ommited, qq2clone will +assume you want to use the machine’s name as described in the XML file +as the template name + +**list-templates** +List the names of all existing templates + +**modify-template** \[*NAME*\] **sub-command** \[*ARG*\] … +Templates can be modified in various ways by invoking +**modify-template**. Each subcommand is described below + +**modify-template** \[*NAME*\] **commit-image** +After an image has been created and modified as desired using +**modify-template** \[*NAME*\] **prepare-image**, **commit-image** is +used to alter a template’s underlying storage device by commiting any +changes made using prepare-image. See the commit command described in +**man** **qemu-img** for more information on how this works + +**modify-template** \[*NAME*\] **destroy-image** +Invoke virsh destroy on a running image created/run through +**modify-template** \[*NAME*\] **prepare-image**. This is generally not +wise, as it is equivalent to unplugging a physical machine and could +cause corruption to the image that will later be commited as a permanent +change to the template’s image + +**modify-template** \[*NAME*\] **discard-image** +Delete an image produced by **modify-template** \[*NAME*\] +**prepare-image** without commiting any changes + +**modify-template** \[*NAME*\] **edit** +Edit the XML document defining a template + +**modify-template** \[*NAME*\] **rename** \[*NEW-NAME*\] +Change the name of a template, and all of its clones + +**modify-template** \[*NAME*\] **prepare-image** +Create and/or run a clone that acts as a staging area for changes to the +`template's` actual image. For instance, you could update the +`template's` software by running **modify-template** \[*NAME*\] +**prepare-image**, updating the clone produced by this command, shutting +it down, and then running **modify-template** \[*NAME*\] +**commit-image**. This serves a twofold purpose - to prevent incidental +damage to an underlying image by providing a safe buffer to work in, and +to allow modifications to be safely prepared for an underlying image +even while that image has existing clones. + +CLONE COMMANDS +============== + +A description of the argument *SET* is described in the **SETS** section +below + +**clone** \[*NUMBER*\] +Invoke without any argument to produce a single clone. Supply a number +as an argument to specify the number of clones to create + +**connect** \[*SET*\] +Start any machine in *SET* that `isn't` already running. If any machine +in *SET* has spice graphics and spicy or virt-viewer is installed, use +one or the other (chosen by command-line option or configuration) to +connect to the graphical console + +**destroy** \[*SET*\] +Invoke virsh destroy on any running machine in *SET* (in other words, if +the domain is running forcibly turn it off) + +**edit** \[*NUMBER*\] +Edit the XML file of the clone with given number + +**exec** \[*SET*\] \[*command-string*\] +For every machine in *SET*, sequentially, execute the contents of the +command string in an environment where the following variables are +defined per clone: `"$uuid"`, `"$name"`, `"$disks"` (a newline delimited +string containing the machine’s qcow2 disk device filepaths). This is +done using bash’s eval command, so be sure to put any instances of these +variables in single quotes (double quotes inside the single quotes is +best practice) or they will not be set properly. If any instance of exec +has a non-zero return value, execution stops. + +**list** \[*ARG*\] +Without arguments, list all clones of the current template and their +state. With argument “all”, provide list including all clones of every +template. With argument “xml”, produce an XML document with information +about every template, their clones, and their state. The XML option is +not complete - its format is at this point defined only implicitly, by +the output of this command. + +**resume** \[*SET*\] +Resume any suspended machines in *SET* + +**rm** \[*SET*\] +Destroy every domain in *SET* (if running), undefine them and delete +their storage volumes + +**rm-wipe** \[*SET*\] +Destroy every domain in *SET* (if running), undefine them and wipe their +storage volumes using virsh + +**rm-shred** \[*SET*\] +Destroy every domain in *SET* (if running), undefine them and shred +their storage volumes + +**save** \[*SET*\] +Save execution state of every running domain in *SET* to file + +**save-rm** \[*SET*\] +Delete the state file associated with every machine in *SET* + +**start** \[*SET*\] +Start every machine in *SET* that is currently not running. For saved +domains, their state will be restored + +**suspend** \[*SET*\] +Suspend execution of every machine in *SET* + +OTHER COMMANDS +============== + +**check** \[*TEMPLATE-NAME*\] +As described in the limitations section, there are ways that qq2clone +can lose track of a clone. If this happens, it will remain in qq2clone’s +database, its ID number will remain reserved, and its image files may +not be deleted and take up space doing nothing. the **check** command +tries to find and fix this and other problems. The *TEMPLATE-NAME* +argument is optional, and restricts the check to that template and its +clones. Otherwise, all templates are checked + +**config** list, **config** info \[*OPTION*\], **config** edit \[*OPTION*\] +List all configuration options and their current value, get info about a +particular option, or edit one + +SETS +==== + +*SET* is listed as an argument to many commands. *SET* simply describes +a set of virtual machines - clones of a given template. *SET* is a comma +delimited list with no whitespace. *SET* can be an individual machine or +several individual machines designated by number: + + 1 (Machine 1) + 3,7 (Machines 3 and 7) + +Machine numbers can be shown with **qq2clone** **list**. Ranges and +omitted values are supported as well: + + 1,2-5,^3 (Machines 1 and 2-5 excluding 3) + 1-10,^3-7 (Machines 1-10 excluding 3-7) + +Lastly, groups of machines can be addressed by their state: + + all (All machines) + all,^running (All machines that aren't running) + ^running,1-10 (Machines 1-10 except those that are running) + +The possible states of a virtual machine are based on the states listed +in **man virsh**, with some modifications. States in qq2clone are: + + all + crashed + idle + in-shutdown + off + paused + pmsuspended + running + saved + +Specifying machines that do not exist will not cause an error: i.e., +1-10 is a valid set even if only machines 3-7 exist. A set will only +cause an error if it is malformed, includes zero existing machines, +contains no machines that the command being invoked may act upon, or +includes numbers less than 1. + +CONFIG +====== + +There is no need to refer to the manual to understand configuration +options. Use “**qq2clone** config list” to see all options and their +current values, and “**qq2clone** config info \[*OPTION*\]” to get +information about a particular option. However, here is the same +information provided by **qq2clone** info for each option + +TEMPLATE + +> This template will be used for commands like clone, rm, destroy when +> option --template/-t is not specified +> +> Default value: Default value: `'0'` + +TEMPLATE\_DIR + +> This is the where template XML files will be kept +> +> Default value: `'${HOME}/storage-qq2clone/templates'` + +QUIET + +> If set to 1, most non-error output will be suppressed +> +> Default value: `'0'` + +USE\_SPICE + +> If set to 1, attempt to connect to the spice graphics of a virtual +> machine by default when cloning it, if it is configured to use spice +> graphics. qq2clone can do this using the programs spicy and +> virt-viewer. If either is installed on your system during the first +> run, the default value is `'1'` (enabled). Otherwise, the default +> value is `'0'` + +S\_TIMEOUT + +> Wait this many seconds before timing out when trying to connect to a +> virtual `machine's` spice graphics. +> +> Default value: `'10'` + +STORAGE + +> The default location to store clone images when creating them. +> Changing this location is fine, but it is a good idea to ensure that +> whatever location you do choose is only used by qq2clone +> +> Default value: `'${HOME}/storage-qq2clone/qq2clone-pool'` + +EXAMPLES +======== + +**qq2clone** --template Debian --run --virt-viewer clone +Make a clone of Debian, run it, and connect to its spice graphics using +virt-viewer. All of these options could have instead been defined in the +configuration, so that the entire command would be: **qq2clone** clone + +**qq2clone** --template Debian exec 3 ‘virsh console “$uuid”’ +Use virsh to connect to the serial console of template Debian’s clone +with number 3 (as shown in **qq2clone** list) + +**qq2clone** **modify-template** Debian *prepare-image* +Create a clone of Debian that can be used as a staging area for +permanent changes to the backing template storage device + +**qq2clone** **modify-template** Debian **commit-image** +Commit changes to the image Debian staged with the previous command + +**qq2clone** **copy-template** Debian Debian\_2 +Copy the XML of template Debian, creating a new template with the same +backing storage device that you can edit as you please + +LIMITATIONS +=========== + +The largest limitation of **qq2clone** is that it cannot protect your +template images from the actions of other software. If nothing else +touches a template’s storage volumes, qq2clone can safely handle them +(barring unknown bugs or bad luck during a commit-image). However, if +something else alters the image upon which a template is based, its +existing clones may be corrupted and future clones may behave +differently than expected. It is the user’s responsibility to understand +this aspect of copy on write and carefully manage template images. +Future updates to qq2clone may add features that give some additional +protections, but this risk is inherent to copy on write. + +Libvirt has permissions errors when a storage pool is in a “hidden” +directory with a name beginning with “.” and qcow2 files with backing +files are involved. This may be due to apparmor, or it may be an issue +with libvirt. It is unknown how widespread this issue is, but it is the +reason that the default directory storage-qq2clone does not start with +‘.’ + +If the UUID of a clone is changed, qq2clone will no longer be able to +track it and will not be able to perform commands on it anymore. If +virsh undefine is run on a clone, qq2clone will not be able to see it +once it is turned off. This limitation will be eliminated or reduced in +the future, when qq2clone moves away from relying on virsh and +implements direct usage of the libvirt API. It could be addressed now by +using transient domains, but that would require qq2clone to do more +things manually instead of just invoking virsh. Since the plan is to +transition to a different approach later, that would be wasted effort. +For now, if you find yourself in this position just use **qq2clone** +check. + +qq2clone can only produce clones by making qcow2 image files. The +backing file need not be qcow2, but the images produced by qq2clone +always will be. This is unlikely to ever change - levaraging the +features of qcow2 is the entire purpose of qq2clone. If it does change, +qq2clone will need a new name. + +qq2clone does not support creating images in pool types other than +directories, and attempting to use a machine as a template when it has +storage volumes in a non-directory pool is likely to fail or have +unexpected results. Support for some other pool types may be added in +the future. + +qq2clone currently cannot copy storage volumes when importing a template +(it just references the originals), or when copying a template. This +will change in the future, and qq2clone will also be able to handle more +complex relationships between templates, clones and their images + +FILES +===== + +~/.config/qq2clone +This document simply contains a string defining the location at which +qq2clone will store files, including the database containing the rest of +it configuration options. Currently, qq2clone cannot run without ${HOME} +being defined unless a few lines are altered to refer to a new location + +~/storage-qq2clone +Directory where qq2clone stores all files and binary executables. Can be +changed by modifying ~/.config/qq2clone. This directory is not named +“qq2clone” because it can then slightly interfere with bash completion +when in the home directory, and it does not start with a ‘.’ for the +reasons described in the **LIMITATIONS** section above + +~/storage-qq2clone/qq2clone.db +sqlite3 database containing the configuration information for qq2clone, +as well as data about templates and clones + +~/storage-qq2clone/qq2clone-pool +Storage pool used for clone images and saved state files, if the +--storage option is not used when creating or saving a clone and the +option STORAGE is not changed in the configuration file + +~/qq2clone/templates +Directory in which template XML files are stored. These can be edited +manually, but it is more advisable to use **qq2clone** +**modify-template** \[*template-name*\] edit + +BUGS +==== + +As described in the options section, the implementation of the +--quieter/-Q option needs some work. Its current behavior is the easiest +functional approach without complicating the options parser, but it will +eventually be modified and become better behaved. In addition to the +previously described problem, very early error messages will not be +suppressed. Most likely, the solution is to implement a better options +parser and make it the first thing to run when executing qq2clone. +However, the impact of this bug is minimal and other improvements are +likely to come before this bug fix. + +If you find any worse bugs, and I’m sure I missed some, please let me +know and I will fix them as time allows. + +EXIT VALUES +=========== + +**10** +No permission to access file or file doesn’t exist + +**11** +Required software dependencies are not met (see description for a list), +or are cannot be found in PATH + +**12** +Invalid command line argument specified, or command specifies an invalid +action + +**13** +Problem with a template - i.e., specified template does not exist, or +import-template failed because template of specified name already exists + +**14** +Invocation of an external command failed + +**15** +Problem with a libvirt XML file + +**16** +Attempted action with a libvirt tool resulted in failure + +**17** +Could not establish graphical spice connection to machine before timeout +expired + +**18** +A file is of the wrong type or does not exist + +**19** +Unexpected error - a bug in qq2clone, or a highly unexpected failure of +some command diff --git a/pandoc_gen_docs b/pandoc_gen_docs new file mode 100755 index 0000000..491421a --- /dev/null +++ b/pandoc_gen_docs @@ -0,0 +1,3 @@ +#!/bin/bash +pandoc -s -f markdown -t markdown_strict -o man.md man.pandoc +pandoc -s -f markdown -t man -o qq2clone.1 man.pandoc diff --git a/qq2clone.1 b/qq2clone.1 new file mode 100644 index 0000000..2a0ae84 --- /dev/null +++ b/qq2clone.1 @@ -0,0 +1,601 @@ +.\" Automatically generated by Pandoc 2.5 +.\" +.TH "QQ2CLONE" "1" "February 2021" "qq2clone 0.1" "" +.hy +.SH NAME +.PP +qq2clone \- Create and manage QEMU/KVM VMs using template machines and +qcow2 images with backing files +.SH SYNOPSIS +.PP +\f[B]qq2clone\f[R] [\f[I]OPTION\f[R]]\&... \f[I]COMMAND\f[R] +[\f[I]ARG\f[R]]\&... +.SH DESCRIPTION +.PP +\f[B]qq2clone\f[R] is a tool working on top of virsh that makes creating +clones of template QEMU/KVM machines simple. +By using the copy on write feature for which qcow2 is named, clones of +an existing virtual machine can be made without inadvertently altering +the original image (with caveats \- read the \f[B]LIMITATIONS\f[R] +section if you aren\[cq]t already familiar with how copy on write +works). +\f[B]qq2clone\f[R] makes creating and managing these clones simple and +efficient. +.PP +\f[B]qq2clone\f[R] supports creating numerous clones of a template and +performing batch operations on them \- including the execution of +arbitrary commands with exec. +This simplifies workflows involving large numbers of virtual machines, +or the frequent creation/destruction of virtual machines. +.PP +In addition to virsh, basic linux utilities and QEMU/KVM, qq2clone +requires: +.IP +.nf +\f[C] +Bash 4.0+ +qemu\-img +libvirt tools: + virt\-clone + virt\-xml +virt\-xml\-validate +xmllint (from libxml2) +\f[R] +.fi +.PP +If you want to easily establish graphical connections to your virtual +machines, you should have virt\-viewer and/or spicy installed and +configure your templates to use Spice graphics. +This is not strictly necessary, and with the use of \f[B]qq2clone\f[R] +\f[B]exec\f[R] and a small script of your own you can automate +connecting to Spice/VNC clients of your choice without too much hassle +.SH OPTIONS +.PP +Not every option has an effect in the context of every command. +Specifying an option that has no effect in the context of the command +being invoked will not produce an error, it simply will not do anything +.PP +Options are parsed left to right, and right\-hand options override +left\-hand options. +The only exception is for \-Q/\-\-quieter, which \f[I]must\f[R] be the +first option listed to work properly. +.TP +.B \-c, \-\-connection [\f[I]URI\f[R]] +Specify a non\-default connection URI: sets the value of +LIBVIRT_DEFAULT_URI +.TP +.B \-f, \-\-no\-spice +Do not attempt to connect to a virtual machine\[cq]s Spice graphics. +Overrides USE_SPICE setting in configuration +.TP +.B \-g, \-\-use\-spice +Attempt to connect to a virtual machine\[cq]s spice graphics. +Overrides SPICE setting in configuration +.TP +.B \-h, \-\-help +Print basic help information and exit +.TP +.B \-n, \-\-no\-run +After making a clone of a template, do not run it. +Overrides NORUN setting in configuration +.TP +.B \-q, \-\-quiet +Suppress most non\-error output. +Overrides QUIET setting in configuration. +Also suppresses various prompts for user choices, either exiting with an +error or making a safe default choice depending on the command. +Recommended only once familiar with the behavior of \f[B]qq2clone\f[R] +.TP +.B \-Q, \-\-quieter +This option is (currently) required to appear immediately following the +invocation of \f[B]qq2clone\f[R]. +Suppresses all output, error message or otherwise, except when running +interactive commands or commands that require output to be useful. +The commands for which output is not entirely supressed are: config +list, config info, list, list\-templates, exec, edit, modify\-template +edit, and check. +Other commands will receive only an exit code as output. +This option is intended for calling qq2clone from a script. +.TP +.B \-r, \-\-run +Run a clone when creating it. +Overrides NORUN setting in configuration +.TP +.B \-s, \-\-storage [\f[I]LOCATION\f[R]] +When creating a clone, place new disk image file(s) at location +specified by [\f[I]LOCATION\f[R]]. +[\f[I]LOCATION\f[R]] may be one of an absolute filepath, or the name of +a libvirt directory type storage pool. +Also defines where state files will be saved when using \f[B]save\f[R] +command. +Overrides STORAGE option in configuration +.TP +.B \-S, \-\-spicy +Use spicy rather than virt\-viewer when connecting to the spice graphics +of a clone. +Overrides SPICY setting in configuration +.TP +.B \-t, \-\-template [\f[I]NAME\f[R]] +Use template of given name as context when executing a clone command +(see TYPES OF COMMAND section above). +Overrides TEMPLATE option in configuration +.TP +.B \-v, \-\-verbose +Enable all output. +Overrides QUIET setting in configuration +.TP +.B \-V, \-\-virt\-viewer +Use virt\-viewer rather than spicy when connecting to the spice graphics +of a clone. +Overrides SPICY setting in configuration +.SH TYPES OF COMMAND +.PP +There are two main classes of commands: commands that operate directly +on templates, and commands that create or operate on clones of +templates. +In order to make it less likely that the user may unintentionally invoke +a command of one class when they intended to invoke one of the other, +they use a different syntax. +Commands that operate on templates use the syntax: +.PP +\f[B]qq2clone\f[R] \f[B]command\f[R] [\f[I]template\-name\f[R]] +[\f[I]ARG\f[R]] \&... +.PP +while commands that operate on clones use the syntax: +.PP +\f[B]qq2clone\f[R] \-\-template [\f[I]template\-name\f[R]] +\f[B]command\f[R] [\f[I]ARG\f[R]] \&... +.PP +Notice that commands operating on clones work within the context of a +template defined by the option \-\-template/\-t. +Conversely, commands operating on templates specify the template as an +argument to the command. +There can also be a default template defined by the TEMPLATE option in +the configuration file, allowing the \-\-template option to be omitted +for commands that operate on clones. +Commands operating on templates do not respect this default \- the +template must always be explicitly defined, further reducing the +likelihood of accidentally modifying or deleting a template. +.SH TEMPLATE COMMMANDS +.TP +.B \f[B]copy\-template\f[R] [\f[I]CURRENT\-NAME\f[R]] [\f[I]NEW\-NAME\f[R]] +Copy the XML of template \f[I]CURRENT\-NAME\f[R] to a new template with +\f[I]NEW\-NAME\f[R]. +The new template will not receive a copy of the old template\[cq]s +storage devices \- it will point to the same locations +.TP +.B \f[B]delete\-template\f[R] [\f[I]NAME\f[R]] +Delete the template \f[I]NAME\f[R]. +This operation will succeed only if there are currently no clones of the +template +.PP +\f[B]import\-template\f[R] [\f[I]LIBVIRT\-DOMAIN\f[R]] [\f[I]NAME\f[R]], +\f[B]import\-template\f[R] [\f[I]XML\-LOCATION\f[R]] [\f[I]NAME\f[R]] : +Import a new template from either an existing libvirt domain, or a fully +qualified filepath to a libvirt domain XML file on disk. +If argument \f[I]NAME\f[R] is ommited, qq2clone will assume you want to +use the machine\[cq]s name as described in the XML file as the template +name +.TP +.B \f[B]list\-templates\f[R] +List the names of all existing templates +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]sub\-command\f[R] [\f[I]ARG\f[R]] \&... +Templates can be modified in various ways by invoking +\f[B]modify\-template\f[R]. +Each subcommand is described below +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]commit\-image\f[R] +After an image has been created and modified as desired using +\f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]prepare\-image\f[R], +\f[B]commit\-image\f[R] is used to alter a template\[cq]s underlying +storage device by commiting any changes made using prepare\-image. +See the commit command described in \f[B]man\f[R] \f[B]qemu\-img\f[R] +for more information on how this works +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]destroy\-image\f[R] +Invoke virsh destroy on a running image created/run through +\f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]prepare\-image\f[R]. +This is generally not wise, as it is equivalent to unplugging a physical +machine and could cause corruption to the image that will later be +commited as a permanent change to the template\[cq]s image +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]discard\-image\f[R] +Delete an image produced by \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] +\f[B]prepare\-image\f[R] without commiting any changes +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]edit\f[R] +Edit the XML document defining a template +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]rename\f[R] [\f[I]NEW\-NAME\f[R]] +Change the name of a template, and all of its clones +.TP +.B \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] \f[B]prepare\-image\f[R] +Create and/or run a clone that acts as a staging area for changes to the +\f[C]template\[aq]s\f[R] actual image. +For instance, you could update the \f[C]template\[aq]s\f[R] software by +running \f[B]modify\-template\f[R] [\f[I]NAME\f[R]] +\f[B]prepare\-image\f[R], updating the clone produced by this command, +shutting it down, and then running \f[B]modify\-template\f[R] +[\f[I]NAME\f[R]] \f[B]commit\-image\f[R]. +This serves a twofold purpose \- to prevent incidental damage to an +underlying image by providing a safe buffer to work in, and to allow +modifications to be safely prepared for an underlying image even while +that image has existing clones. +.SH CLONE COMMANDS +.PP +A description of the argument \f[I]SET\f[R] is described in the +\f[B]SETS\f[R] section below +.TP +.B \f[B]clone\f[R] [\f[I]NUMBER\f[R]] +Invoke without any argument to produce a single clone. +Supply a number as an argument to specify the number of clones to create +.TP +.B \f[B]connect\f[R] [\f[I]SET\f[R]] +Start any machine in \f[I]SET\f[R] that \f[C]isn\[aq]t\f[R] already +running. +If any machine in \f[I]SET\f[R] has spice graphics and spicy or +virt\-viewer is installed, use one or the other (chosen by command\-line +option or configuration) to connect to the graphical console +.TP +.B \f[B]destroy\f[R] [\f[I]SET\f[R]] +Invoke virsh destroy on any running machine in \f[I]SET\f[R] (in other +words, if the domain is running forcibly turn it off) +.TP +.B \f[B]edit\f[R] [\f[I]NUMBER\f[R]] +Edit the XML file of the clone with given number +.TP +.B \f[B]exec\f[R] [\f[I]SET\f[R]] [\f[I]command\-string\f[R]] +For every machine in \f[I]SET\f[R], sequentially, execute the contents +of the command string in an environment where the following variables +are defined per clone: \f[C]\[dq]$uuid\[dq]\f[R], +\f[C]\[dq]$name\[dq]\f[R], \f[C]\[dq]$disks\[dq]\f[R] (a newline +delimited string containing the machine\[cq]s qcow2 disk device +filepaths). +This is done using bash\[cq]s eval command, so be sure to put any +instances of these variables in single quotes (double quotes inside the +single quotes is best practice) or they will not be set properly. +If any instance of exec has a non\-zero return value, execution stops. +.TP +.B \f[B]list\f[R] [\f[I]ARG\f[R]] +Without arguments, list all clones of the current template and their +state. +With argument \[lq]all\[rq], provide list including all clones of every +template. +With argument \[lq]xml\[rq], produce an XML document with information +about every template, their clones, and their state. +The XML option is not complete \- its format is at this point defined +only implicitly, by the output of this command. +.TP +.B \f[B]resume\f[R] [\f[I]SET\f[R]] +Resume any suspended machines in \f[I]SET\f[R] +.TP +.B \f[B]rm\f[R] [\f[I]SET\f[R]] +Destroy every domain in \f[I]SET\f[R] (if running), undefine them and +delete their storage volumes +.TP +.B \f[B]rm\-wipe\f[R] [\f[I]SET\f[R]] +Destroy every domain in \f[I]SET\f[R] (if running), undefine them and +wipe their storage volumes using virsh +.TP +.B \f[B]rm\-shred\f[R] [\f[I]SET\f[R]] +Destroy every domain in \f[I]SET\f[R] (if running), undefine them and +shred their storage volumes +.TP +.B \f[B]save\f[R] [\f[I]SET\f[R]] +Save execution state of every running domain in \f[I]SET\f[R] to file +.TP +.B \f[B]save\-rm\f[R] [\f[I]SET\f[R]] +Delete the state file associated with every machine in \f[I]SET\f[R] +.TP +.B \f[B]start\f[R] [\f[I]SET\f[R]] +Start every machine in \f[I]SET\f[R] that is currently not running. +For saved domains, their state will be restored +.TP +.B \f[B]suspend\f[R] [\f[I]SET\f[R]] +Suspend execution of every machine in \f[I]SET\f[R] +.SH OTHER COMMANDS +.TP +.B \f[B]check\f[R] [\f[I]TEMPLATE\-NAME\f[R]] +As described in the limitations section, there are ways that qq2clone +can lose track of a clone. +If this happens, it will remain in qq2clone\[cq]s database, its ID +number will remain reserved, and its image files may not be deleted and +take up space doing nothing. +the \f[B]check\f[R] command tries to find and fix this and other +problems. +The \f[I]TEMPLATE\-NAME\f[R] argument is optional, and restricts the +check to that template and its clones. +Otherwise, all templates are checked +.TP +.B \f[B]config\f[R] list, \f[B]config\f[R] info [\f[I]OPTION\f[R]], \f[B]config\f[R] edit [\f[I]OPTION\f[R]] +List all configuration options and their current value, get info about a +particular option, or edit one +.SH SETS +.PP +\f[I]SET\f[R] is listed as an argument to many commands. +\f[I]SET\f[R] simply describes a set of virtual machines \- clones of a +given template. +\f[I]SET\f[R] is a comma delimited list with no whitespace. +\f[I]SET\f[R] can be an individual machine or several individual +machines designated by number: +.IP +.nf +\f[C] +1 (Machine 1) +3,7 (Machines 3 and 7) +\f[R] +.fi +.PP +Machine numbers can be shown with \f[B]qq2clone\f[R] \f[B]list\f[R]. +Ranges and omitted values are supported as well: +.IP +.nf +\f[C] +1,2\-5,\[ha]3 (Machines 1 and 2\-5 excluding 3) +1\-10,\[ha]3\-7 (Machines 1\-10 excluding 3\-7) +\f[R] +.fi +.PP +Lastly, groups of machines can be addressed by their state: +.IP +.nf +\f[C] +all (All machines) +all,\[ha]running (All machines that aren\[aq]t running) +\[ha]running,1\-10 (Machines 1\-10 except those that are running) +\f[R] +.fi +.PP +The possible states of a virtual machine are based on the states listed +in \f[B]man virsh\f[R], with some modifications. +States in qq2clone are: +.IP +.nf +\f[C] +all +crashed +idle +in\-shutdown +off +paused +pmsuspended +running +saved +\f[R] +.fi +.PP +Specifying machines that do not exist will not cause an error: i.e., +1\-10 is a valid set even if only machines 3\-7 exist. +A set will only cause an error if it is malformed, includes zero +existing machines, contains no machines that the command being invoked +may act upon, or includes numbers less than 1. +.SH CONFIG +.PP +There is no need to refer to the manual to understand configuration +options. +Use \[lq]\f[B]qq2clone\f[R] config list\[rq] to see all options and +their current values, and \[lq]\f[B]qq2clone\f[R] config info +[\f[I]OPTION\f[R]]\[rq] to get information about a particular option. +However, here is the same information provided by \f[B]qq2clone\f[R] +info for each option +.PP +TEMPLATE +.RS +.PP +This template will be used for commands like clone, rm, destroy when +option \-\-template/\-t is not specified +.PP +Default value: Default value: \f[C]\[aq]0\[aq]\f[R] +.RE +.PP +TEMPLATE_DIR +.RS +.PP +This is the where template XML files will be kept +.PP +Default value: \f[C]\[aq]${HOME}/storage\-qq2clone/templates\[aq]\f[R] +.RE +.PP +QUIET +.RS +.PP +If set to 1, most non\-error output will be suppressed +.PP +Default value: \f[C]\[aq]0\[aq]\f[R] +.RE +.PP +USE_SPICE +.RS +.PP +If set to 1, attempt to connect to the spice graphics of a virtual +machine by default when cloning it, if it is configured to use spice +graphics. +qq2clone can do this using the programs spicy and virt\-viewer. +If either is installed on your system during the first run, the default +value is \f[C]\[aq]1\[aq]\f[R] (enabled). +Otherwise, the default value is \f[C]\[aq]0\[aq]\f[R] +.RE +.PP +S_TIMEOUT +.RS +.PP +Wait this many seconds before timing out when trying to connect to a +virtual \f[C]machine\[aq]s\f[R] spice graphics. +.PP +Default value: \f[C]\[aq]10\[aq]\f[R] +.RE +.PP +STORAGE +.RS +.PP +The default location to store clone images when creating them. +Changing this location is fine, but it is a good idea to ensure that +whatever location you do choose is only used by qq2clone +.PP +Default value: +\f[C]\[aq]${HOME}/storage\-qq2clone/qq2clone\-pool\[aq]\f[R] +.RE +.SH EXAMPLES +.TP +.B \f[B]qq2clone\f[R] \-\-template Debian \-\-run \-\-virt\-viewer clone +Make a clone of Debian, run it, and connect to its spice graphics using +virt\-viewer. +All of these options could have instead been defined in the +configuration, so that the entire command would be: \f[B]qq2clone\f[R] +clone +.TP +.B \f[B]qq2clone\f[R] \-\-template Debian exec 3 `virsh console \[lq]$uuid\[rq]' +Use virsh to connect to the serial console of template Debian\[cq]s +clone with number 3 (as shown in \f[B]qq2clone\f[R] list) +.TP +.B \f[B]qq2clone\f[R] \f[B]modify\-template\f[R] Debian \f[I]prepare\-image\f[R] +Create a clone of Debian that can be used as a staging area for +permanent changes to the backing template storage device +.TP +.B \f[B]qq2clone\f[R] \f[B]modify\-template\f[R] Debian \f[B]commit\-image\f[R] +Commit changes to the image Debian staged with the previous command +.TP +.B \f[B]qq2clone\f[R] \f[B]copy\-template\f[R] Debian Debian_2 +Copy the XML of template Debian, creating a new template with the same +backing storage device that you can edit as you please +.SH LIMITATIONS +.PP +The largest limitation of \f[B]qq2clone\f[R] is that it cannot protect +your template images from the actions of other software. +If nothing else touches a template\[cq]s storage volumes, qq2clone can +safely handle them (barring unknown bugs or bad luck during a +commit\-image). +However, if something else alters the image upon which a template is +based, its existing clones may be corrupted and future clones may behave +differently than expected. +It is the user\[cq]s responsibility to understand this aspect of copy on +write and carefully manage template images. +Future updates to qq2clone may add features that give some additional +protections, but this risk is inherent to copy on write. +.PP +Libvirt has permissions errors when a storage pool is in a +\[lq]hidden\[rq] directory with a name beginning with \[lq].\[rq] and +qcow2 files with backing files are involved. +This may be due to apparmor, or it may be an issue with libvirt. +It is unknown how widespread this issue is, but it is the reason that +the default directory storage\-qq2clone does not start with `.' +.PP +If the UUID of a clone is changed, qq2clone will no longer be able to +track it and will not be able to perform commands on it anymore. +If virsh undefine is run on a clone, qq2clone will not be able to see it +once it is turned off. +This limitation will be eliminated or reduced in the future, when +qq2clone moves away from relying on virsh and implements direct usage of +the libvirt API. +It could be addressed now by using transient domains, but that would +require qq2clone to do more things manually instead of just invoking +virsh. +Since the plan is to transition to a different approach later, that +would be wasted effort. +For now, if you find yourself in this position just use +\f[B]qq2clone\f[R] check. +.PP +qq2clone can only produce clones by making qcow2 image files. +The backing file need not be qcow2, but the images produced by qq2clone +always will be. +This is unlikely to ever change \- levaraging the features of qcow2 is +the entire purpose of qq2clone. +If it does change, qq2clone will need a new name. +.PP +qq2clone does not support creating images in pool types other than +directories, and attempting to use a machine as a template when it has +storage volumes in a non\-directory pool is likely to fail or have +unexpected results. +Support for some other pool types may be added in the future. +.PP +qq2clone currently cannot copy storage volumes when importing a template +(it just references the originals), or when copying a template. +This will change in the future, and qq2clone will also be able to handle +more complex relationships between templates, clones and their images +.SH FILES +.TP +.B \[ti]/.config/qq2clone +This document simply contains a string defining the location at which +qq2clone will store files, including the database containing the rest of +it configuration options. +Currently, qq2clone cannot run without ${HOME} being defined unless a +few lines are altered to refer to a new location +.TP +.B \[ti]/storage\-qq2clone +Directory where qq2clone stores all files and binary executables. +Can be changed by modifying \[ti]/.config/qq2clone. +This directory is not named \[lq]qq2clone\[rq] because it can then +slightly interfere with bash completion when in the home directory, and +it does not start with a `.' for the reasons described in the +\f[B]LIMITATIONS\f[R] section above +.TP +.B \[ti]/storage\-qq2clone/qq2clone.db +sqlite3 database containing the configuration information for qq2clone, +as well as data about templates and clones +.TP +.B \[ti]/storage\-qq2clone/qq2clone\-pool +Storage pool used for clone images and saved state files, if the +\-\-storage option is not used when creating or saving a clone and the +option STORAGE is not changed in the configuration file +.TP +.B \[ti]/qq2clone/templates +Directory in which template XML files are stored. +These can be edited manually, but it is more advisable to use +\f[B]qq2clone\f[R] \f[B]modify\-template\f[R] [\f[I]template\-name\f[R]] +edit +.SH BUGS +.PP +As described in the options section, the implementation of the +\-\-quieter/\-Q option needs some work. +Its current behavior is the easiest functional approach without +complicating the options parser, but it will eventually be modified and +become better behaved. +In addition to the previously described problem, very early error +messages will not be suppressed. +Most likely, the solution is to implement a better options parser and +make it the first thing to run when executing qq2clone. +However, the impact of this bug is minimal and other improvements are +likely to come before this bug fix. +.PP +If you find any worse bugs, and I\[cq]m sure I missed some, please let +me know and I will fix them as time allows. +.SH EXIT VALUES +.TP +.B \f[B]10\f[R] +No permission to access file or file doesn\[cq]t exist +.TP +.B \f[B]11\f[R] +Required software dependencies are not met (see description for a list), +or are cannot be found in PATH +.TP +.B \f[B]12\f[R] +Invalid command line argument specified, or command specifies an invalid +action +.TP +.B \f[B]13\f[R] +Problem with a template \- i.e., specified template does not exist, or +import\-template failed because template of specified name already +exists +.TP +.B \f[B]14\f[R] +Invocation of an external command failed +.TP +.B \f[B]15\f[R] +Problem with a libvirt XML file +.TP +.B \f[B]16\f[R] +Attempted action with a libvirt tool resulted in failure +.TP +.B \f[B]17\f[R] +Could not establish graphical spice connection to machine before timeout +expired +.TP +.B \f[B]18\f[R] +A file is of the wrong type or does not exist +.TP +.B \f[B]19\f[R] +Unexpected error \- a bug in qq2clone, or a highly unexpected failure of +some command +.SH AUTHORS +Jesse Gardner.