From 305fb5b6d00a061d4ae7895c68c48a4f3b96719f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 25 May 2017 12:26:01 +0200 Subject: [PATCH] Move qvm-template-postprocess tool to core-admin-client Since implementing admin.vm.volume.Import, this migrated to Admin API. --- qubes/tools/qvm_template_postprocess.py | 194 ------------------------ rpm_spec/core-dom0.spec | 1 - 2 files changed, 195 deletions(-) delete mode 100644 qubes/tools/qvm_template_postprocess.py diff --git a/qubes/tools/qvm_template_postprocess.py b/qubes/tools/qvm_template_postprocess.py deleted file mode 100644 index e484a849..00000000 --- a/qubes/tools/qvm_template_postprocess.py +++ /dev/null @@ -1,194 +0,0 @@ -# -# The Qubes OS Project, https://www.qubes-os.org/ -# -# Copyright (C) 2016 Marek Marczykowski-Górecki -# -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import argparse -import glob -import os - -import shutil -import subprocess - -import sys - -import grp - -import qubes -import qubes.tools - -parser = qubes.tools.QubesArgumentParser( - description='Postprocess template package, for internal use only') -parser.add_argument('--really', action='store_true', default=False, - help=argparse.SUPPRESS) -parser.add_argument('action', choices=['post-install', 'pre-remove'], - help='Action to perform') -parser.add_argument('name', action='store', - help='Template name') -parser.add_argument('dir', action='store', - help='Template directory') - - -def move_if_exists(source, dest_dir): - if os.path.exists(source): - shutil.move(source, os.path.join(dest_dir, os.path.basename(source))) - - -def import_data(source_dir, vm): - # FIXME: this abuses volume export() for importing purposes - root_path = os.path.join(source_dir, 'root.img') - target_path = vm.storage.export('root') - if os.path.exists(root_path + '.part.00'): - input_files = glob.glob(root_path + '.*') - cat = subprocess.Popen(['cat'] + sorted(input_files), - stdout=subprocess.PIPE) - tar = subprocess.Popen(['tar', 'xSOf', '-'], - stdin=cat.stdout, - stdout=open(target_path, 'w')) - if tar.wait() != 0: - raise qubes.exc.QubesException('root.img extraction failed') - if cat.wait() != 0: - raise qubes.exc.QubesException('root.img extraction failed') - elif os.path.exists(root_path): - subprocess.check_call( - ['dd', 'if='+root_path, 'of='+target_path, 'conv=sparse'] - ) - - move_if_exists(os.path.join(source_dir, 'whitelisted-appmenus.list'), - vm.dir_path) - move_if_exists(os.path.join(source_dir, 'vm-whitelisted-appmenus.list'), - vm.dir_path) - move_if_exists(os.path.join(source_dir, 'netvm-whitelisted-appmenus.list'), - vm.dir_path) - - shutil.rmtree(source_dir) - - -def post_install(args): - root_path = os.path.join(args.dir, 'root.img') - if os.path.exists(root_path + '.part.00'): - # get just file root_size from the tar header - p = subprocess.Popen(['tar', 'tvf', root_path + '.part.00'], - stdout=subprocess.PIPE, stderr=open(os.devnull, 'w')) - (stdout, _) = p.communicate() - # -rw-r--r-- 0/0 1073741824 1970-01-01 01:00 root.img - root_size = int(stdout.split()[2]) - elif os.path.exists(root_path): - root_size = os.path.getsize(root_path) - else: - raise qubes.exc.QubesException('root.img not found') - volume_config = {'root': {'size': root_size}} - - # TODO: add lock=True - app = args.app - reinstall = False - try: - # reinstall - vm = app.domains[args.name] - reinstall = True - except KeyError: - vm = app.add_new_vm(qubes.vm.templatevm.TemplateVM, - name=args.name, - label=qubes.config.defaults['template_label'], - volume_config=volume_config) - - # vm.create_on_disk() need to create the directory on its own, move it - # away for from its way - if vm.dir_path == args.dir: - shutil.move(args.dir, - os.path.join(qubes.config.qubes_base_dir, 'tmp-' + args.name)) - args.dir = os.path.join(qubes.config.qubes_base_dir, 'tmp-' + args.name) - if reinstall: - vm.remove_from_disk() - vm.create_on_disk() - vm.log.info('Importing data') - import_data(args.dir, vm) - app.save() - if os.getuid() == 0: - # fix permissions, do it only here (not after starting the VM), - # because we're running as root only at early installation phase, - # when offline mode is enabled anyway - otherwise main() would switch - # to non-root user - try: - qubes_group = grp.getgrnam('qubes') - for dirpath, _, filenames in os.walk(vm.dir_path): - os.chown(dirpath, -1, qubes_group.gr_gid) - os.chmod(dirpath, 0o2775) - for name in filenames: - filename = os.path.join(dirpath, name) - os.chown(filename, -1, qubes_group.gr_gid) - os.chmod(filename, 0o664) - except KeyError: - raise qubes.exc.QubesException('\'qubes\' group missing') - - if not app.vmm.offline_mode: - # just created, so no need to save previous value - we know what it was - vm.netvm = None - vm.start(start_guid=False) - vm.fire_event('template-postinstall') - vm.shutdown(wait=True) - vm.netvm = qubes.property.DEFAULT - return 0 - - -def pre_remove(args): - # TODO: add lock=True - app = args.app - try: - tpl = app.domains[args.name] - except KeyError: - parser.error('Qube with this name do not exist') - return 1 - for appvm in app.domains: - if hasattr(appvm, 'template') and appvm.template == tpl: - parser.error('Qube {} use this template'.format(appvm.name)) - return 1 - - del app.domains[args.name] - tpl.remove_from_disk() - app.save() - return 0 - - -def main(args=None): - if os.getuid() == 0: - try: - qubes_group = grp.getgrnam('qubes') - prefix_cmd = ['runuser', '-u', qubes_group.gr_mem[0], '--'] - os.execvp('runuser', prefix_cmd + sys.argv) - except (KeyError, IndexError): - # When group or user do not exist yet, continue as root. This - # probably also means we're still in installer, so some actions - # will not be taken anyway (because of running in chroot -> - # offline mode). - pass - args = parser.parse_args(args) - if not args.really: - parser.error('Do not call this tool directly.') - return 1 - if args.action == 'post-install': - return post_install(args) - elif args.action == 'pre-remove': - pre_remove(args) - else: - parser.error('Unknown action') - return 1 - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index 0d4b1615..2e6d76a5 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -281,7 +281,6 @@ fi %{python3_sitelib}/qubes/tools/qubesd_query.py %{python3_sitelib}/qubes/tools/qvm_backup.py %{python3_sitelib}/qubes/tools/qvm_backup_restore.py -%{python3_sitelib}/qubes/tools/qvm_template_postprocess.py %dir %{python3_sitelib}/qubes/ext %dir %{python3_sitelib}/qubes/ext/__pycache__