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()
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()
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()
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))
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()
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()
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()))
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
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))
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)
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))
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)
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()))
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)
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()
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)
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()
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))
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()))
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()
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()
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()
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))
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))
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()
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()
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()
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()
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 _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