Class: Conjure::Service::Image

Inherits:
Object
  • Object
show all
Defined in:
lib/conjure/service/docker_host.rb

Instance Method Summary collapse

Constructor Details

#initialize(host, options) ⇒ Image

Returns a new instance of Image.



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/conjure/service/docker_host.rb', line 82

def initialize(host, options)
  @host = host
  @label = options[:label]
  @base_image = options[:base_image]
  @ports = options[:ports].to_a
  @volumes = options[:volumes].to_a
  @host_volumes = options[:host_volumes]
  @setup_commands = options[:setup_commands].to_a
  @daemon_command = options[:daemon_command]
  @environment = options[:environment]
  @files = options[:files]
end

Instance Method Details

#base_image_nameObject



148
149
150
# File 'lib/conjure/service/docker_host.rb', line 148

def base_image_name
  @base_image.respond_to?(:installed_image_name) ? @base_image.installed_image_name : @base_image
end

#buildObject



152
153
154
155
156
157
# File 'lib/conjure/service/docker_host.rb', line 152

def build
  destroy_instances
  Conjure.log "[docker] Building #{@label} image"
  raise_build_errors(@host.command "build -t #{expected_image_name} -", stdin: dockerfile)
  @host.containers.destroy_all_stopped
end

#command(command, options = {}, &block) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/conjure/service/docker_host.rb', line 159

def command(command, options = {}, &block)
  destroy_instances
  file_options = options[:files] ? ["-v /files:/files"] : []
  file_options += host_volume_options(@host_volumes)
  file_options << "-i" if options[:stream_stdin]
  @host.command "run #{file_options.join ' '} #{installed_image_name} #{shell_command command}", :stream_stdin => options[:stream_stdin], :files => files_hash(options[:files]), &block
end

#destroy_instancesObject



192
193
194
# File 'lib/conjure/service/docker_host.rb', line 192

def destroy_instances
  @host.containers.destroy_all :image_name => @label
end

#dockerfileObject



139
140
141
142
143
144
145
146
# File 'lib/conjure/service/docker_host.rb', line 139

def dockerfile
  lines = ["FROM #{base_image_name}"]
  lines += @environment.map{|k, v| "ENV #{k} #{v}"} if @environment
  lines += @setup_commands.map{|c| "RUN #{c}"}
  lines << "VOLUME #{@volumes.inspect}" if @volumes.to_a.any?
  lines << "ENTRYPOINT #{@daemon_command}" if @daemon_command
  lines.join "\n"
end

#expected_image_nameObject



99
100
101
# File 'lib/conjure/service/docker_host.rb', line 99

def expected_image_name
  "#{@label}:#{image_fingerprint}"
end

#files_hash(files_array) ⇒ Object



178
179
180
181
182
# File 'lib/conjure/service/docker_host.rb', line 178

def files_hash(files_array)
  files_array.to_a.inject({}) do |hash, local_file|
    hash.merge local_file => "/files/#{File.basename local_file}"
  end
end

#host_volume_options(host_volumes) ⇒ Object



167
168
169
170
171
172
# File 'lib/conjure/service/docker_host.rb', line 167

def host_volume_options(host_volumes)
  host_volumes.to_a.map do |host_path, container_path|
    @host.ensure_host_directory host_path
    "-v=#{host_path}:#{container_path}:rw"
  end
end

#image_fingerprintObject



95
96
97
# File 'lib/conjure/service/docker_host.rb', line 95

def image_fingerprint
  Digest::SHA1.hexdigest(dockerfile)[0..11]
end

#image_installed?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/conjure/service/docker_host.rb', line 108

def image_installed?
  @host.command("history #{expected_image_name}") rescue false
end

#installed_image_nameObject



103
104
105
106
# File 'lib/conjure/service/docker_host.rb', line 103

def installed_image_name
  build unless image_installed?
  expected_image_name
end

#port_options(ports) ⇒ Object



174
175
176
# File 'lib/conjure/service/docker_host.rb', line 174

def port_options(ports)
  ports.to_a.map {|port| "-p=#{port}:#{port}" }
end

#raise_build_errors(build_output) ⇒ Object



128
129
130
131
132
133
134
135
136
137
# File 'lib/conjure/service/docker_host.rb', line 128

def raise_build_errors(build_output)
  match = build_output.match(/Error build: The command \[([^\]]*)\] returned a non-zero code:/)
  if match
    failed_command = match[1]
    last_section = build_output.split("--->").last
    last_section.gsub!(/Running in [0-9a-f]+/, "")
    last_section.gsub!(/Error build: The command.*/m, "")
    raise "Docker: build step '#{failed_command}' failed: #{last_section.strip}"
  end
end

#run(command = "") ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/conjure/service/docker_host.rb', line 112

def run(command = "")
  unless running_container
    Conjure.log "[docker] Starting #{@label}"
    run_options = host_volume_options(@host_volumes)
    run_options += port_options(@ports)
    command = shell_command command if command != ""
    container_id = @host.command("run #{run_options.join ' '} -d #{installed_image_name} #{command}").strip
    if(!running_container)
      output = @host.command "logs #{container_id}"
      raise "Docker: #{@label} daemon exited with: #{output}"
    end
  end
  Conjure.log "[docker] #{@label} is running at #{running_container.ip_address}"
  running_container
end

#running_containerObject



188
189
190
# File 'lib/conjure/service/docker_host.rb', line 188

def running_container
  @runnning_container ||= @host.containers.find(:image_name => expected_image_name)
end

#shell_command(command) ⇒ Object



184
185
186
# File 'lib/conjure/service/docker_host.rb', line 184

def shell_command(command)
  "bash -c '#{@host.shell_escape command}'"
end

#stopObject



196
197
198
# File 'lib/conjure/service/docker_host.rb', line 196

def stop
  destroy_instances
end