class Omnibus::Packager::BFF
Constants
- SCRIPT_MAP
@return [Hash]
Public Instance Methods
Return the BFF-specific version for this package. This is calculated using the first three digits of the version, concatenated by a dot, then suffixed with the build_iteration.
@todo This is probably not the best way to extract the version and
probably misses edge cases like when using git describe!
@return [String]
# File lib/omnibus/packagers/bff.rb, line 289 def bff_version version = project.build_version.split(/[^\d]/)[0..2].join(".") "#{version}.#{project.build_iteration}" end
Create the bff file using mkinstallp
.
Warning: This command runs as sudo! AIX requires the use of sudo to run the mkinstallp
command.
@return [void]
# File lib/omnibus/packagers/bff.rb, line 205 def create_bff_file # We are making the assumption that sudo exists. # Unforunately, the owner of the file in the staging directory is what # will be on the target machine, and mkinstallp can't tell you if that # is a bad thing (it usually is). # The match is so we only pick the lowest level of the project dir. # This implies that if we are in /tmp/staging/project/dir/things, # we will chown from 'project' on, rather than 'project/dir', which leaves # project owned by the build user (which is incorrect) # First - let's find out who we are. shellout!("sudo chown -Rh 0:0 #{File.join(staging_dir, project.install_dir.match(%r{^/?(\w+)}).to_s)}") log.info(log_key) { "Creating .bff file" } # Since we want the owner to be root, we need to sudo the mkinstallp # command, otherwise it will not have access to the previously chowned # directory. shellout!("sudo /usr/sbin/mkinstallp -d #{staging_dir} -T #{File.join(staging_dir, "gen.template")}") # Print the full contents of the inventory file generated by mkinstallp # from within the staging_dir's .info folder (where control files for the # packaging process are kept.) log.debug(log_key) do "With .inventory file of:\n" + File.read("#{File.join( staging_dir, ".info", "#{safe_base_package_name}.inventory" )}") end # Copy the resulting package up to the package_dir FileSyncer.glob(File.join(staging_dir, "tmp/*.bff")).each do |bff| copy_file(bff, File.join(Config.package_dir, create_bff_file_name)) end ensure # chown back to original user's uid/gid so cleanup works correctly original_uid = shellout!("id -u").stdout.chomp original_gid = shellout!("id -g").stdout.chomp shellout!("sudo chown -Rh #{original_uid}:#{original_gid} #{staging_dir}") end
Create bff file name
mkinstallp
names the bff file according to the version specified in the template. We want to differentiate the build specific version correctly.
@return [String]
# File lib/omnibus/packagers/bff.rb, line 252 def create_bff_file_name "#{safe_base_package_name}-#{project.build_version}-#{project.build_iteration}.#{safe_architecture}.bff" end
@see Base#package_name
# File lib/omnibus/packagers/bff.rb, line 56 def package_name "#{safe_base_package_name}-#{project.build_version}-#{project.build_iteration}.#{safe_architecture}.bff" end
The architecture for this RPM package.
@return [String]
# File lib/omnibus/packagers/bff.rb, line 299 def safe_architecture Ohai["kernel"]["machine"] end
Return the BFF-ready base package name, converting any invalid characters to dashes (-
).
@return [String]
# File lib/omnibus/packagers/bff.rb, line 262 def safe_base_package_name if project.package_name =~ /\A[a-z0-9\.\+\-]+\z/ project.package_name.dup else converted = project.package_name.downcase.gsub(/[^a-z0-9\.\+\-]+/, "-") log.warn(log_key) do "The `name' component of BFF package names can only include " \ "lowercase alphabetical characters (a-z), numbers (0-9), dots (.), " \ "plus signs (+), and dashes (-). Converting `#{project.package_name}' to " \ "`#{converted}'." end converted end end
The path where the package scripts in the install directory.
@return [String]
# File lib/omnibus/packagers/bff.rb, line 65 def scripts_install_dir File.expand_path(File.join(project.install_dir, "embedded/share/installp")) end
The path where the package scripts will staged.
@return [String]
# File lib/omnibus/packagers/bff.rb, line 74 def scripts_staging_dir File.expand_path(File.join(staging_dir, scripts_install_dir)) end
Create the gen template for mkinstallp
.
@return [void]
Some details on the various lifecycle scripts:
The order of the installp scripts is:
-
install
-
pre-install
-
post-install
-
config
-
-
upgrade
-
pre-remove (of previous version)
-
pre-install (previous version of software not present anymore)
-
post-install
-
config
-
-
remove
-
unconfig
-
unpre-install
-
To run the new version of scc, the post-install will do. To run the previous version with an upgrade, use the pre-remove script. To run a source install of scc upon installation of installp package, use the pre-install. Upon upgrade, both the pre-remove and the pre-install scripts will run. As scc has been removed between the runs of these scripts, it will only run once during upgrade.
Keywords for scripts:
Pre-installation Script: /path/script Unpre-installation Script: /path/script Post-installation Script: /path/script Pre_rm Script: /path/script Configuration Script: /path/script Unconfiguration Script: /path/script
# File lib/omnibus/packagers/bff.rb, line 131 def write_gen_template # Get a list of all files files = FileSyncer.glob("#{staging_dir}/**/*").reject do |path| # remove any files with spaces or braces. if path =~ /[[:space:]{}]/ log.warn(log_key) { "Skipping packaging '#{path}' file due to whitespace or braces in filename" } true end end files.map! do |path| # If paths have colons or commas, rename them and add them to a post-install, # post-sysck renaming script ('config') which is created if needed if path =~ /:|,/ alt = path.gsub(/(:|,)/, "__") log.debug(log_key) { "Renaming #{path} to #{alt}" } File.rename(path, alt) if File.exist?(path) # Create a config script if needed based on resources/bff/config.erb config_script_path = File.join(scripts_staging_dir, "config") unless File.exist? config_script_path render_template(resource_path("config.erb"), destination: "#{scripts_staging_dir}/config", variables: { name: project.name, }) end File.open(File.join(scripts_staging_dir, "config"), "a") do |file| file.puts "mv '#{alt.gsub(/^#{staging_dir}/, "")}' '#{path.gsub(/^#{staging_dir}/, "")}'" end path = alt end path.gsub(/^#{staging_dir}/, "") end # Create a map of scripts that exist to inject into the template scripts = SCRIPT_MAP.inject({}) do |hash, (script, installp_key)| staging_path = File.join(scripts_staging_dir, script.to_s) if File.file?(staging_path) hash[installp_key] = staging_path log.debug(log_key) { installp_key + ":\n" + File.read(staging_path) } end hash end render_template(resource_path("gen.template.erb"), destination: File.join(staging_dir, "gen.template"), variables: { name: safe_base_package_name, install_dir: project.install_dir, friendly_name: project.friendly_name, version: bff_version, description: project.description, files: files, scripts: scripts, }) # Print the full contents of the rendered template file for mkinstallp's use log.debug(log_key) { "Rendered Template:\n" + File.read(File.join(staging_dir, "gen.template")) } end
Copy all scripts in {Project#package_scripts_path} to the package directory.
@return [void]
# File lib/omnibus/packagers/bff.rb, line 84 def write_scripts SCRIPT_MAP.each do |script, _installp_name| source_path = File.join(project.package_scripts_path, script.to_s) if File.file?(source_path) log.debug(log_key) { "Adding script `#{script}' to `#{scripts_staging_dir}'" } copy_file(source_path, scripts_staging_dir) end end end