def __init__(self, boxname: str, arch: str = '') -> None: self.arch = arch or platform.machine() self.box_config = BoxConfig(boxname, arch) self.box_dir = os.sep.join( [Defaults.get_local_box_cache_dir(), boxname]) self.box_stage = DirFiles(self.box_dir) self.system = '' self.kernel = '' self.initrd = '' Path.create(self.box_dir)
def __init__(self, boxname, arch=None): self.box_config = BoxConfig(boxname, arch) self.box_dir = os.sep.join( [Defaults.get_local_box_cache_dir(), boxname]) self.vm_setup_type = namedtuple( 'vm_setup_type', ['system', 'kernel', 'initrd', 'append', 'ram', 'smp']) self.box_stage = DirFiles(self.box_dir) self.system = None self.kernel = None self.initrd = None Path.create(self.box_dir)
def run(self, kiwi_build_command, update_check=True, snapshot=True, keep_open=False): """ Start the build process in a box VM using KVM :param list kiwi_build_command: kiwi build command line Example: .. code:: python [ '--type', 'vmx', 'system', 'build', '--description', 'some/description', '--target-dir', 'some/target-dir' ] :param bool update_check: check for box updates True|False :param bool snapshot: run box in snapshot mode True|False :param bool keep_open: keep VM running True|False """ self.kiwi_build_command = kiwi_build_command desc = self._pop_arg_param('--description') target_dir = self._pop_arg_param('--target-dir') Path.create(target_dir) vm_setup = self.box.fetch(update_check) vm_append = [ vm_setup.append, 'kiwi=\\"{0}\\"'.format(' '.join(self.kiwi_build_command)) ] if keep_open: vm_append.append('kiwi-no-halt') vm_run = [ 'qemu-system-{0}'.format(self.arch), '-m', format(self.ram or vm_setup.ram) ] + Defaults.get_qemu_generic_setup() + [ '-kernel', vm_setup.kernel, '-append', '"{0}"'.format(' '.join(vm_append)) ] + Defaults.get_qemu_storage_setup(vm_setup.system, snapshot) + \ Defaults.get_qemu_network_setup() + \ Defaults.get_qemu_console_setup() + \ Defaults.get_qemu_shared_path_setup(0, desc, 'kiwidescription') + \ Defaults.get_qemu_shared_path_setup(1, target_dir, 'kiwibundle') if vm_setup.initrd: vm_run += ['-initrd', vm_setup.initrd] if vm_setup.smp: vm_run += ['-smp', format(vm_setup.smp)] os.environ['TMPDIR'] = Defaults.get_local_box_cache_dir() log.debug('Set TMPDIR: {0}'.format(os.environ['TMPDIR'])) log.debug('Calling Qemu: {0}'.format(vm_run)) os.system(' '.join(vm_run)) log.info('Box build done. Find build log at: {0}'.format( os.sep.join([target_dir, 'result.log'])))
def __init__(self): self.config_data = None plugin_config_file = Defaults.get_plugin_config_file() log.info( 'Reading box plugin config file: {0}'.format(plugin_config_file)) try: with open(plugin_config_file, 'r') as config: self.config_data = yaml.safe_load(config) except Exception as issue: raise KiwiBoxPluginConfigError(issue) validator = Validator(schema) validator.validate(self.config_data, schema) if validator.errors: raise KiwiBoxPluginConfigError( 'Failed to validate {0}: {1}'.format(plugin_config_file, validator.errors))
def run(self, kiwi_build_command: List[str], update_check: bool = True, snapshot: bool = True, keep_open: bool = False, kiwi_version: str = '', custom_shared_path: str = '') -> None: """ Start the build process in a box VM using KVM :param list kiwi_build_command: kiwi build command line Example: .. code:: python [ '--type', 'vmx', 'system', 'build', '--description', 'some/description', '--target-dir', 'some/target-dir' ] :param bool update_check: check for box updates True|False :param bool snapshot: run box in snapshot mode True|False :param bool keep_open: keep VM running True|False """ self.kiwi_build_command = kiwi_build_command desc = self._pop_arg_param('--description') target_dir = self._pop_arg_param('--target-dir') Path.create(target_dir) vm_setup = self.box.fetch(update_check) vm_append = [ vm_setup.append, 'kiwi=\\"{0}\\"'.format(' '.join(self.kiwi_build_command)) ] if keep_open: vm_append.append('kiwi-no-halt') if kiwi_version: vm_append.append('kiwi_version=_{0}_'.format(kiwi_version)) if custom_shared_path: vm_append.append('custom_mount=_{0}_'.format(custom_shared_path)) if self.sharing_backend == 'sshfs': ssh_key_file = os.sep.join( [os.environ.get('HOME') or '~', '.ssh', f'{self.ssh_key}.pub']) if os.path.isfile(ssh_key_file): with open(ssh_key_file) as key_fd: ssh_key = key_fd.read().split() key_type = ssh_key[0] key_value = ssh_key[1] vm_append.append(f'ssh_key=_{key_value}_') vm_append.append(f'ssh_key_type=_{key_type}_') user = pwd.getpwuid(os.geteuid()).pw_name vm_append.append('host_kiwidescription=_{0}_'.format( f'{user}@localhost:{desc}')) vm_append.append('host_kiwibundle=_{0}_'.format( f'{user}@localhost:{target_dir}')) if custom_shared_path: vm_append.append('host_custompath=_{0}_'.format( f'{user}@localhost:{custom_shared_path}')) vm_append.append('sharing_backend=_{0}_'.format(self.sharing_backend)) vm_machine = [] if self.machine: vm_machine.append('-machine') vm_machine.append(self.machine) if self.accel: vm_machine.append('-accel') vm_machine.append('accel=kvm') vm_machine.append('-cpu') vm_machine.append(self.cpu) qemu_binary = self._find_qemu_call_binary() if not qemu_binary: raise KiwiBoxPluginQEMUBinaryNotFound( f'No QEMU binary for {self.arch} found') vm_run = [ qemu_binary, '-m', format(self.ram or vm_setup.ram) ] + vm_machine + [ ] + Defaults.get_qemu_generic_setup() + [ '-kernel', vm_setup.kernel, '-append', '"{0}"'.format(' '.join(vm_append)) ] + Defaults.get_qemu_storage_setup(vm_setup.system, snapshot) + \ Defaults.get_qemu_network_setup() + \ Defaults.get_qemu_console_setup() + \ Defaults.get_qemu_shared_path_setup( 0, desc, 'kiwidescription', self.sharing_backend) + \ Defaults.get_qemu_shared_path_setup( 1, target_dir, 'kiwibundle', self.sharing_backend) if custom_shared_path: vm_run += Defaults.get_qemu_shared_path_setup( 2, custom_shared_path, 'custompath', self.sharing_backend) if self.sharing_backend == 'virtiofs': vm_run += [ '-object', '{0},id=mem,size={1},mem-path={2},share=on'.format( 'memory-backend-file', self.ram or vm_setup.ram, '/dev/shm'), '-numa', 'node,memdev=mem' ] if vm_setup.initrd: vm_run += ['-initrd', vm_setup.initrd] if vm_setup.smp: vm_run += ['-smp', format(self.smp or vm_setup.smp)] os.environ['TMPDIR'] = Defaults.get_local_box_cache_dir() log.debug('Set TMPDIR: {0}'.format(os.environ['TMPDIR'])) if self.sharing_backend == 'sshfs': log.debug('Initiating port forwarding') # delete eventual existing host key for localhost on # the kvm forwared box ssh port BOX_SSH_PORT_FORWARDED_TO_HOST # this is required because the host ssh key changes # with every kvm box run. ssh identifies this as # a potential man-in-the-middle attack and will disable # port forwarding which is required though. Command.run([ 'ssh-keygen', '-R', '[localhost]:{0}'.format( runtime.BOX_SSH_PORT_FORWARDED_TO_HOST) ], raise_on_error=False) # remote forward the host ssh port(22) into the box # at port HOST_SSH_PORT_FORWARDED_TO_BOX using the kvm forwarded # box ssh port BOX_SSH_PORT_FORWARDED_TO_HOST. This action only # completes successfully when the box has started up and is # ready to operate through ssh ssh_forward_thread = Thread(target=self._forward_host_ssh_to_guest, args=()) ssh_forward_thread.start() log.debug('Calling Qemu: {0}'.format(vm_run)) os.system(' '.join(vm_run)) for virtiofsd_process in runtime.VIRTIOFSD_PROCESS_LIST: virtiofsd_process.terminate() exit_code_file = os.sep.join([target_dir, 'result.code']) build_log_file = os.sep.join([target_dir, 'result.log']) self.kiwi_exit = 0 if os.path.exists(exit_code_file): with open(exit_code_file) as exit_code: self.kiwi_exit = int(exit_code.readline()) if self.kiwi_exit != 0: raise KiwiError( f'Box build failed. Find build log at: {build_log_file!r}') log.info(f'Box build done. Find build log at: {build_log_file!r}')
def test_get_plugin_config_file(self): assert Defaults.get_plugin_config_file() == resource_filename( 'kiwi_boxed_plugin', 'config/kiwi_boxed_plugin.yml')