# Copyright (c) 2013-2015 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 KiwiConfig < Exporter attr_accessor :xml, :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_existance_of_extraced_files 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.to_xml) 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 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) ["config_files", "changed_managed_files"].each do |dir| path = @system_description.scope_file_store(dir).path if path output_root_path = File.join(output_location, "root") FileUtils.mkdir_p(output_root_path) FileUtils.cp_r(Dir.glob("#{path}/*"), output_root_path) end end unmanaged_files_path = @system_description. scope_file_store("unmanaged_files").path if unmanaged_files_path filter = "unmanaged_files_#{@name}_excludes" destination = File.join(output_location, "root", "tmp") FileUtils.mkdir_p(destination, mode: 01777) FileUtils.cp_r(unmanaged_files_path, destination) FileUtils.cp( File.join(Machinery::ROOT, "export_helpers/#{filter}"), destination ) @sh << "# Apply the extracted unmanaged files\n" @sh << "find /tmp/unmanaged_files -name *.tgz -exec " \ "tar -C / -X '/tmp/#{filter}' -xf {} \\;\n" @sh << "rm -rf '/tmp/unmanaged_files' '/tmp/#{filter}'\n" end end def check_existance_of_extraced_files missing_scopes = [] ["config_files", "changed_managed_files", "unmanaged_files"].each do |scope| if @system_description[scope] && !@system_description.scope_file_store(scope).path missing_scopes << scope end end if !missing_scopes.empty? raise Machinery::Errors::MissingExtractedFiles.new(@system_description, missing_scopes) end end def generate_config @sh = <