예제 #1
0
파일: fetch.py 프로젝트: fkfang/edi
 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
예제 #2
0
    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()
예제 #3
0
    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))
예제 #4
0
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
예제 #5
0
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)