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}" }