lib/percheron/actions/create.rb in percheron-0.7.16 vs lib/percheron/actions/create.rb in percheron-0.8.0
- old
+ new
@@ -1,38 +1,34 @@
module Percheron
module Actions
class Create
-
include Base
- def initialize(unit, start: false, cmd: false, exec_scripts: true)
+ def initialize(unit, build: true, start: false, force: false, cmd: false)
@unit = unit
+ @build = build
@start = start
- @exec_scripts = exec_scripts
- @cmd = cmd
- @unit_image_existed = unit.image_exists?
+ @force = force
+ @cmd = (cmd || unit.start_args)
end
def execute!
results = []
- if unit.exists?
- $logger.debug "Unit '#{unit.display_name}' already exists"
- else
- results << create!
- end
+ results << build_or_pull_image!
+ results << create!
results.compact.empty? ? nil : unit
end
private
- attr_reader :unit, :start, :exec_scripts, :unit_image_existed
+ attr_reader :unit, :build, :start, :force, :cmd
+ alias_method :build?, :build
alias_method :start?, :start
- alias_method :exec_scripts?, :exec_scripts
- alias_method :unit_image_existed?, :unit_image_existed
+ alias_method :force?, :force
- def cmd
- @cmd ||= (@cmd || unit.start_args)
+ def create?
+ unit.startable? && (!unit.exists? || force)
end
def base_options
{
'name' => unit.full_name,
@@ -44,74 +40,89 @@
'Labels' => unit.labels
}
end
def host_config_options
- config = {
- 'HostConfig' => {
+ {
+ 'HostConfig' => {
'PortBindings' => port_bindings,
'Links' => unit.links,
- 'Binds' => unit.volumes
+ 'Binds' => unit.volumes,
+ 'RestartPolicy' => unit.restart_policy,
+ 'Privileged' => unit.privileged
}
}
- config['Dns'] = unit.dns unless unit.dns.empty?
- config
end
+ def host_config_dns_options
+ unit.dns.empty? ? {} : { 'HostConfig' => { 'Dns' => unit.dns } }
+ end
+
def options
- @options ||= base_options.merge(host_config_options)
+ @options ||= begin
+ base_options.merge(host_config_options).merge(host_config_dns_options)
+ end
end
def port_bindings
unit.ports.each_with_object({}) do |p, all|
destination, source = p.split(':')
all[source] = [ { 'HostPort' => destination } ]
end
end
- def create!
+ def build_or_pull_image!
unit.buildable? ? build_image! : pull_image!
- return unless unit.startable?
- insert_scripts!
- create_unit!
- update_dockerfile_md5!
- start!
end
+ def create!
+ if create?
+ create_unit!
+ update_dockerfile_md5!
+ start_and_insert_scripts! if start?
+ else
+ $logger.warn("Unit '#{unit.display_name}' already exists (--force to overwrite)")
+ end
+ rescue Errors::DockerContainerCannotDelete => e
+ $logger.error "Unable to delete '%s' unit - %s" % [ unit.name, e.inspect ]
+ end
+
def build_image!
- Build.new(unit).execute! unless unit.image_exists?
+ Build.new(unit).execute! if build?
end
- # FIXME: move this
def pull_image!
return nil if unit.image_exists?
$logger.info "Pulling '#{unit.image_name}' image"
Connection.perform(Docker::Image, :create, fromImage: unit.image_name) do |out|
- $logger.debug JSON.parse(out)
+ $logger.info JSON.parse(out)
end
end
+ def delete_unit!
+ $logger.info "Deleting '#{unit.display_name}' unit"
+ unit.container.remove(force: force?)
+ rescue Docker::Error::ConflictError => e
+ raise(Errors::DockerContainerCannotDelete.new, e)
+ end
+
def create_unit!
+ delete_unit! if force?
$logger.info "Creating '#{unit.display_name}' unit"
Connection.perform(Docker::Container, :create, options)
end
- def start!
- return nil if !unit.startable? || !start?
+ def start_and_insert_scripts!
Start.new(unit).execute!
+ insert_post_start_scripts!
end
def update_dockerfile_md5!
unit.update_dockerfile_md5!
end
- def insert_scripts!
- return nil if unit_image_existed?
- insert_files!(unit.post_start_scripts)
- end
-
- def insert_files!(files)
- files.each { |file| insert_file!(file) }
+ def insert_post_start_scripts!
+ unit.post_start_scripts.each { |file| insert_file!(file) }
end
def insert_file!(file)
file = Pathname.new(File.expand_path(file, base_dir))
opts = { 'localPath' => file.to_s, 'outputPath' => "/tmp/#{file.basename}" }