Class: Docker::Image

Inherits:
Object
  • Object
show all
Extended by:
Error
Includes:
Error
Defined in:
lib/docker/image.rb

Overview

This class represents a Docker Image.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, id = nil, info = {}) ⇒ Image

The private new method accepts a connection and optional id.



8
9
10
11
12
13
14
# File 'lib/docker/image.rb', line 8

def initialize(connection, id = nil, info = {})
  if connection.is_a?(Docker::Connection)
    @connection, @id, @info = connection, id, info
  else
    raise ArgumentError, "Expected a Docker::Connection, got: #{connection}."
  end
end

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



5
6
7
# File 'lib/docker/image.rb', line 5

def connection
  @connection
end

#idObject

Returns the value of attribute id.



5
6
7
# File 'lib/docker/image.rb', line 5

def id
  @id
end

#infoObject

Returns the value of attribute info.



5
6
7
# File 'lib/docker/image.rb', line 5

def info
  @info
end

Class Method Details

.all(opts = {}, conn = Docker.connection) ⇒ Object

Return every Image.



133
134
135
136
# File 'lib/docker/image.rb', line 133

def all(opts = {}, conn = Docker.connection)
  hashes = Docker::Util.parse_json(conn.get('/images/json', opts)) || []
  hashes.map { |hash| new(conn, hash['Id'], hash.tap{|h| h.delete('Id')}) }
end

.build(commands, opts = {}, connection = Docker.connection) ⇒ Object

Given a Dockerfile as a string, builds an Image.



160
161
162
163
164
165
166
167
168
# File 'lib/docker/image.rb', line 160

def build(commands, opts = {}, connection = Docker.connection)
  body = connection.post(
    '/build', opts,
    :body => Docker::Util.create_tar('Dockerfile' => commands)
  )
  new(connection, Docker::Util.extract_id(body))
rescue Docker::Error::ServerError
  raise Docker::Error::UnexpectedResponseError
end

.build_from_dir(dir, opts = {}, connection = Docker.connection) ⇒ Object

Given a directory that contains a Dockerfile, builds an Image.



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/docker/image.rb', line 171

def build_from_dir(dir, opts = {}, connection = Docker.connection)
  tar = Docker::Util.create_dir_tar(dir)
  body = connection.post(
    '/build', opts,
    :headers => { 'Content-Type'      => 'application/tar',
                  'Transfer-Encoding' => 'chunked' }
  ) { tar.read(Excon.defaults[:chunk_size]).to_s }
  new(connection, Docker::Util.extract_id(body))
ensure
  tar.close unless tar.nil?
end

.create(opts = {}, creds = nil, conn = Docker.connection) ⇒ Object

Create a new Image.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/docker/image.rb', line 108

def create(opts = {}, creds = nil, conn = Docker.connection)
  credentials = (creds.nil?) ? creds.to_json : Docker.creds
  headers = if credentials.nil?
    Docker::Util.build_auth_header(credentials)
  else
    {}
  end
  instance = new(conn, {}, :headers => headers)
  conn.post('/images/create', opts)
  id = opts['repo'] ? "#{opts['repo']}/#{opts['tag']}" : opts['fromImage']
  if (instance.id = id).nil?
    raise UnexpectedResponseError, 'Create response did not contain an Id'
  else
    instance
  end
end

.get(id, opts = {}, conn = Docker.connection) ⇒ Object

Return a specific image.



126
127
128
129
130
# File 'lib/docker/image.rb', line 126

def get(id, opts = {}, conn = Docker.connection)
  image_json = conn.get("/images/#{URI.encode(id)}/json", opts)
  hash = Docker::Util.parse_json(image_json) || {}
  new(conn, hash['id'])
end

.import(file, options = {}, connection = Docker.connection) ⇒ Object

Import an Image from the output of Docker::Container#export.



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/docker/image.rb', line 147

def import(file, options = {}, connection = Docker.connection)
  File.open(file, 'r') do |io|
    body = connection.post(
      '/images/create',
       options.merge('fromSrc' => '-'),
       :headers => { 'Content-Type' => 'application/tar',
                     'Transfer-Encoding' => 'chunked' }
    ) { io.read(Excon.defaults[:chunk_size]).to_s }
    new(connection, Docker::Util.parse_json(body)['status'])
  end
end

.search(query = {}, connection = Docker.connection) ⇒ Object

Given a query like ‘{ :term => ’sshd’ }‘, queries the Docker Registry for a corresponding Image.



140
141
142
143
144
# File 'lib/docker/image.rb', line 140

def search(query = {}, connection = Docker.connection)
  body = connection.get('/images/search', query)
  hashes = Docker::Util.parse_json(body) || []
  hashes.map { |hash| new(connection, hash['Name']) }
end

Instance Method Details

#insert(query = {}) ⇒ Object

Insert a file into the Image, returns a new Image that has that file.



59
60
61
62
63
64
65
66
# File 'lib/docker/image.rb', line 59

def insert(query = {})
  body = connection.post(path_for(:insert), query)
  if (id = body.match(/{"Id":"([a-f0-9]+)"}\z/)).nil? || id[1].empty?
    raise UnexpectedResponseError, "Could not find Id in '#{body}'"
  else
    self.class.send(:new, connection, id[1])
  end
end

#insert_local(opts = {}) ⇒ Object

Given a path of a local file and the path it should be inserted, creates a new Image that has that file.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/docker/image.rb', line 70

def insert_local(opts = {})
  local_paths = opts.delete('localPath')
  output_path = opts.delete('outputPath')

  local_paths = [ local_paths ] unless local_paths.is_a?(Array)

  file_hash = Docker::Util.file_hash_from_paths(local_paths)

  file_hash['Dockerfile'] = dockerfile_for(file_hash, output_path)

  tar = Docker::Util.create_tar(file_hash)
  body = connection.post('/build', opts, :body => tar)
  self.class.send(:new, connection, Docker::Util.extract_id(body))
end

#push(creds = nil, options = {}) ⇒ Object

Push the Image to the Docker registry.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/docker/image.rb', line 36

def push(creds = nil, options = {})
  repository = self.info['Repository']
  unless repository
    raise ArgumentError
      "Image does not have a name to push, got: #{repository}."
  end

  credentials = (creds.nil?) ? Docker.creds : creds.to_json
  headers = Docker::Util.build_auth_header(credentials)
  connection.post(
    "/images/#{repository}/push",
    options,
    :headers => headers
  )
  self
end

#removeObject

Remove the Image from the server.



86
87
88
# File 'lib/docker/image.rb', line 86

def remove
  connection.delete("/images/#{self.id}")
end

#run(cmd = nil) ⇒ Object

Given a command and optional list of streams to attach to, run a command on an Image. This will not modify the Image, but rather create a new Container to run the Image. If the image has an embedded config, no command is necessary, but it will fail with 500 if no config is saved with the image



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/docker/image.rb', line 20

def run(cmd=nil)
  opts = { 'Image' => self.id }
  opts["Cmd"] = cmd.is_a?(String) ? cmd.split(/\s+/) : cmd
  begin
    Docker::Container.create(opts, connection)
                     .tap(&:start!)
  rescue ServerError
    if cmd
      raise ServerError, "Docker Server Error."
    else
      raise ServerError, "No command specified."
    end
  end
end

#tag(opts = {}) ⇒ Object

Tag the Image.



54
55
56
# File 'lib/docker/image.rb', line 54

def tag(opts = {})
  Docker::Util.parse_json(connection.post(path_for(:tag), opts))
end

#to_sObject

Return a String representation of the Image.



91
92
93
94
# File 'lib/docker/image.rb', line 91

def to_s
  "Docker::Image { :id => #{self.id}, :info => #{self.info.inspect}, "\
    ":connection => #{self.connection} }"
end