Skip to content

Commit

Permalink
Add command for migrating templates from rpmdb
Browse files Browse the repository at this point in the history
  • Loading branch information
marmarek committed Apr 12, 2022
1 parent 400ea49 commit 43b6dd6
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
20 changes: 20 additions & 0 deletions doc/manpages/qvm-template.rst
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,26 @@ Options

Show only disabled repos.

migrate-from-rpmdb
------------------

Migrate templates metadata from R4.0 format. This makes template originally
installed via rpm (qubes-dom0-update) available for qvm-template.
All templates gets `installed_by_rpm` property set to false.
If the operation fails for any reason, it is safe to retry.

Synopsis
^^^^^^^^

:command:`qvm-template migrate-from-rpmdb` [-h]

Options
^^^^^^^

.. option:: -h, --help

Show help message and exit.

Template Spec
-------------

Expand Down
50 changes: 50 additions & 0 deletions qubesadmin/tools/qvm_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ def parser_add_command(cmd, help_str):
help='Show only disabled repos.')
parser_repolist.add_argument('repos', nargs='*', metavar='REPOS')

# qvm-template migrate-from-rpmdb
parser_add_command('migrate-from-rpmdb',
help_str='Import R4.0 templates info to R4.1 format')

return parser_main


Expand Down Expand Up @@ -1574,6 +1578,50 @@ def repolist(args: argparse.Namespace, app: qubesadmin.app.QubesBase) -> None:
qubesadmin.tools.print_table(table)


def migrate_from_rpmdb(args, app):
"""Migrate templates stored in rpmdb, into 'features' set on the VM itself.
"""

if os.getuid() != 0:
parser.error('This command needs to be run as root')
ts = rpm.TransactionSet()
pkgs_to_remove = []
for pkg in ts.dbMatch():
if not pkg["name"].startswith('qubes-template-'):
continue
try:
vm = app.domains[pkg['name'][len('qubes-template-'):]]
except KeyError:
# no longer present, remove from rpmdb
pkgs_to_remove.append(pkg)
continue
if is_managed_template(vm):
# already migrated, cleanup
pkgs_to_remove.append(pkg)
continue
try:
vm.features['template-name'] = vm.name
vm.features['template-epoch'] = pkg[rpm.RPMTAG_EPOCHNUM]
vm.features['template-version'] = pkg[rpm.RPMTAG_VERSION]
vm.features['template-release'] = pkg[rpm.RPMTAG_RELEASE]
vm.features['template-reponame'] = ''
vm.features['template-buildtime'] = datetime.datetime.fromtimestamp(
pkg[rpm.RPMTAG_BUILDTIME]).strftime(DATE_FMT)
vm.features['template-installtime'] = pkg[rpm.RPMTAG_INSTALLTIME]
vm.features['template-license'] = pkg[rpm.RPMTAG_LICENSE]
vm.features['template-url'] = pkg[rpm.RPMTAG_URL]
vm.features['template-summary'] = pkg[rpm.RPMTAG_SUMMARY]
vm.features['template-description'] = \
pkg[rpm.RPMTAG_DESCRIPTION].replace('\n', '|')
vm.installed_by_rpm = False
except Exception as e:
print('Failed to set template {} metadata: {}'.format(vm.name, e))
continue
pkgs_to_remove.append(pkg)
subprocess.check_call(
['rpm', '-e', '--justdb'] + [p['name'] for p in pkgs_to_remove])


def main(args: typing.Optional[typing.Sequence[str]] = None,
app: typing.Optional[qubesadmin.app.QubesBase] = None) -> int:
"""Main routine of **qvm-template**.
Expand Down Expand Up @@ -1636,6 +1684,8 @@ def main(args: typing.Optional[typing.Sequence[str]] = None,
clean(p_args, app)
elif p_args.command == 'repolist':
repolist(p_args, app)
elif p_args.command == 'migrate-from-rpmdb':
migrate_from_rpmdb(p_args, app)
else:
parser.error(f'Command \'{p_args.command}\' not supported.')
except Exception as e: # pylint: disable=broad-except
Expand Down

0 comments on commit 43b6dd6

Please sign in to comment.