def _teardown_chroot_mounts(self): if not self.plugin_config.get('recursive_unmount', False): if self.plugin_config.get('configure_mounts', True): for mountdef in reversed(self.plugin_config.chroot_mounts): dev, fstype, mountpoint, options = mountdef mountpoint = mountpoint.lstrip('/') mountpoint = os.path.join(self.root_mountspec.mountpoint, mountpoint) mountspec = MountSpec(dev, fstype, mountpoint, options) log.debug('Attempting to unmount {0.mountpoint}'.format( mountspec)) try: self._unmount(mountspec) except VolumeException as ve: log.critical('Unable to unmount {0.mountpoint}'.format( mountspec)) return False log.debug('Checking for stray mounts') for mountpoint in lifo_mounts(self.root_mountspec.mountpoint): log.debug( 'Stray mount found: {0}, attempting to unmount'.format( mountpoint)) try: self._unmount(mountpoint) except VolumeException as ve: log.critical( 'Unable to unmount {0}'.format(mountpoint)) return False if not self._unmount_root(): err = 'Unable to unmount root volume at {0.mountpoint)' err = err.format(self.root_mountspec) log.critical(err) return False log.debug('Teardown of chroot mounts succeeded!') return True
def setup_method(self, method): self.config = Config() self.config.plugins = Config() # TODO: this is fragile as it may depend on the dir the tests were run from self.config.plugins[ 'aminator.plugins.provisioner.apt'] = self.config.from_file( yaml_file= 'aminator/plugins/provisioner/default_conf/aminator.plugins.provisioner.apt.yml' ) log.info(self.config.plugins) self.plugin = AptProvisionerPlugin() self.plugin._config = self.config config = self.plugin._config.plugins[ 'aminator.plugins.provisioner.apt'] # use /tmp if not configured, ideally to use tempfile, but needs C build self.full_path = os.path.join( config.get('mountpoint', '/tmp'), config.get('policy_file_path', '/usr/sbin'), config.get('policy_file', 'policy-rc.d')) self.plugin._root_mountspec = MountSpec( None, None, config.get('mountpoint', '/tmp'), None) # cleanup if os.path.isfile(self.full_path): os.remove(self.full_path)
def _mount(self): if self._config.volume_dir.startswith(('~', '/')): self._volume_root = os.path.expanduser(self._config.volume_dir) else: self._volume_root = os.path.join(self._config.aminator_root, self._config.volume_dir) self._mountpoint = os.path.join(self._volume_root, os.path.basename(self._dev)) if not os.path.exists(self._mountpoint): os.makedirs(self._mountpoint) if not mounted(self._mountpoint): # Handle optional partition dev = self._dev if self._blockdevice.partition is not None: dev = '{0}{1}'.format(dev, self._blockdevice.partition) mountspec = MountSpec(dev, None, self._mountpoint, None) result = mount(mountspec) if not result.success: msg = 'Unable to mount {0.dev} at {0.mountpoint}: {1}'.format( mountspec, result.result.std_err) log.critical(msg) raise VolumeException(msg) log.debug( 'Mounted {0.dev} at {0.mountpoint} successfully'.format(mountspec))
def _teardown_chroot_mounts(self): config = self._config.plugins[self.full_name] for mountdef in reversed(config.chroot_mounts): dev, fstype, mountpoint, options = mountdef mountspec = MountSpec( dev, fstype, os.path.join(self._mountpoint, mountpoint.lstrip('/')), options) log.debug('Attempting to unmount {0}'.format(mountspec)) if not mounted(mountspec.mountpoint): log.warn('{0} not mounted'.format(mountspec.mountpoint)) continue result = unmount(mountspec.mountpoint) if not result.success: log.error( 'Unable to unmount {0.mountpoint}: {1.stderr}'.format( mountspec, result)) return False log.debug('Checking for stray mounts') for mountpoint in lifo_mounts(self._mountpoint): log.debug('Stray mount found: {0}, attempting to unmount'.format( mountpoint)) result = unmount(mountpoint) if not result.success: log.error( 'Unable to unmount {0.mountpoint}: {1.stderr}'.format( mountspec, result)) return False log.debug('Teardown of chroot mounts succeeded!') return True
def _configure_chroot_mounts(self): config = self._config.plugins[self.full_name] for mountdef in config.chroot_mounts: dev, fstype, mountpoint, options = mountdef mountspec = MountSpec(dev, fstype, os.path.join(self._mountpoint, mountpoint.lstrip('/')), options) log.debug('Attempting to mount {0}'.format(mountspec)) if not mounted(mountspec.mountpoint): result = mount(mountspec) if not result.success: log.critical('Unable to configure chroot: {0.std_err}'.format(result.result)) return False log.debug('Mounts configured') return True
def _configure_chroot_mounts(self): log.debug('Attempting to mount root volume: {0}'.format( self.root_mountspec)) if not self._mount(self.root_mountspec): log.critical('Failed to mount root volume') return False if self.plugin_config.get('configure_mounts', True): for mountdef in self.plugin_config.chroot_mounts: dev, fstype, mountpoint, options = mountdef mountpoint = mountpoint.lstrip('/') mountpoint = os.path.join(self.root_mountspec.mountpoint, mountpoint) mountspec = MountSpec(dev, fstype, mountpoint, options) log.debug('Attempting to mount {0}'.format(mountspec)) if not self._mount(mountspec): log.critical('Mount failure, unable to configure chroot') return False log.debug('Mounts configured') return True
def __enter__(self): if self._config.volume_dir.startswith(('~', '/')): root_base = os.path.expanduser(self._config.volume_dir) else: root_base = os.path.join(self._config.aminator_root, self._config.volume_dir) root_mountpoint = os.path.join( root_base, os.path.basename(self.context.volume.dev)) self._root_mountspec = MountSpec(self.context.volume.dev, None, root_mountpoint, None) try: chroot_setup = self._configure_chroot() except Exception as e: chroot_setup = False log.critical( 'Error encountered during chroot setup. Attempting to clean up volumes.' ) self._teardown_chroot_mounts() if not chroot_setup: raise VolumeException('Error configuring chroot') return self