class Spriggan::BuildJob
Public Class Methods
new(source_dir, dest_dir)
click to toggle source
# File lib/spriggan/buildjob.rb, line 11 def initialize(source_dir, dest_dir) @bare_repo = Pathname.new(source_dir).expand_path @apt_root = Pathname.new(dest_dir).expand_path unless @bare_repo.directory? and (@bare_repo + 'config').file? raise ArgumentError, 'invalid source' end unless @apt_root.directory? and (@apt_root + 'conf' + 'distributions').file? raise ArgumentError, 'invalid destination' end @project = {} @project[:root] = @bare_repo + 'spriggan' @project[:name] = @bare_repo.basename.to_s.sub(/\.git$/, '') @project[:name] = @bare_repo.parent.basename.to_s if @project[:name] == '' @project[:cache] = @project[:root] + 'cache' @build = {} @build[:timestamp] = Time.now.strftime("%Y%m%d%H%M%S") @build[:id] = @build[:timestamp] + '-' + rand(2**40).to_s(32).rjust(8, '0') @build[:root] = @project[:root] + 'jobs' + @build[:id] @build[:files] = @build[:root] + 'fs' @build[:pkgs] = @build[:root] + 'pkgs' @build[:debs] = @build[:root] + 'debs' @packages = {} @signatures = {'packages' => {}, 'metapackage' => nil} end
Public Instance Methods
run!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 42 def run! [@project[:cache], @build[:files], @build[:pkgs], @build[:debs]].each(&:mkpath) begin execute_mutations! ensure @build[:root].rmtree if @build[:root].directory? end end
Private Instance Methods
checkout_repo!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 66 def checkout_repo! @project[:sha] = `git --git-dir=#{@bare_repo} show-ref -s master`.strip @project[:tag] = `git --git-dir=#{@bare_repo} describe --tags #{@project[:sha]}`.strip @build[:files].parent.mkpath system!("git clone -s #{@bare_repo} #{@build[:files]}") Dir.chdir(@build[:files]) do system!("git checkout -q -f #{@project[:sha]}") end @project[:conf] = @build[:files] + 'spriggan' @project.update(YAML.load((@project[:conf] + 'project.yml').open)) @project[:signatures] = @project[:root] + 'signatures.yml' if @project[:signatures].file? @signatures = YAML.load(@project[:signatures].open) end end
debian_version_str(project_tag, build_timestamp, pkg_sha)
click to toggle source
# File lib/spriggan/buildjob.rb, line 208 def debian_version_str(project_tag, build_timestamp, pkg_sha) rev_parts = project_tag.split('-') rev_base_version = rev_parts.shift.sub(/^v/, '') rev_advance = nil if rev_parts.last =~ /^g[0-9a-f]{6,}$/ rev_cur_ref = rev_parts.pop rev_commits_since = rev_parts.pop rev_advance = [rev_commits_since, rev_cur_ref].join('+') end if rev_parts.length > 0 rev_full_version = [rev_base_version, rev_parts.join('+')].join('~') else rev_full_version = rev_base_version end upstream_ver = [rev_full_version, rev_advance].compact.join('+') deb_ver = [build_timestamp, pkg_sha[0...7]].join('+') [upstream_ver, deb_ver].join('-') end
do_project_specific_build!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 86 def do_project_specific_build! Dir.chdir(@build[:files]) do if bootstrap = @project['bootstrap'] system!(bootstrap['command']) end if resolve_deps = @project['resolve dependencies'] if mountpoint = resolve_deps['keep in shared cache'] with_cache_mounted(@project[:cache], @build[:files] + mountpoint) do system!(resolve_deps['command']) end else system!(resolve_deps['command']) end end if build = @project['build'] system!(build['command']) end @project['packages'].each do |pkg_name, pkg| pkg_dir = @build[:pkgs] + pkg_name pkg_dir.mkpath system!(pkg['install command'] + " " + Shellwords.escape(pkg_dir.to_s)) end end end
execute_mutations!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 55 def execute_mutations! checkout_repo! do_project_specific_build! generate_packages! generate_metapackage! publish_packages! end
generate_metapackage!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 160 def generate_metapackage! @build[:signature] = hash_metapackage @build[:vsn] = debian_version_str(@project[:tag], @build[:timestamp], @build[:signature]) deps_str = @packages.map{ |pkg_name, pkg| "-d #{pkg[:name]}" }.sort.join(' ') hooks_str = %w(before-install after-install before-remove after-remove).map{ |h| @project[:conf] + h }.find_all{ |h| h.file? }.map{ |h| "--#{h.basename.to_s} #{h}" }.join(" ") if @build[:signature] != @signatures['metapackage'] Dir.mktmpdir do |tmpdir| Dir.chdir(@build[:debs]) do system("fpm -s dir -t deb --deb-user root --deb-group root -C #{Shellwords.escape(tmpdir.to_s)} -n #{Shellwords.escape(@project[:name])} -v #{@build[:vsn]} -a all #{hooks_str} #{deps_str} .") end end @signatures['metapackage'] = @build[:signature] end end
generate_package!(pkg_dir)
click to toggle source
# File lib/spriggan/buildjob.rb, line 124 def generate_package!(pkg_dir) pkg = {} pkg[:shortname] = pkg_dir.basename.to_s pkg[:name] = "#{@project[:name]}-#{pkg[:shortname]}" pkg[:signature] = hash_package(pkg_dir) pkg[:vsn] = debian_version_str(@project[:tag], @build[:timestamp], pkg[:signature]) pkg.update(@project['packages'][pkg_dir.basename.to_s]) deps_str = "" if pkg_deps = pkg['dependencies'] deps_str = pkg_deps.map{ |dep| "-d #{Shellwords.escape(dep.to_s)}" }.join(" ") end if pkg[:signature] != @signatures['packages'][pkg[:shortname]] Dir.chdir(@build[:debs]) do system("fpm -s dir -t deb --deb-user root --deb-group root -C #{Shellwords.escape(pkg_dir.to_s)} -n #{Shellwords.escape(pkg[:name])} -v #{Shellwords.escape(pkg[:vsn])} -a all #{deps_str} .") end @signatures['packages'][pkg[:shortname]] = pkg[:signature] end pkg end
generate_packages!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 115 def generate_packages! @packages = {} @build[:pkgs].children.each do |pkg_dir| next unless pkg_dir.directory? and (pkg_dir.children.length > 0) @packages[pkg_dir.basename.to_s] = generate_package!(pkg_dir) end end
hash_metapackage()
click to toggle source
# File lib/spriggan/buildjob.rb, line 178 def hash_metapackage sigs = {} @packages.each{ |pkg_name, pkg| sigs[pkg_name] = @signatures['packages'][pkg_name] } manifest = sigs.to_a.sort.map{ |(pkg_name,sha)| "#{pkg_name} #{sha}" }.join("\n") Digest::SHA1.hexdigest(manifest) end
hash_package(pkg_dir)
click to toggle source
# File lib/spriggan/buildjob.rb, line 150 def hash_package(pkg_dir) hashes = [] pkg_dir.find do |f| next unless f.file? hashes << [f.relative_path_from(pkg_dir).to_s, Digest::SHA1.file(f).hexdigest] end manifest = hashes.sort.map{ |(name, hsh)| "#{name} #{hsh}" }.join("\n") Digest::SHA1.hexdigest(manifest) end
publish_packages!()
click to toggle source
# File lib/spriggan/buildjob.rb, line 185 def publish_packages! @build[:debs].children.each do |deb| system("dpkg-sig -k spriggan@peripia.com --sign builder #{Shellwords.escape(deb.to_s)}") system("reprepro -b #{Shellwords.escape(@apt_root.to_s)} includedeb stable #{Shellwords.escape(deb.to_s)}") end @project[:signatures].open('w'){ |f| f.write( @signatures.to_yaml ) } end
with_cache_mounted(cache_dir, mountpoint) { || ... }
click to toggle source
# File lib/spriggan/buildjob.rb, line 194 def with_cache_mounted(cache_dir, mountpoint) cache_dir.mkpath mountpoint.parent.mkpath mountpoint.make_symlink(cache_dir) begin yield ensure mountpoint.unlink FileUtils.cp_r(cache_dir, mountpoint) end end