예제 #1
0
    def _run(self):
        if os.path.isfile(self._result()):
            logging.info(("{0} is already there. "
                          "Delete it to regenerate it."
                          ).format(self._result()))
            return self._result()

        self._require_sudo()

        bootstrap_cmd = Bootstrap()

        # This command is based upon the output of the bootstrap command
        bootstrap_result = bootstrap_cmd.run(self.config.get_base_config_file())

        workdir = get_workdir()

        print("Going to upgrade the bootstrap image to a lxc image.")

        with tempfile.TemporaryDirectory(dir=workdir) as tempdir:
            chown_to_user(tempdir)
            lxcimagedir = os.path.join(tempdir, "lxcimage")
            self._unpack_image(bootstrap_result, lxcimagedir)
            self._write_container_metadata(lxcimagedir)
            archive = self._pack_image(tempdir, lxcimagedir)
            chown_to_user(archive)
            create_artifact_dir()
            shutil.move(archive, self._result())

        print_success("Created lxc image {}.".format(self._result()))
        return self._result()
예제 #2
0
    def _run(self):
        if os.path.isfile(self._result()):
            logging.info(
                ("{0} is already there. "
                 "Delete it to regenerate it.").format(self._result()))
            return self._result()

        self._require_sudo()

        qemu_executable = Fetch().run(self.config.get_base_config_file())

        print("Going to bootstrap initial image - be patient.")

        if self.config.get_bootstrap_tool() != "debootstrap":
            raise FatalError(("At the moment only debootstrap "
                              "is supported for bootstrapping!"))

        workdir = get_workdir()

        with tempfile.TemporaryDirectory(dir=workdir) as tempdir:
            chown_to_user(tempdir)
            key_data = fetch_repository_key(
                self.config.get_bootstrap_repository_key())
            keyring_file = build_keyring(tempdir, "temp_keyring.gpg", key_data)
            rootfs = self._run_debootstrap(tempdir, keyring_file,
                                           qemu_executable)
            self._postprocess_rootfs(rootfs, key_data)
            archive = self._pack_image(tempdir, rootfs)
            chown_to_user(archive)
            create_artifact_dir()
            shutil.move(archive, self._result())

        print_success("Bootstrapped initial image {}.".format(self._result()))
        return self._result()
예제 #3
0
    def run(self, container_name, config_file, introspection_method=None):
        self._setup_parser(config_file)
        self.container_name = container_name

        if introspection_method:
            print(introspection_method())
            return self._result()

        Launch().run(container_name, config_file)

        print("Going to configure container {} - be patient.".format(self._result()))

        playbook_runner = PlaybookRunner(self.config, self._result(), "lxd")
        playbook_runner.run_all()

        sfc = SharedFolderCoordinator(self.config)
        sfc.create_host_folders()
        sfc.verify_container_mountpoints(container_name)

        profiles = Profile().run(config_file, include_post_config_profiles=True)
        # TODO: stop container if profiles need to be updated
        apply_profiles(container_name, profiles)
        # TODO: restart container if needed

        print_success("Configured container {}.".format(self._result()))
        return self._result()
예제 #4
0
    def run(self, project_name, config_template):
        workdir = os.getcwd()

        if os.getuid() == 0:
            raise FatalError('Do not initialize a configuration as root!')

        if not os.access(workdir, os.W_OK):
            raise FatalError('''No write access to '{}'.'''.format(workdir))

        if os.listdir(workdir):
            raise FatalError(
                'Please initialize your new configuration within an empty folder!'
            )

        source = get_project_tree()
        copy_tree(source, workdir)
        template = ConfigurationTemplate(workdir)
        with open(get_template(config_template), encoding="UTF-8",
                  mode="r") as template_file:
            t = Template(template_file.read())
            template_dict = yaml.load(t.render(get_base_dictionary())).get(
                'parameters', {})

        template_dict['edi_project_name'] = project_name
        template_dict["edi_edi_version"] = get_stripped_version(
            get_edi_version())
        template.render(template_dict)

        print_success(
            '''Configuration for project '{}' generated in folder '{}'.'''.
            format(project_name, workdir))
예제 #5
0
파일: launch.py 프로젝트: erickeller/edi
    def run(self, container_name, config_file):
        self._setup_parser(config_file)
        self.container_name = container_name

        if not is_valid_hostname(container_name):
            raise FatalError(
                ("The provided container name '{}' "
                 "is not a valid host name.").format(container_name))

        if self._is_container_existing():
            logging.info(
                ("Container {0} is already existing. "
                 "Destroy it to regenerate it or reconfigure it.").format(
                     self._result()))
            if not self._is_container_running():
                logging.info(("Starting existing container {0}.").format(
                    self._result()))
                self._start_container()
                print_success("Started container {}.".format(self._result()))
        else:
            image = Import().run(config_file)
            profiles = Profile().run(config_file)
            print("Going to launch container.")
            self._launch_container(image, profiles)
            print_success("Launched container {}.".format(self._result()))

        return self._result()
예제 #6
0
파일: export.py 프로젝트: timofurrer/edi
    def run(self, config_file, introspection_method=None):
        with command_context({'edi_create_distributable_image': True}):
            self._setup_parser(config_file)

            if introspection_method:
                print(introspection_method())
                return self._result()

            if os.path.isfile(self._result()):
                logging.info(("{0} is already there. "
                              "Delete it to regenerate it."
                              ).format(self._result()))
                return self._result()

            image_name = Publish().run(config_file)

            print("Going to export lxc image from image store.")

            export_image(image_name, self._image_without_extension())

            if (os.path.isfile(self._image_without_extension()) and
                    not os.path.isfile(self._result())):
                # Workaround for https://github.com/lxc/lxd/issues/3869
                logging.info("Fixing file extension of exported image.")
                os.rename(self._image_without_extension(), self._result())

            print_success("Exported lxc image as {}.".format(self._result()))

        return self._result()
예제 #7
0
    def clean(self, config_file):
        self._setup_parser(config_file)

        if os.path.isfile(self._result()):
            logging.info("Removing '{}'.".format(self._result()))
            os.remove(self._result())
            print_success("Removed lxc image {}.".format(self._result()))
예제 #8
0
파일: profile.py 프로젝트: erickeller/edi
    def run(self, config_file, include_post_config_profiles=False):
        self._setup_parser(config_file)

        profile_list = self.config.get_ordered_path_items("lxc_profiles")
        profile_name_list = []
        for name, path, dictionary in profile_list:
            logging.info(("Creating profile {} located in "
                          "{} with dictionary:\n{}"
                          ).format(name, path,
                                   yaml.dump(dictionary,
                                             default_flow_style=False)))

            with open(path, encoding="UTF-8", mode="r") as profile_file:
                profile = Template(profile_file.read())
                profile_text = profile.render(dictionary)
                name = self._write_lxc_profile(profile_text)
                profile_name_list.append(name)

        sfc = SharedFolderCoordinator(self.config)
        if include_post_config_profiles:
            sfc_profiles = sfc.get_post_config_profiles()
        else:
            sfc_profiles = sfc.get_pre_config_profiles()

        for profile in sfc_profiles:
            name = self._write_lxc_profile(profile)
            profile_name_list.append(name)

        print_success('The following profiles are now available: {}'.format(', '.join(profile_name_list)))
        return profile_name_list
예제 #9
0
파일: fetch.py 프로젝트: fkfang/edi
 def _clean(self):
     result = self._result()
     if not result:
         return
     elif os.path.isfile(result):
         logging.info("Removing '{}'.".format(result))
         os.remove(result)
         print_success("Removed QEMU binary {}.".format(result))
예제 #10
0
파일: launch.py 프로젝트: fkfang/edi
    def _clean(self):
        if self.config.create_distributable_image():
            # Do not delete containers that were generated using "edi lxc configure ..."!
            if try_delete_container(self._result(), self.config.get_lxc_stop_timeout()):
                print_success("Deleted lxc container {}.".format(self._result()))

        if self.clean_depth > 0:
            Import().clean_recursive(self.config.get_base_config_file(), self.clean_depth - 1)
예제 #11
0
파일: fetch.py 프로젝트: matthiasklein/edi
 def _clean(self):
     result_folder = self._result_folder()
     if not result_folder:
         return
     elif os.path.isdir(result_folder):
         logging.info("Removing '{}'.".format(result_folder))
         shutil.rmtree(result_folder)
         print_success("Removed QEMU binary folder {}.".format(result_folder))
예제 #12
0
    def _clean(self):
        if os.path.isfile(self._result()):
            logging.info("Removing '{}'.".format(self._result()))
            os.remove(self._result())
            print_success("Removed lxc image {}.".format(self._result()))

        if self.clean_depth > 0:
            Bootstrap().clean_recursive(self.config.get_base_config_file(), self.clean_depth - 1)
예제 #13
0
파일: importcmd.py 프로젝트: timofurrer/edi
    def clean(self, config_file):
        self._setup_parser(config_file)

        if is_in_image_store(self._result()):
            logging.info(("Removing '{}' from image store."
                          ).format(self._result()))
            delete_image(self._result())
            print_success("Removed {} from image store.".format(self._result()))
예제 #14
0
파일: stop.py 프로젝트: vraevsky/edi
    def _clean(self):
        if self._delete_container and try_delete_container(
                self._result(), self.config.get_lxc_stop_timeout()):
            print_success("Deleted lxc container {}.".format(self._result()))

        if self.clean_depth > 0:
            Configure().clean_recursive(self._result(),
                                        self.config.get_base_config_file(),
                                        self.clean_depth - 1)
예제 #15
0
    def _run(self):
        print("Going to configure target system ({}) - be patient.".format(
            self._result()))

        playbook_runner = PlaybookRunner(self.config, self._result(), "ssh")
        playbook_runner.run_all()

        print_success("Configured target system ({}).".format(self._result()))
        return self._result()
예제 #16
0
파일: publish.py 프로젝트: fkfang/edi
    def _clean(self):
        if is_in_image_store(self._result()):
            logging.info(("Removing '{}' from image store."
                          ).format(self._result()))
            delete_image(self._result())
            print_success("Removed {} from image store.".format(self._result()))

        if self.clean_depth > 0:
            Stop().clean_recursive(self.config.get_base_config_file(), self.clean_depth - 1)
예제 #17
0
파일: stop.py 프로젝트: vraevsky/edi
    def _run(self):
        # configure in any case since the container might be only partially configured
        Configure().run(self._result(), self.config.get_base_config_file())

        print("Going to stop lxc container {}.".format(self._result()))
        stop_container(self._result(),
                       timeout=self.config.get_lxc_stop_timeout())
        print_success("Stopped lxc container {}.".format(self._result()))

        return self._result()
예제 #18
0
    def clean(self, config_file):
        self._setup_parser(config_file)

        result = self._result()
        if not result:
            return
        elif os.path.isfile(result):
            logging.info("Removing '{}'.".format(result))
            os.remove(result)
            print_success("Removed QEMU binary {}.".format(result))
예제 #19
0
    def clean(self, config_file):
        self._setup_parser(config_file)

        if is_container_existing(self._result()):
            if is_container_running(self._result()):
                stop_container(self._result())

            delete_container(self._result())

            print_success("Deleted lxc container {}.".format(self._result()))
예제 #20
0
    def _run(self):
        print("Going to render project documentation to '{}'.".format(
            self._result()))

        documentation_step_runner = DocumentationStepRunner(
            self.config, self.raw_input, self._result())
        documentation_step_runner.check_for_absence_of_output_files()
        documentation_step_runner.run_all()
        print_success("Rendered project documentation to '{}'.".format(
            self._result()))
        return self._result()
예제 #21
0
    def run(self, ip_address, config_file):
        self._setup_parser(config_file)
        self.ip_address = ip_address

        print("Going to configure target system ({}) - be patient.".format(
            self._result()))

        playbook_runner = PlaybookRunner(self.config, self._result(), "ssh")
        playbook_runner.run_all()

        print_success("Configured target system ({}).".format(self._result()))
        return self._result()
예제 #22
0
파일: publish.py 프로젝트: fkfang/edi
    def _run(self):
        if is_in_image_store(self._result()):
            logging.info(("{0} is already in image store. "
                          "Delete it to regenerate it."
                          ).format(self._result()))
            return self._result()

        container_name = Stop().run(self.config.get_base_config_file())

        print("Going to publish lxc container in image store.")
        publish_container(container_name, self._result())
        print_success("Published lxc container in image store as {}.".format(self._result()))
        return self._result()
예제 #23
0
    def clean(self):
        for name, _, _, raw_node in self._get_documentation_steps():
            file = self._get_output_file(name, raw_node)

            file_path = os.path.join(self.rendered_output, file)
            if os.path.exists(file_path):
                logging.info("Removing '{}'.".format(file_path))
                try:
                    os.remove(file_path)
                except Exception as e:
                    raise FatalError("Failed to delete {}:\n{}".format(
                        file_path, e))

                print_success(
                    "Removed documentation file {}.".format(file_path))
예제 #24
0
    def clean(self):
        commands = self._get_commands()
        for filename, content, name, path, dictionary, raw_node, artifacts in commands:
            for _, artifact in artifacts.items():
                if not str(get_workdir()) in str(artifact):
                    raise FatalError(('Output artifact {} is not within the current working directory!'
                                      ).format(artifact))

                if os.path.isfile(artifact):
                    logging.info("Removing '{}'.".format(artifact))
                    os.remove(artifact)
                    print_success("Removed image file artifact {}.".format(artifact))
                elif os.path.isdir(artifact):
                    safely_remove_artifacts_folder(artifact, sudo=raw_node.get('require_root', False))
                    print_success("Removed image directory artifact {}.".format(artifact))
예제 #25
0
    def run(self, config_file, introspection_method=None):
        with command_context({'edi_create_distributable_image': True}):
            self._setup_parser(config_file)

            if introspection_method:
                print(introspection_method())
                return self._result()

            # configure in any case since the container might be only partially configured
            Configure().run(self._result(), config_file)

            print("Going to stop lxc container {}.".format(self._result()))
            stop_container(self._result())
            print_success("Stopped lxc container {}.".format(self._result()))

        return self._result()
예제 #26
0
    def run(self, container_name, config_file, introspection_method=None):
        self._setup_parser(config_file)
        self.container_name = container_name

        if introspection_method:
            print(introspection_method())
            return self._result()

        if not is_valid_hostname(container_name):
            raise FatalError(
                ("The provided container name '{}' "
                 "is not a valid host name.").format(container_name))

        profiles = Profile().run(config_file)

        if is_container_existing(self._result()):
            logging.info(
                ("Container {0} is already existing. "
                 "Destroy it to regenerate it or reconfigure it.").format(
                     self._result()))

            current_profiles = get_container_profiles(self._result())
            if not Launch.verify_profiles(profiles, current_profiles):
                # we might end up here if the container got imported
                # from a distributable image
                logging.info(
                    ("The profiles of container {0} need to be updated."
                     ).format(self._result()))
                if is_container_running(self._result()):
                    logging.info(
                        ("Stopping container {0} to update profiles.").format(
                            self._result()))
                    stop_container(self._result())
                apply_profiles(self._result(), profiles)

            if not is_container_running(self._result()):
                logging.info(("Starting existing container {0}.").format(
                    self._result()))
                start_container(self._result())
                print_success("Started container {}.".format(self._result()))
        else:
            image = Import().run(config_file)
            print("Going to launch container.")
            launch_container(image, self._result(), profiles)
            print_success("Launched container {}.".format(self._result()))

        return self._result()
예제 #27
0
    def _run(self):
        if is_in_image_store(self._result()):
            logging.info(
                ("{0} is already in image store. "
                 "Delete it to regenerate it.").format(self._result()))
            return self._result()

        image = LxcImageCommand().run(self.config.get_base_config_file())

        print("Going to import lxc image into image store.")

        import_image(image, self._result())

        print_success("Imported lxc image into image store as {}.".format(
            self._result()))

        return self._result()
예제 #28
0
    def _run(self):
        if not is_valid_hostname(self.container_name):
            raise FatalError(
                ("The provided container name '{}' "
                 "is not a valid host name.").format(self.container_name))

        if is_container_existing(self._result()):
            logging.info(
                ("Container {0} is already existing. "
                 "Destroy it to regenerate it or reconfigure it.").format(
                     self._result()))

            profiles = Profile().run(self.config.get_base_config_file(),
                                     include_post_config_profiles=False)
            current_profiles = get_container_profiles(self._result())
            if not Launch.verify_profiles(profiles, current_profiles):
                # we might end up here if the container got imported
                # from a distributable image
                logging.info(
                    ("The profiles of container {0} need to be updated."
                     ).format(self._result()))
                if is_container_running(self._result()):
                    logging.info(
                        ("Stopping container {0} to update profiles.").format(
                            self._result()))
                    stop_container(self._result(),
                                   timeout=self.config.get_lxc_stop_timeout())
                apply_profiles(self._result(), profiles)

            if not is_container_running(self._result()):
                logging.info(("Starting existing container {0}.").format(
                    self._result()))
                self._setup_bridge()
                start_container(self._result())
                print_success("Started container {}.".format(self._result()))
        else:
            image = Import().run(self.config.get_base_config_file())
            profiles = Profile().run(self.config.get_base_config_file(),
                                     include_post_config_profiles=False)
            self._setup_bridge()
            print("Going to launch container.")
            launch_container(image, self._result(), profiles)
            print_success("Launched container {}.".format(self._result()))

        return self._result()
예제 #29
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()
예제 #30
0
    def _run(self):
        command_runner = CommandRunner(self.config, self.section, self._input_artifact())

        if command_runner.require_root():
            self._require_sudo()

        if self._input_artifact() is not None:
            Export().run(self.config.get_base_config_file())
        else:
            logging.info("Creating new image without bootstrapping other artifacts.")

        print("Going to post process image - be patient.")

        result = command_runner.run()

        if result:
            print_success(("Completed the image creation post processing commands.\n"
                           "The following artifacts are now available:\n- {}".format('\n- '.join(result))))
        return result