# Copyright (c) 2013-2016 SUSE LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of version 3 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact SUSE LLC. # # To contact SUSE about this file by physical or electronic mail, # you may find current contact information at www.suse.com class Machinery::KiwiConfig < Machinery::Exporter attr_accessor :xml_text, :sh attr_accessor :name def initialize(system_description, options = {}) @name = "kiwi" @system_description = system_description @options = options @system_description.assert_scopes( "repositories", "packages", "os" ) check_exported_os check_existance_of_extracted_files check_repositories generate_config end def write(output_location) inject_users_and_groups(output_location) inject_extracted_files(output_location) @sh << "baseCleanMount\n" @sh << "exit 0\n" File.write(File.join(output_location, "config.xml"), xml_text) File.write(File.join(output_location, "config.sh"), @sh) FileUtils.cp( File.join(Machinery::ROOT, "export_helpers/kiwi_export_readme.md"), File.join(output_location, "README.md") ) post_process_config(output_location) end def export_name "#{@system_description.name}-kiwi" end private def repos_with_credentials?(repo) repo.username && repo.password end def optional_bootstrap_packages [ "glibc-locale", "module-init-tools", "cracklib-dict-full", "ca-certificates", "ca-certificates-mozilla" ] end def add_bootstrap_packages(xml) xml.packages(type: "bootstrap") do xml.package(name: "filesystem") bootstrap_packages = @system_description.packages.select { |package| optional_bootstrap_packages.include?(package.name) } bootstrap_packages.each do |package| xml.package(name: package.name) end end end def pre_process_config enable_ssh if @options[:enable_ssh] end def post_process_config(output_location) enable_dhcp(output_location) if @options[:enable_dhcp] end def inject_users_and_groups(output_location) return if !@system_description.users || !@system_description.groups merge_script_name = "merge_users_and_groups.pl" template = ERB.new( File.read(File.join(Machinery::ROOT, "export_helpers", "#{merge_script_name}.erb")) ) passwd_entries = @system_description.users.map do |u| passwd = [u.name, u.password, u.uid, u.gid, u.comment, u.home, u.shell].join(":") # The shadow file contains an eigth reserved field at the end, so we have # to manually add it, too. shadow = [u.name, u.encrypted_password, u.last_changed_date, u.min_days, u.max_days, u.warn_days, u.disable_days, u.disabled_date, ""].join(":") "['#{passwd}', '#{shadow}']" end.join(",\n") group_entries = @system_description.groups.map do |g| "'#{g.name}:#{g.password}:#{g.gid}:#{g.users.join(",")}'" end.join(",\n") FileUtils.mkdir_p(File.join(output_location, "root", "tmp"), mode: 01777) script_path = File.join(output_location, "root", "tmp", merge_script_name) File.write(script_path, template.result(binding)) @sh << "perl /tmp/#{merge_script_name} /etc/passwd /etc/shadow /etc/group\n" @sh << "rm /tmp/#{merge_script_name}\n" end def inject_extracted_files(output_location) ["changed_managed_files", "changed_config_files"].each do |scope| next unless @system_description.scope_extracted?(scope) output_root_path = File.join(output_location, "root") FileUtils.mkdir_p(output_root_path) @system_description[scope].each do |file| if file.deleted? @sh << "rm -rf '#{quote(file.name)}'\n" elsif file.directory? @sh << <