def add_install_to_buildscript(self): """ Add 'install' command to component's buildscript. """ if self.component_data_dict["install"] is not None: text = self.component_data_dict["install"] if self.component_data_dict["install_options"] is not None: text = "{i} {io}".format(i=self.component_data_dict["install"], io=self.component_data_dict["install_options"]) tools.add_text_to_file(self.component_data_dict["buildscript_path"], text)
def add_make_to_buildscript(self): """ Add 'make' command to component's buildscript. """ if self.component_data_dict["make"] is not None: text = self.component_data_dict["make"] if self.component_data_dict["make_options"] is not None: text = "{m} {mo}".format(m=self.component_data_dict["make"], mo=self.component_data_dict["make_options"]) tools.add_text_to_file(self.component_data_dict["buildscript_path"], text)
def run_extra_steps(self, stepname, run_directory): """ Run extra steps when building a component. 'stepname' can be 'previous' or 'post'. """ filename = os.path.join(run_directory, stepname + ".sh") self.copy_script_header(filename) tools.add_text_to_file(filename, self.component_data_dict[stepname]) self.run_script(filename, run_directory)
def add_configure_to_buildscript(self): """ Add 'configure' command to component's buildscript. """ if self.component_data_dict["configure"] is not None: text = self.component_data_dict["configure"] if self.component_data_dict["configure_options"] is not None: text = "{c} {co}".format(c=self.component_data_dict["configure"], co=self.component_data_dict["configure_options"]) tools.add_text_to_file(self.component_data_dict["buildscript_path"], text)
def add_tests_to_buildscript(self): """ Add 'test' command to component's buildscripti if 'include_tests' is true. """ if self.component_data_dict["include_tests"] is True: if self.component_data_dict["test"] is not None: text = self.component_data_dict["test"] if self.component_data_dict["test_options"] is not None: text = "{t} {to}".format(t=self.component_data_dict["test"], to=self.component_data_dict["test_options"]) tools.add_text_to_file(self.component_data_dict["buildscript_path"], text)
def test_add_text_to_file_beginning(self): """ .- check we can add text at the beginning of files """ text = "previous" test_string = "previous\n{t}".format(t=self.text) # .- add text tools.add_text_to_file(self.dummy_file, text, at_the_beginning=True) # .- read file read_text = tools.read_file(self.dummy_file) self.assertMultiLineEqual(read_text, test_string)
def test_add_text_to_file_end(self): """ .- check we can add text at the end of files """ text = "post" test_string = "{t}\npost".format(t=self.text) # .- add text tools.add_text_to_file(self.dummy_file, text) # .- read file read_text = tools.read_file(self.dummy_file) self.assertMultiLineEqual(read_text, test_string)
def apply_patches(self): """ Apply patches to the component's source code. """ cmd = "patch -N -p1 --verbose < {f}" # Search a .patch file and apply it pattern = "{n}*.patch".format(n=self.component_data_dict["package_name"]) patch_filename = tools.find_file(self.component_data_dict["sources_directory"], pattern) if patch_filename is not None: script_filename = os.path.join(self.component_data_dict["extracted_directory"], "patch.sh") # Generate 'patch.sh' script self.copy_script_header(script_filename) cmd = cmd.format(f=patch_filename) tools.add_text_to_file(script_filename, cmd) self.run_script(script_filename, run_directory=self.component_data_dict["extracted_directory"])
def generate_components_dict(self, components_filelist): """ Generate 'components_dict' from 'components_filelist'. Parse component XML file. """ components_dict = {} for componentfile_path in components_filelist: component_filename = os.path.basename(componentfile_path) component_name = self.get_component_name(component_filename) component_recipe_data = tools.read_recipe_file(component_name) # Backup xmlfile tools.backup_file(componentfile_path) # Read 'functions.py' file if exists self.extra_functions = tools.read_functions_file(component_name) # .- modify_xml if self.extra_functions is not None and \ hasattr(self.extra_functions, "modify_xmlfile"): self.extra_functions.modify_xmlfile(component_recipe_data, componentfile_path, self.modify_xmlfile) else: self.modify_xmlfile(component_recipe_data, componentfile_path) # Create XML parser on every iteration parser = ET.XMLParser(load_dtd=True, dtd_validation=False) xml_tree = ET.parse(componentfile_path, parser=parser) # Save components list to file tools.add_text_to_file(self.save_index_file, component_name) # Do not create build directory by default key = "{c}-require_build_dir".format(c=component_name) tools.add_to_dictionary(components_dict, key, "0") # Check 'screen/userinput' nodes for node in xml_tree.iter('screen'): if node.attrib.get('revision') == config.EXCLUDED_BOOT_MANAGER: # skip unselected boot manager continue for subnode in node.iter('userinput'): # Does the 'remap' attribute exists? # If not, add it to '_previous' if 'remap' in subnode.attrib: attribute = subnode.attrib.get('remap') else: attribute = "" if attribute == "pre": # Check if we have to create a build directory if subnode.text.find("mkdir -v build") != -1: key = component_name + "-require_build_dir" tools.add_to_dictionary(components_dict, key, "1", concat=False) continue # Skip patch calls as we do this step later on elif subnode.text.find("patch -Np1") != -1: continue else: key = component_name + "-previous" elif attribute == "configure": key = component_name + "-configure" elif attribute == "make": key = component_name + "-make" elif attribute == "install": key = component_name + "-install" elif attribute == "test": key = component_name + "-test" elif attribute == "check": key = component_name + "-check" elif attribute == "locale-full": # Do not run the "locale-full" command because # it is not necessary continue elif attribute == "lfsbuilder_disabled": # Do not run the "lfsbuilder_disabled" commands because # it is not necessary continue else: # By default, add it to the post steps. # Stripping does not have 'remap' attribute key = component_name + "-post" # Add the value to dictionary tools.add_to_dictionary(components_dict, key, subnode.text) # 'parser' is no longer required del parser # Restore backup if config.RESTORE_XML_BACKUPS is True: tools.restore_backup_file(componentfile_path) # Return generated dictionary return components_dict
def run_post_steps(component_data_dict, parent_function): parent_function() # Get required paths ssh_filename = os.path.join( component_data_dict["lfsbuilder_src_directory"], "recipes", "components", "openssh", "files", component_data_dict["openssh_public_key_filename"]) # .- get $HOME directory path if component_data_dict["openssh_username"] == "root": # It can be dangerous! printer.warning("WARNING: will configure SSH access for 'root'") home_directory = os.path.join(config.BASE_DIRECTORY, "root") elif component_data_dict[ "openssh_username"] == "config.NON_PRIVILEGED_USERNAME": # Update dictionary value tools.add_to_dictionary(component_data_dict, "openssh_username", config.NON_PRIVILEGED_USERNAME, concat=False) # Set home directory home_directory = os.path.join(config.BASE_DIRECTORY, "home", config.NON_PRIVILEGED_USERNAME) else: home_directory = os.path.join(config.BASE_DIRECTORY, "home", component_data_dict["openssh_username"]) # .- '$HOME/.ssh' path ssh_config_path = os.path.join(home_directory, ".ssh") # .- destination file path ssh_destination_filename = os.path.join( ssh_config_path, component_data_dict["openssh_public_key_filename"]) # .- authorized_keys authorized_keys = os.path.join(ssh_config_path, "authorized_keys") if os.path.exists(ssh_filename) is False: # Do not configure. SSH public key do not exists. msg = """WARNING: SSH access will not be configured because \ the provided public key file '{k}' do not exists.""" msg = msg.format(k=component_data_dict["openssh_public_key_filename"]) printer.warning(msg) elif tools.check_chroot_user_exists( component_data_dict["openssh_username"]) is False: # Do not configure. SSH username do not exists. msg = """WARNING: SSH access will not be configured because \ the provided username '{u}' do not exists.""" msg = msg.format(u=component_data_dict["openssh_username"]) printer.warning(msg) elif os.path.exists(home_directory) is False: # Do not configure. SSH username's home directory do not exists. msg = """WARNING: SSH access will not be configured because \ the home directory '{h}' do not exists.""" msg = msg.format(h=home_directory) printer.warning(msg) else: msg = "Installing provided SSH public key '{k}' for username '{u}'" msg = msg.format(k=component_data_dict["openssh_public_key_filename"], u=component_data_dict["openssh_username"]) printer.substep_info(msg) # .- create 'ssh_config_path' directory tools.create_directory(ssh_config_path) # .- copy public key file tools.copy_file(ssh_filename, ssh_destination_filename) # .- add to authorized keys header = "# --- {f} ---".format( f=component_data_dict["openssh_public_key_filename"]) tools.add_text_to_file(authorized_keys, header) tools.add_text_to_file(authorized_keys, tools.read_file(ssh_filename)) # .- get 'UID' and 'GID' values to set permission etc_passwd_values = tools.get_uid_gid_chroot_username( component_data_dict["openssh_username"]) # .- set 'ssh_config_path' permission tools.set_numeric_recursive_owner_and_group(ssh_config_path, etc_passwd_values["uid"], etc_passwd_values["gid"])