diff --git a/kiwi/volume_manager/btrfs.py b/kiwi/volume_manager/btrfs.py index 00ec3ebd26b..a7354045298 100644 --- a/kiwi/volume_manager/btrfs.py +++ b/kiwi/volume_manager/btrfs.py @@ -28,6 +28,7 @@ from kiwi.command import Command from kiwi.volume_manager.base import VolumeManagerBase from kiwi.mount_manager import MountManager +from kiwi.chroot_manager import ChrootManager from kiwi.storage.mapped_device import MappedDevice from kiwi.filesystem import FileSystem from kiwi.utils.sync import DataSync @@ -135,21 +136,14 @@ def setup(self, name=None): ['btrfs', 'subvolume', 'create', root_volume] ) if self.custom_args['root_is_snapper_snapshot']: - snapshot_volume = self.mountpoint + \ - f'/{self.root_volume_name}/.snapshots' - Command.run( - ['btrfs', 'subvolume', 'create', snapshot_volume] - ) - os.chmod(snapshot_volume, 0o700) - Path.create(snapshot_volume + '/1') - snapshot = self.mountpoint + \ - f'/{self.root_volume_name}/.snapshots/1/snapshot' - Command.run( - ['btrfs', 'subvolume', 'create', snapshot] - ) - self._set_default_volume( - f'{self.root_volume_name}/.snapshots/1/snapshot' - ) + with ChrootManager( + self.root_dir, binds=[self.mountpoint] + ) as chroot: + chroot.run([ + '/usr/lib/snapper/installation-helper', '--root-prefix', + os.path.join(self.mountpoint, self.root_volume_name), + '--step', 'filesystem' + ]) snapshot = self.mountpoint + \ f'/{self.root_volume_name}/.snapshots/1/snapshot' # Mount /{some-name}/.snapshots as /.snapshots inside the root @@ -413,19 +407,24 @@ def sync_data(self, exclude=None): """ if self.toplevel_mount: sync_target = self.get_mountpoint() - if self.custom_args['root_is_snapper_snapshot']: - self._create_snapshot_info( - ''.join( - [ - self.mountpoint, - f'/{self.root_volume_name}/.snapshots/1/info.xml' - ] - ) - ) data = DataSync(self.root_dir, sync_target) data.sync_data( options=Defaults.get_sync_options(), exclude=exclude ) + if self.custom_args['root_is_snapper_snapshot']: + root_prefix = os.path.join( + self.mountpoint, + f'{self.root_volume_name}/.snapshots/1/snapshot' + ) + snapshots_prefix = os.path.join(root_prefix, '.snapshots') + with ChrootManager( + self.root_dir, binds=[root_prefix, snapshots_prefix] + ) as chroot: + chroot.run([ + '/usr/lib/snapper/installation-helper', '--root-prefix', + root_prefix, '--step', 'config', '--description', + 'first root filesystem' + ]) if self.custom_args['quota_groups'] and \ self.custom_args['root_is_snapper_snapshot']: self._create_snapper_quota_configuration() @@ -503,13 +502,6 @@ def _set_default_volume(self, default_volume): 'Failed to find btrfs volume: %s' % default_volume ) - def _xml_pretty(self, toplevel_element): - xml_data_unformatted = ElementTree.tostring( - toplevel_element, 'utf-8' - ) - xml_data_domtree = minidom.parseString(xml_data_unformatted) - return xml_data_domtree.toprettyxml(indent=" ") - def _create_snapper_quota_configuration(self): root_path = os.sep.join( [ @@ -517,62 +509,15 @@ def _create_snapper_quota_configuration(self): f'{self.root_volume_name}/.snapshots/1/snapshot' ] ) - snapper_default_conf = Defaults.get_snapper_config_template_file( - root_path + # snapper requires an extra parent qgroup to operate with quotas + Command.run( + ['btrfs', 'qgroup', 'create', '1/0', self.mountpoint] ) - if snapper_default_conf: - # snapper requires an extra parent qgroup to operate with quotas - Command.run( - ['btrfs', 'qgroup', 'create', '1/0', self.mountpoint] - ) - config_file = self._set_snapper_sysconfig_file(root_path) - if not os.path.exists(config_file): - shutil.copyfile(snapper_default_conf, config_file) - Command.run([ - 'chroot', root_path, 'snapper', '--no-dbus', 'set-config', - 'QGROUP=1/0' + with ChrootManager(root_path) as chroot: + chroot.run([ + 'snapper', '--no-dbus', 'set-config', 'QGROUP=1/0' ]) - @staticmethod - def _set_snapper_sysconfig_file(root_path): - sysconf_file = SysConfig( - os.sep.join([root_path, 'etc/sysconfig/snapper']) - ) - if not sysconf_file.get('SNAPPER_CONFIGS') or \ - len(sysconf_file['SNAPPER_CONFIGS'].strip('\"')) == 0: - - sysconf_file['SNAPPER_CONFIGS'] = '"root"' - sysconf_file.write() - elif len(sysconf_file['SNAPPER_CONFIGS'].split()) > 1: - raise KiwiVolumeManagerSetupError( - 'Unsupported SNAPPER_CONFIGS value: {0}'.format( - sysconf_file['SNAPPER_CONFIGS'] - ) - ) - return os.sep.join([ - root_path, 'etc/snapper/configs', - sysconf_file['SNAPPER_CONFIGS'].strip('\"')] - ) - - def _create_snapshot_info(self, filename): - date_info = datetime.datetime.now() - snapshot = ElementTree.Element('snapshot') - - snapshot_type = ElementTree.SubElement(snapshot, 'type') - snapshot_type.text = 'single' - - snapshot_number = ElementTree.SubElement(snapshot, 'num') - snapshot_number.text = '1' - - snapshot_description = ElementTree.SubElement(snapshot, 'description') - snapshot_description.text = 'first root filesystem' - - snapshot_date = ElementTree.SubElement(snapshot, 'date') - snapshot_date.text = date_info.strftime("%Y-%m-%d %H:%M:%S") - - with open(filename, 'w') as snapshot_info_file: - snapshot_info_file.write(self._xml_pretty(snapshot)) - def __exit__(self, exc_type, exc_value, traceback): if self.toplevel_mount: self.umount_volumes()