Class: Conjure::Service::Image

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, options) ⇒ Image

Returns a new instance of Image.



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/conjure/service/docker_host.rb', line 85

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 Attribute Details

#host_volumesObject (readonly)

Returns the value of attribute host_volumes.



83
84
85
# File 'lib/conjure/service/docker_host.rb', line 83

def host_volumes
  @host_volumes
end

Instance Method Details

#base_image_nameObject



157
158
159
# File 'lib/conjure/service/docker_host.rb', line 157

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

#buildObject



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

def build
  destroy_instances
  Log.info "[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



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

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



201
202
203
# File 'lib/conjure/service/docker_host.rb', line 201

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

#dockerfileObject



142
143
144
145
146
147
148
149
# File 'lib/conjure/service/docker_host.rb', line 142

def dockerfile
  lines = ["FROM #{base_image_name}"]
  lines += dockerfile_environment_entries
  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

#dockerfile_environment_entriesObject



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

def dockerfile_environment_entries
  @environment.to_a.map do |k, v|
    "ENV #{k} #{v}" if v.to_s != ""
  end.compact
end

#expected_image_nameObject



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

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

#files_hash(files_array) ⇒ Object



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

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



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

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



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

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

#image_installed?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/conjure/service/docker_host.rb', line 111

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

#installed_image_nameObject



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

def installed_image_name
  build unless image_installed?
  expected_image_name
end

#port_options(ports) ⇒ Object



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

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

#raise_build_errors(build_output) ⇒ Object



131
132
133
134
135
136
137
138
139
140
# File 'lib/conjure/service/docker_host.rb', line 131

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



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

def run(command = "")
  unless running_container
    Log.info "[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
  Log.info "[docker] #{@label} is running at #{running_container.ip_address}"
  running_container
end

#running_containerObject



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

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

#shell_command(command) ⇒ Object



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

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

#stopObject



205
206
207
# File 'lib/conjure/service/docker_host.rb', line 205

def stop
  destroy_instances
end