class Rum::Manifest
Attributes
Access Docker
image object.
Public Class Methods
Initialize new manifest with name, build path, and home path for caching build digests. Evaluates &block
if given.
Example:
Manifest.new(name: "my_image", path: ".", home: ".docker")
# File lib/rumrunner/manifest.rb, line 28 def initialize(name:, path:nil, home:nil, env:nil, &block) @path = path || ENV["RUM_PATH"] || "." @home = home || ENV["RUM_HOME"] || ".docker" @env = env || [] @image = Docker::Image.parse(name) instance_eval(&block) if block_given? end
Public Instance Methods
Get application
# File lib/rumrunner/manifest.rb, line 38 def application Rake.application end
Defines +docker run+ task for redirecting a file from a running instance of the dependent stage's container to the local file system.
Example:
artifact :name => [:stage]
# File lib/rumrunner/manifest.rb, line 131 def artifact(*args, &block) name, _, deps = Rake.application.resolve_args(args) target = deps.first image = Docker::Image.parse("#{@image}-#{target}") iidfile = File.join(home, *image) path = File.split(name).first deps = [iidfile] unless path == "." directory path deps << path end artifact_file(name, deps, iidfile, &block) artifact_clobber(name, path) end
Defines generic +docker build+ task.
Example:
build :name build :name => [:deps]
# File lib/rumrunner/manifest.rb, line 61 def build(*args, &block) task(*args) do sh Docker::Build.new(options: build_options, path: path, &block).to_s end end
Defines the default task for rum
executable.
Example:
default :task_or_file default :task_or_file => [:deps]
# File lib/rumrunner/manifest.rb, line 49 def default(*args, &block) name = Rake.application.resolve_args(args).first task :default => name end
Install any remaining tasks for the manifest.
# File lib/rumrunner/manifest.rb, line 177 def install install_default unless Rake::Task.task_defined?(:default) install_clean self end
Defines generic +docker run+ task.
Example:
run :name run :name => [:deps]
# File lib/rumrunner/manifest.rb, line 74 def run(*args, &block) name, _, deps = Rake.application.resolve_args(args) images = deps.map{|dep| Docker::Image.parse("#{@image}-#{dep}") } iidfiles = images.map{|image| File.join(home, *image) } task name => iidfiles do |t| image = t.prereqs.empty? ? to_s : File.read(t.prereqs.first) sh Docker::Run.new(options: run_options, image: image, &block).to_s end end
Defines +docker run+ task for shelling into the given stage.
Example:
shell :stage shell :stage => [:deps]
# File lib/rumrunner/manifest.rb, line 157 def shell(*args, &block) target = Rake.application.resolve_args(args).first name = task_name shell: target image = Docker::Image.parse("#{@image}-#{target}") iidfile = File.join(home, *image) Rake::Task[name].clear if Rake::Task.task_defined?(name) desc "Shell into `#{target}` stage" task name, [:shell] => iidfile do |t,args| digest = File.read(iidfile) shell = args.any? ? args.to_a.join(" ") : "/bin/sh" run = Docker::Run.new(options: run_options, image: digest, &block) run.with_defaults(entrypoint: shell, interactive:true, rm: true, tty: true) sh run.to_s end end
Defines +docker build+ task for the given stage.
Example:
stage :name stage :name => [:deps]
# File lib/rumrunner/manifest.rb, line 93 def stage(*args, &block) name, _, deps = Rake.application.resolve_args(args) # Assemble image/iidfile from manifest/stage name image = Docker::Image.parse("#{@image}-#{name}") iidfile = File.join(home, *image) iidpath = File.split(iidfile).first # Ensure path to iidfile exists iiddeps = if deps.empty? directory iidpath iidpath else images = deps.map{|x| Docker::Image.parse("#{@image}-#{x}") } images.map{|x| File.join(home, *x) } end # Build stage and save digest in iidfile stage_file(iidfile, iiddeps, tag: image, target: name, &block) # Shortcut to build stage by name stage_task(name, iidfile) # Shell into stage stage_shell(name, iidfile) # Clean stage stage_clean(name, iidfile, deps) end
Private Instance Methods
Install clobber tasks for cleaning up generated files
# File lib/rumrunner/manifest.rb, line 295 def artifact_clobber(name, path) desc "Remove any generated files" task :clobber => :clean do rm_rf name rm_rf path unless path == "." end end
Install file task for artifact
# File lib/rumrunner/manifest.rb, line 283 def artifact_file(name, deps, iidfile, &block) desc "Build `#{name}`" file name => deps do digest = File.read(iidfile) run = Docker::Run.new(options: run_options, image: digest, cmd: [name], &block) run.with_defaults(rm: true, entrypoint: "cat") sh "#{run} > #{name}" end end
Get the shared build options for the Manifest
.
# File lib/rumrunner/manifest.rb, line 188 def build_options Docker::Options.new(build_arg: @env) unless @env.empty? end
Install :clean task for removing temporary Docker
images and iidfiles.
# File lib/rumrunner/manifest.rb, line 201 def install_clean desc "Remove any temporary images and products" task :clean do Dir[File.join(home, "**/*")].reverse.each do |name| sh "docker", "image", "rm", "--force", File.read(name) if File.file?(name) rm_rf name end rm_rf home if Dir.exist?(home) end end
Install :default task that builds the image
# File lib/rumrunner/manifest.rb, line 214 def install_default iidfile = File.join(home, *image) file iidfile do |t| tsfile = "#{t.name}@#{Time.now.utc.to_i}" build = Docker::Build.new(options: build_options, path: path) build.with_defaults(iidfile: tsfile, tag: tag || :latest) sh build.to_s cp tsfile, iidfile end task :default => iidfile end
Get the shared run options for the Manifest
.
# File lib/rumrunner/manifest.rb, line 194 def run_options Docker::Options.new(env: @env) unless @env.empty? end
Install clean tasks for cleaning up stage image and iidfile
# File lib/rumrunner/manifest.rb, line 264 def stage_clean(name, iidfile, deps) # Clean stage image desc "Remove any temporary images and products through `#{name}` stage" task task_name(clean: name) do if File.exist?(iidfile) sh "docker", "image", "rm", "--force", File.read(iidfile) rm_rf iidfile end end # Add stage to general clean task :clean => task_name(clean: name) # Ensure subsequent stages are cleaned before this one deps.each{|dep| task task_name(clean: dep) => task_name(clean: name) } end
Install file task for stage and save digest in iidfile
# File lib/rumrunner/manifest.rb, line 228 def stage_file(iidfile, iiddeps, tag:, target:, &block) file iidfile => iiddeps do |t| tsfile = "#{t.name}@#{Time.now.utc.to_i}" build = Docker::Build.new(options: build_options, path: path, &block) build.with_defaults(iidfile: tsfile, tag: tag, target: target) sh build.to_s cp tsfile, iidfile end end
Install shell task for shelling into stage
# File lib/rumrunner/manifest.rb, line 247 def stage_shell(name, iidfile) desc "Shell into `#{name}` stage" task task_name(shell: name), [:shell] => iidfile do |t,args| digest = File.read(t.prereqs.first) shell = args.any? ? args.to_a.join(" ") : "/bin/sh" run = Docker::Run.new(options: run_options) .entrypoint(shell) .interactive(true) .rm(true) .tty(true) .image(digest) sh run.to_s end end
Install alias task for building stage
# File lib/rumrunner/manifest.rb, line 240 def stage_task(name, iidfile) desc "Build `#{name}` stage" task name => iidfile end
Get name of support task
# File lib/rumrunner/manifest.rb, line 305 def task_name(verb_stage) case ENV["RUM_TASK_NAMES"]&.upcase when "STAGE_FIRST" verb_stage.first.reverse when "VERB_FIRST" verb_stage.first else verb_stage.first end.join(":").to_sym end