def _needs_qemu(self): host_architecture = get_debian_architecture() container_architecture = self.config.get_bootstrap_architecture() if host_architecture == container_architecture: return False elif host_architecture == 'amd64' and container_architecture == 'i386': return False else: return True
def run(self, config_file, introspection_method=None): self._setup_parser(config_file) if introspection_method: print(introspection_method()) return self._result() if not self._needs_qemu(): return None if os.path.isfile(self._result()): logging.info(("{0} is already there. " "Delete it to re-fetch it.").format(self._result())) return self._result() qemu_package = self.config.get_qemu_package_name() print("Going to fetch qemu Debian package ({}).".format(qemu_package)) workdir = self.config.get_workdir() with tempfile.TemporaryDirectory(dir=workdir) as tempdir: chown_to_user(tempdir) qemu_repository = self.config.get_qemu_repository() if qemu_repository: key_url = self.config.get_qemu_repository_key() else: qemu_repository = self.config.get_bootstrap_repository() key_url = self.config.get_bootstrap_repository_key() d = PackageDownloader(repository=qemu_repository, repository_key=key_url, architectures=[get_debian_architecture()]) package_file = d.download(package_name=qemu_package, dest=tempdir) apt_inst.DebFile(package_file).data.extractall(tempdir) qemu_binary = os.path.join(tempdir, 'usr', 'bin', self._get_qemu_binary_name()) chown_to_user(qemu_binary) shutil.move(qemu_binary, self._result()) print_success("Fetched qemu binary {}.".format(self._result())) return self._result()
def _write_container_metadata(self, imagedir): metadata = {} # we build this container for the host architecture # (QEMU makes sure that the binaries of a foreign architecture can also run) metadata["architecture"] = get_debian_architecture() metadata["creation_date"] = calendar.timegm(time.gmtime()) template_node = {} template_list = self.config.get_ordered_path_items("lxc_templates") if template_list: templates_dest = os.path.join(imagedir, "templates") os.mkdir(templates_dest) for name, path, dictionary in template_list: logging.info(("Loading template {} located in " "{} with dictionary:\n{}").format( name, path, yaml.dump(remove_passwords(dictionary), default_flow_style=False))) with open(path, encoding="UTF-8", mode="r") as template_file: template = Template(template_file.read()) sub_node = yaml.load(template.render(dictionary)) template_node = dict(template_node, **sub_node) templates_src = os.path.dirname(path) tpl_files = glob.iglob(os.path.join(templates_src, "*.tpl")) for tpl_file in tpl_files: if os.path.isfile(tpl_file): shutil.copy(tpl_file, templates_dest) if template_node: metadata["templates"] = template_node metadatafile = os.path.join(imagedir, "metadata.yaml") with open(metadatafile, encoding='utf-8', mode='w') as f: f.write(yaml.dump(metadata))
def test_create_buster_image(capsys): print(os.getcwd()) with workspace(): edi_exec = os.path.join(get_project_root(), 'bin', 'edi') project_name = 'pytest-{}'.format(get_random_string(6)) config_command = [ edi_exec, 'config', 'init', project_name, 'debian-buster-{}'.format(get_debian_architecture()) ] run(config_command) # run as non root parser = edi._setup_command_line_interface() cli_args = parser.parse_args( ['image', 'create', '{}-develop.yml'.format(project_name)]) Create().run_cli(cli_args) out, err = capsys.readouterr() print(out) assert not err lxc_compression_algo = get_server_image_compression_algorithm() lxc_export_extension = get_file_extension_from_image_compression_algorithm( lxc_compression_algo) images = [ os.path.join( get_artifact_dir(), '{}-develop_edicommand_image_bootstrap_di.tar.gz'.format( project_name)), os.path.join( get_artifact_dir(), '{}-develop_edicommand_lxc_prepare_di.tar.gz'.format( project_name)), os.path.join( get_artifact_dir(), '{}-develop_edicommand_lxc_export{}'.format( project_name, lxc_export_extension)), os.path.join(get_artifact_dir(), '{}-develop.result'.format(project_name)), ] for image in images: assert os.path.isfile(image) image_store_items = [ "{}-develop_edicommand_lxc_import_di".format(project_name), "{}-develop_edicommand_lxc_publish".format(project_name) ] lxc_image_list_cmd = [lxc_exec(), 'image', 'list'] result = run(lxc_image_list_cmd, stdout=subprocess.PIPE) for image_store_item in image_store_items: assert image_store_item in result.stdout parser = edi._setup_command_line_interface() cli_args = parser.parse_args([ 'image', 'create', '--clean', '{}-develop.yml'.format(project_name) ]) Create().run_cli(cli_args) parser = edi._setup_command_line_interface() cli_args = parser.parse_args([ 'image', 'create', '--recursive-clean', '8', '{}-develop.yml'.format(project_name) ]) Create().run_cli(cli_args) for image in images: assert not os.path.isfile(image) result = run(lxc_image_list_cmd, stdout=subprocess.PIPE) for image_store_item in image_store_items: assert image_store_item not in result.stdout
def test_build_stretch_container(capsys, datadir): with workspace(): edi_exec = os.path.join(get_project_root(), 'bin', 'edi') project_name = 'pytest-{}'.format(get_random_string(6)) config_command = [ edi_exec, 'config', 'init', project_name, 'debian-stretch-{}'.format(get_debian_architecture()) ] run(config_command) # run as non root # enable ssh server and create a default user modify_develop_overlay(project_name) # copy pub key into default pub key folder prepare_pub_key(datadir) container_name = 'pytest-{}'.format(get_random_string(6)) parser = edi._setup_command_line_interface() cli_args = parser.parse_args([ '-v', 'lxc', 'configure', container_name, '{}-develop.yml'.format(project_name) ]) Configure().run_cli(cli_args) out, err = capsys.readouterr() print(out) assert not err images = [ os.path.join( get_artifact_dir(), '{}-develop_edicommand_image_bootstrap.tar.gz'.format( project_name)), os.path.join( get_artifact_dir(), '{}-develop_edicommand_lxc_prepare.tar.gz'.format( project_name)) ] for image in images: assert os.path.isfile(image) lxc_image_list_cmd = [lxc_exec(), 'image', 'list'] result = run(lxc_image_list_cmd, stdout=subprocess.PIPE) assert project_name in result.stdout parser = edi._setup_command_line_interface() cli_args = parser.parse_args( ['-v', 'clean', '{}-develop.yml'.format(project_name)]) Clean().run_cli(cli_args) for image in images: assert not os.path.isfile(image) result = run(lxc_image_list_cmd, stdout=subprocess.PIPE) assert project_name not in result.stdout verification_command = [ lxc_exec(), 'exec', container_name, '--', 'cat', '/etc/os-release' ] result = run(verification_command, stdout=subprocess.PIPE) assert '''VERSION_ID="9"''' in result.stdout assert 'ID=debian' in result.stdout os.chmod(os.path.join(str(datadir), 'keys'), 0o700) os.chmod(os.path.join(str(datadir), 'keys', 'test_id_rsa'), 0o600) container_ip = get_container_ip_addr(container_name, 'lxcif0') ssh_cmd = [ 'ssh', '-i', str(os.path.join(str(datadir), 'keys', 'test_id_rsa')), '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', 'testuser@{}'.format(container_ip), 'true' ] # ssh command should work without password due to proper ssh key setup! run(ssh_cmd, sudo=True, timeout=5) verify_shared_folder(container_name) stop_command = [lxc_exec(), 'stop', container_name] run(stop_command) delete_command = [lxc_exec(), 'delete', container_name] run(delete_command)