diff --git a/doc/manpages/qvm-template.rst b/doc/manpages/qvm-template.rst new file mode 100644 index 00000000..2b0c50bb --- /dev/null +++ b/doc/manpages/qvm-template.rst @@ -0,0 +1,499 @@ +.. program:: qvm-template + +:program:`qvm-template` -- Manage template VMs +============================================== + +Synopsis +-------- + +:command:`qvm-template` [-h] [--repo-files *REPO_FILES*] [--keyring *KEYRING*] [--updatevm *UPDATEVM*] [--enablerepo *REPOID*] [--disablerepo *REPOID*] [--repoid *REPOID*] [--releasever *RELEASEVER*] [--refresh] [--cachedir *CACHEDIR*] [--yes] [--quiet] *SUBCOMMAND* + +See Section `Subcommands`_ for available subcommands. + +Options +------- + +.. option:: --help, -h + + Show help message and exit. + +.. option:: --repo-files REPO_FILES + + Specify files containing DNF repository configuration. Can be + used more than once. (default: + ['/usr/share/qubes/repo-templates/qubes-templates.repo']) + +.. option:: --keyring KEYRING + + Specify directory containing RPM public keys. (default: + /usr/share/qubes/repo-templates/keys) + +.. option:: --updatevm UPDATEVM + + Specify VM to download updates from. (default: sys-firewall) + +.. option:: --enablerepo REPOID + + Enable additional repositories by an id or a glob. Can be used more than + once. + +.. option:: --disablerepo REPOID + + Disable certain repositories by an id or a glob. Can be used more than once. + +.. option:: --repoid REPOID + + Enable just specific repositories by an id or a glob. Can be used more than + once. + +.. option:: --releasever RELEASEVER + + Override Qubes release version. + +.. option:: --refresh + + Set repository metadata as expired before running the command. + +.. option:: --cachedir CACHEDIR + + Specify cache directory. (default: ~/.cache/qvm-template) + +.. option:: --yes + + Assume "yes" to questions. + +.. option:: --quiet + + Decrease verbosity. + +Subcommands +=========== + +install +------- + +Install template packages. + +Synopsis +^^^^^^^^ + +:command:`qvm-template install` [-h] [--pool *POOL*] [--nogpgcheck] [--allow-pv] [--downloaddir *DOWNLOADDIR*] [--retries *RETRIES*] [*TEMPLATESPEC* [*TEMPLATESPEC* ...]] + +See Section `Template Spec`_ for an explanation of *TEMPLATESPEC*. + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --pool POOL + + Specify pool to store created VMs in. + +.. option:: --nogpgcheck + + Disable signature checks. + +.. option:: --allow-pv + + Allow templates that set virt_mode to pv. + +.. option:: --downloaddir DOWNLOADDIR + + Specify download directory. (default: .) + +.. option:: --retries RETRIES + + Specify maximum number of retries for downloads. (default: 5) + +{reinstall,downgrade,upgrade} +----------------------------- + +Reinstall/downgrade/upgrade template packages. + +Synopsis +^^^^^^^^ + +:command:`qvm-template {reinstall,downgrade,upgrade}` [-h] [--nogpgcheck] [--allow-pv] [--downloaddir *DOWNLOADDIR*] [--retries *RETRIES*] [*TEMPLATESPEC* [*TEMPLATESPEC* ...]] + +See Section `Template Spec`_ for an explanation of *TEMPLATESPEC*. + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --nogpgcheck + + Disable signature checks. + +.. option:: --allow-pv + + Allow templates that set virt_mode to pv. + +.. option:: --downloaddir DOWNLOADDIR + + Specify download directory. (default: .) + +.. option:: --retries RETRIES + + Specify maximum number of retries for downloads. (default: 5) + +download +-------- + +Download template packages. + +Synopsis +^^^^^^^^ + +:command:`qvm-template download` [-h] [--downloaddir *DOWNLOADDIR*] [--retries *RETRIES*] [*TEMPLATESPEC* [*TEMPLATESPEC* ...]] + +See Section `Template Spec`_ for an explanation of *TEMPLATESPEC*. + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --downloaddir DOWNLOADDIR + + Specify download directory. (default: .) + +.. option:: --retries RETRIES + + Specify maximum number of retries for downloads. (default: 5) + +list +---- + +List templates. + +Synopsis +^^^^^^^^ + +:command:`qvm-template list` [-h] [--all] [--installed] [--available] [--extras] [--upgrades] [--machine-readable | --machine-readable-json] [*TEMPLATESPEC* [*TEMPLATESPEC* ...]] + +See Section `Template Spec`_ for an explanation of *TEMPLATESPEC*. + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --all + + Show all templates (default). + +.. option:: --installed + + Show installed templates. + +.. option:: --available + + Show available templates. + +.. option:: --extras + + Show extras (e.g., ones that exist locally but not in repos) + templates. + +.. option:: --upgrades + + Show upgradable templates. + +.. option:: --machine-readable + + Enable machine-readable output. + + Format + Each line describes a template in the following format: + + :: + + |{status}|{name}|{evr}|{reponame}| + + Where ``{status}`` can be one of ``installed``, ``available``, + ``extra``, or ``upgradable``. + + The field ``{evr}`` contains version information in the form of + ``{epoch}:{version}-{release}``. + +.. option:: --machine-readable-json + + Enable machine-readable output (JSON). + + Format + The resulting JSON document is in the following format: + + :: + + { + STATUS: [ + { + "name": str, + "evr": str, + "reponame": str + }, + ... + ], + ... + } + + Where ``STATUS`` can be one of ``"installed"``, ``"available"``, + ``"extra"``, or ``"upgradable"``. + + The fields ``buildtime`` and ``installtime`` are in ISO 8601 format. + For example, one can parse them in Python with + ``datetime.fromisoformat()``. + + The field ``{evr}`` contains version information in the form of + ``{epoch}:{version}-{release}``. + +info +---- + +Display details about templates. + +Synopsis +^^^^^^^^ + +:command:`qvm-template list` [-h] [--all] [--installed] [--available] [--extras] [--upgrades] [--machine-readable | --machine-readable-json] [*TEMPLATESPEC* [*TEMPLATESPEC* ...]] + +See Section `Template Spec`_ for an explanation of *TEMPLATESPEC*. + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --all + + Show all templates (default). + +.. option:: --installed + + Show installed templates. + +.. option:: --available + + Show available templates. + +.. option:: --extras + + Show extras (e.g., ones that exist locally but not in repos) + templates. + +.. option:: --upgrades + + Show upgradable templates. + +.. option:: --machine-readable + + Enable machine-readable output. + + Format + Each line describes a template in the following format: + + :: + + |{status}|{name}|{epoch}|{version}|{release}|{reponame}|{size}|{buildtime}|{installtime}|{license}|{url}|{summary}|{description}| + + Where ``{status}`` can be one of ``installed``, ``available``, + ``extra``, or ``upgradable``. + + The fields ``{buildtime}`` and ``{installtime}`` are in ISO 8601 format. + For example, one can parse them in Python with + ``datetime.fromisoformat()``. + + Newlines in the ``{description}`` field are replaced with pipe + characters (``|``) for easier processing. + +.. option:: --machine-readable-json + + Enable machine-readable output (JSON). + + Format + The resulting JSON document is in the following format: + + :: + + { + STATUS: [ + { + "name": str, + "epoch": str, + "version": str, + "release": str, + "reponame": str, + "size": int, + "buildtime": str, + "installtime": str, + "license": str, + "url": str, + "summary": str, + "description": str + }, + ... + ], + ... + } + + Where ``STATUS`` can be one of ``"installed"``, ``"available"``, + ``"extra"``, or ``"upgradable"``. + + The fields ``buildtime`` and ``installtime`` are in ISO 8601 format. + For example, one can parse them in Python using + `datetime.fromisoformat()`. + +search +------ + +Search template details for the given string. + +Synopsis +^^^^^^^^ + +:command:`qvm-template search` [-h] [--all] [*PATTERN* [*PATTERN* ...]] + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --all + + Search also in the template description and URL. In addition, the criterion + are evaluated with OR instead of AND. + +remove +------ + +Remove installed templates. + +Synopsis +^^^^^^^^ + +:command:`qvm-template remove` [-h] [--disassoc] [*TEMPLATE* [*TEMPLATE* ...]] + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --disassoc + + Also disassociate VMs from the templates to be removed. This + creates a *dummy* template for the VMs to link with. + +purge +----- + +Remove installed templates and associated VMs. + +Synopsis +^^^^^^^^ + +:command:`qvm-template purge` [-h] [*TEMPLATE* [*TEMPLATE* ...]] + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +clean +----- + +Remove locally cached packages. + +Synopsis +^^^^^^^^ + +:command:`qvm-template clean` [-h] + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +repolist +-------- + +Show configured repositories. + +Synopsis +^^^^^^^^ + +:command:`qvm-template repolist` [-h] [--all | --enabled | --disabled] [*REPOS* [*REPOS* ...]] + +Options +^^^^^^^ + +.. option:: -h, --help + + Show help message and exit. + +.. option:: --all + + Show all repos. + +.. option:: --enabled + + Show only enabled repos (default). + +.. option:: --disabled + + Show only disabled repos. + +Template Spec +------------- + +Subcommands such as ``install`` and ``download`` accept one or more +*TEMPLATESPEC* strings. The format is, in essence, almost identical to +```` described in the DNF documentation. + +In short, the spec is matched against the following list of NEVRA forms, in +decreasing orders of priority: + +* ``name-[epoch:]version-release`` +* ``name`` +* ``name-[epoch:]version`` + +Note that unlike DNF, ``arch`` is currently ignored as the template packages +should all be of ``noarch``. + +One can also use globs in spec strings. See Section `Globs`_ for details. + +Refer to Section *NEVRA Matching* in the DNF documentation for details. + +Globs +----- + +`Template Spec`_ strings, repo ids, and search patterns support glob pattern +matching. In particular, the following special characters can be used: + +* ``*``: Matches any number of characters. +* ``?``: Matches exactly one character. +* ``[]``: Matches any enclosed character. +* ``[!]``: Matches any character except those enclosed. + +In particular, note that ``{}``, while supported by DNF, is not supported by +`qvm-template`. diff --git a/qubesadmin/tools/qvm_template.py b/qubesadmin/tools/qvm_template.py index 3558a9d7..61736232 100644 --- a/qubesadmin/tools/qvm_template.py +++ b/qubesadmin/tools/qvm_template.py @@ -61,20 +61,26 @@ def parser_add_command(cmd, help_str): parser_main.add_argument('--repo-files', action='append', default=['/usr/share/qubes/repo-templates/qubes-templates.repo'], - help='Specify files containing DNF repository configuration.') + help=('Specify files containing DNF repository configuration.' + ' Can be used more than once.')) parser_main.add_argument('--keyring', default='/usr/share/qubes/repo-templates/keys', help='Specify directory containing RPM public keys.') parser_main.add_argument('--updatevm', default='sys-firewall', help='Specify VM to download updates from.') parser_main.add_argument('--enablerepo', action='append', default=[], - help='Enable additional repositories.') + metavar='REPOID', + help=('Enable additional repositories by an id or a glob.' + ' Can be used more than once.')) parser_main.add_argument('--disablerepo', action='append', default=[], - help='Disable certain repositories.') + metavar='REPOID', + help=('Disable certain repositories by an id or a glob.' + ' Can be used more than once.')) parser_main.add_argument('--repoid', action='append', default=[], - help='Enable just specific repositories.') + help=('Enable just specific repositories by an id or a glob.' + ' Can be used more than once.')) parser_main.add_argument('--releasever', default=qubes_release(), - help='Override distro release version.') + help='Override Qubes release version.') parser_main.add_argument('--refresh', action='store_true', help='Set repository metadata as expired before running the command.') parser_main.add_argument('--cachedir', default=CACHE_DIR, @@ -82,7 +88,7 @@ def parser_add_command(cmd, help_str): parser_main.add_argument('--yes', action='store_true', help='Assume "yes" to questions.') parser_main.add_argument('--quiet', action='store_true', - help='Reduce amount of output.') + help='Decrease verbosity.') # qvm-template {install,reinstall,downgrade,upgrade} parser_install = parser_add_command('install', help_str='Install template packages.') @@ -99,18 +105,19 @@ def parser_add_command(cmd, help_str): parser_x.add_argument('--nogpgcheck', action='store_true', help='Disable signature checks.') parser_x.add_argument('--allow-pv', action='store_true', - help='Allow setting virt_mode to pv in configuration file.') - parser_x.add_argument('templates', nargs='*', metavar='TEMPLATE') + help='Allow templates that set virt_mode to pv.') + parser_x.add_argument('templates', nargs='*', metavar='TEMPLATESPEC') # qvm-template download parser_download = parser_add_command('download', - help_str='Download template package.') + help_str='Download template packages.') for parser_x in [parser_install, parser_reinstall, parser_downgrade, parser_upgrade, parser_download]: parser_x.add_argument('--downloaddir', default='.', help='Specify download directory.') parser_x.add_argument('--retries', default=5, type=int, - help='Specify number of retries for downloads.') - parser_download.add_argument('templates', nargs='*', metavar='TEMPLATE') + help='Specify maximum number of retries for downloads.') + parser_download.add_argument('templates', nargs='*', + metavar='TEMPLATESPEC') # qvm-template {list,info} parser_list = parser_add_command('list', help_str='List templates.') @@ -124,7 +131,7 @@ def parser_add_command(cmd, help_str): parser_x.add_argument('--available', action='store_true', help='Show available templates.') parser_x.add_argument('--extras', action='store_true', - help=('Show extras (e.g., ones that exists' + help=('Show extras (e.g., ones that exist' ' locally but not in repos) templates.')) parser_x.add_argument('--upgrades', action='store_true', help='Show upgradable templates.') @@ -133,19 +140,20 @@ def parser_add_command(cmd, help_str): help='Enable machine-readable output.') readable.add_argument('--machine-readable-json', action='store_true', help='Enable machine-readable output (JSON).') - parser_x.add_argument('templates', nargs='*', metavar='TEMPLATE') + parser_x.add_argument('templates', nargs='*', metavar='TEMPLATESPEC') # qvm-template search parser_search = parser_add_command('search', help_str='Search template details for the given string.') parser_search.add_argument('--all', action='store_true', - help=('Search also in template description and URL. In addition,' + help=('Search also in the template description and URL. In addition,' ' the criterion are evaluated with OR instead of AND.')) parser_search.add_argument('templates', nargs='*', metavar='PATTERN') # qvm-template remove parser_remove = parser_add_command('remove', help_str='Remove installed templates.') parser_remove.add_argument('--disassoc', action='store_true', - help='Also disassociate VMs from the templates to be removed.') + help=('Also disassociate VMs from the templates to be removed.' + ' This creates a dummy template for the VMs to link with.')) parser_remove.add_argument('templates', nargs='*', metavar='TEMPLATE') # qvm-template purge parser_purge = parser_add_command('purge', @@ -153,7 +161,7 @@ def parser_add_command(cmd, help_str): parser_purge.add_argument('templates', nargs='*', metavar='TEMPLATE') # qvm-template clean parser_clean = parser_add_command('clean', - help_str='Remove cached data.') + help_str='Remove locally cached packages.') _ = parser_clean # unused # qvm-template repolist parser_repolist = parser_add_command('repolist', @@ -162,9 +170,9 @@ def parser_add_command(cmd, help_str): repolim.add_argument('--all', action='store_true', help='Show all repos.') repolim.add_argument('--enabled', action='store_true', - help='Show enabled repos (default).') + help='Show only enabled repos (default).') repolim.add_argument('--disabled', action='store_true', - help='Show disabled repos.') + help='Show only disabled repos.') parser_repolist.add_argument('repos', nargs='*', metavar='REPOS') return parser_main