class Docker::Image
Public Class Methods
Return every Image
.
# File lib/docker/image.rb, line 219 def all(opts = {}, conn = Docker.connection) hashes = Docker::Util.parse_json(conn.get('/images/json', opts)) || [] hashes.map { |hash| new(conn, hash) } end
Given a Dockerfile as a string, builds an Image
.
# File lib/docker/image.rb, line 271 def build(commands, opts = {}, connection = Docker.connection, &block) body = +"" connection.post( '/build', opts, :body => Docker::Util.create_tar('Dockerfile' => commands), :response_block => response_block(body, &block) ) new(connection, 'id' => Docker::Util.extract_id(body)) rescue Docker::Error::ServerError raise Docker::Error::UnexpectedResponseError end
Given a directory that contains a Dockerfile, builds an Image
.
If a block is passed, chunks of output produced by Docker
will be passed to that block.
# File lib/docker/image.rb, line 309 def build_from_dir(dir, opts = {}, connection = Docker.connection, creds = nil, &block) tar = Docker::Util.create_dir_tar(dir) build_from_tar tar, opts, connection, creds, &block ensure unless tar.nil? tar.close FileUtils.rm(tar.path, force: true) end end
Given File like object containing a tar file, builds an Image
.
If a block is passed, chunks of output produced by Docker
will be passed to that block.
# File lib/docker/image.rb, line 287 def build_from_tar(tar, opts = {}, connection = Docker.connection, creds = nil, &block) headers = build_headers(creds) # The response_block passed to Excon will build up this body variable. body = +"" connection.post( '/build', opts, :headers => headers, :response_block => response_block(body, &block) ) { tar.read(Excon.defaults[:chunk_size]).to_s } new(connection, 'id' => Docker::Util.extract_id(body), :headers => headers) end
A method to build the config header and merge it into the headers sent by build_from_dir.
# File lib/docker/image.rb, line 326 def self.build_headers(creds=nil) credentials = creds || Docker.creds || {} config_header = Docker::Util.build_config_header(credentials) headers = { 'Content-Type' => 'application/tar', 'Transfer-Encoding' => 'chunked' } headers = headers.merge(config_header) if config_header headers end
Create a new Image
.
# File lib/docker/image.rb, line 121 def create(opts = {}, creds = nil, conn = Docker.connection, &block) credentials = creds.nil? ? Docker.creds : MultiJson.dump(creds) headers = credentials && Docker::Util.build_auth_header(credentials) || {} body = +'' conn.post( '/images/create', opts, :headers => headers, :response_block => response_block(body, &block) ) # NOTE: see associated tests for why we're looking at image#end_with? image = opts['fromImage'] || opts[:fromImage] tag = opts['tag'] || opts[:tag] image = "#{image}:#{tag}" if tag && !image.end_with?(":#{tag}") get(image, {}, conn) end
Check if an image exists.
# File lib/docker/image.rb, line 211 def exist?(id, opts = {}, conn = Docker.connection) get(id, opts, conn) true rescue Docker::Error::NotFoundError false end
Return a specific image.
# File lib/docker/image.rb, line 139 def get(id, opts = {}, conn = Docker.connection) image_json = conn.get("/images/#{id}/json", opts) hash = Docker::Util.parse_json(image_json) || {} new(conn, hash) end
Import an Image
from the output of Docker::Container#export
. The first argument may either be a File or URI.
# File lib/docker/image.rb, line 240 def import(imp, opts = {}, conn = Docker.connection) require 'open-uri' # This differs after Ruby 2.4 if URI.public_methods.include?(:open) munged_open = URI.method(:open) else munged_open = self.method(:open) end munged_open.call(imp) do |io| import_stream(opts, conn) do io.read(Excon.defaults[:chunk_size]).to_s end end rescue StandardError raise Docker::Error::IOError, "Could not import '#{imp}'" end
# File lib/docker/image.rb, line 259 def import_stream(options = {}, connection = Docker.connection, &block) body = connection.post( '/images/create', options.merge('fromSrc' => '-'), :headers => { 'Content-Type' => 'application/tar', 'Transfer-Encoding' => 'chunked' }, &block ) new(connection, 'id'=> Docker::Util.parse_json(body)['status']) end
Load a tar Image
# File lib/docker/image.rb, line 198 def load(tar, opts = {}, conn = Docker.connection, creds = nil, &block) headers = build_headers(creds) io = tar.is_a?(String) ? File.open(tar, 'rb') : tar body = +"" conn.post( '/images/load', opts, :headers => headers, :response_block => response_block(body, &block) ) { io.read(Excon.defaults[:chunk_size]).to_s } end
Prune images
# File lib/docker/image.rb, line 152 def prune(conn = Docker.connection) conn.post("/images/prune", {}) end
Delete a specific image
# File lib/docker/image.rb, line 146 def remove(id, opts = {}, conn = Docker.connection) conn.delete("/images/#{id}", opts) end
Generates the block to be passed as a reponse block to Excon
. The returned lambda will append Docker
output to the first argument, and yield output to the passed block, if a block is given.
# File lib/docker/image.rb, line 362 def self.response_block(body) lambda do |chunk, remaining, total| body << chunk yield chunk if block_given? end end
Generates the block to be passed in to the save request. This lambda will append the streaming data to the file provided.
# File lib/docker/image.rb, line 371 def self.response_block_for_save(file) lambda do |chunk, remianing, total| file << chunk end end
Save the raw binary representation or one or more Docker
images
@param names [String, Array#String] The image(s) you wish to save @param filename [String] The file to export the data to. @param conn [Docker::Connection] The Docker
connection to use
@return [NilClass, String] If filename is nil, return the string representation of the binary data. If the filename is not nil, then return nil.
# File lib/docker/image.rb, line 166 def save(names, filename = nil, conn = Docker.connection) if filename File.open(filename, 'wb') do |file| save_stream(names, {}, conn, &response_block_for_save(file)) end nil else string = +'' save_stream(names, {}, conn, &response_block_for_save(string)) string end end
Stream the contents of Docker
image(s) to a block.
@param names [String, Array#String] The image(s) you wish to save @param conn [Docker::Connection] The Docker
connection to use @yield chunk [String] a chunk of the Docker
image(s).
# File lib/docker/image.rb, line 184 def save_stream(names, opts = {}, conn = Docker.connection, &block) # By using compare_by_identity we can create a Hash that has # the same key multiple times. query = {}.tap(&:compare_by_identity) Array(names).each { |name| query['names'.dup] = name } conn.get( '/images/get', query, opts.merge(:response_block => block) ) nil end
Given a query like ‘{ :term => ’sshd’ }‘, queries the Docker
Registry for a corresponding Image
.
# File lib/docker/image.rb, line 226 def search(query = {}, connection = Docker.connection, creds = nil) credentials = creds.nil? ? Docker.creds : creds.to_json headers = credentials && Docker::Util.build_auth_header(credentials) || {} body = connection.get( '/images/search', query, :headers => headers, ) hashes = Docker::Util.parse_json(body) || [] hashes.map { |hash| new(connection, 'id' => hash['name']) } end
Public Instance Methods
Given a path of a local file and the path it should be inserted, creates a new Image
that has that file.
# File lib/docker/image.rb, line 53 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, 'id' => Docker::Util.extract_id(body)) end
Push the Image
to the Docker
registry.
# File lib/docker/image.rb, line 27 def push(creds = nil, options = {}, &block) repo_tag = options.delete(:repo_tag) || ensure_repo_tags.first raise ArgumentError, "Image is untagged" if repo_tag.nil? repo, tag = Docker::Util.parse_repo_tag(repo_tag) raise ArgumentError, "Image does not have a name to push." if repo.nil? body = +"" credentials = creds || Docker.creds || {} headers = Docker::Util.build_auth_header(credentials) opts = {:tag => tag}.merge(options) connection.post("/images/#{repo}/push", opts, :headers => headers, :response_block => self.class.response_block(body, &block)) self end
Update the @info hash, which is the only mutable state in this object.
# File lib/docker/image.rb, line 109 def refresh! img = Docker::Image.all({:all => true}, connection).find { |image| image.id.start_with?(self.id) || self.id.start_with?(image.id) } info.merge!(self.json) img && info.merge!(img.info) self end
Remove the Image
from the server.
# File lib/docker/image.rb, line 69 def remove(opts = {}) name = opts.delete(:name) unless name if ::Docker.podman?(connection) name = self.id.split(':').last else name = self.id end end connection.delete("/images/#{name}", opts) end
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
# File lib/docker/image.rb, line 11 def run(cmd = nil, options = {}) opts = {'Image' => self.id}.merge(options) opts["Cmd"] = cmd.is_a?(String) ? cmd.split(/\s+/) : cmd begin Docker::Container.create(opts, connection) .tap(&:start!) rescue ServerError, ClientError => ex if cmd raise ex else raise ex, "No command specified." end end end
Save the image as a tarball
# File lib/docker/image.rb, line 99 def save(filename = nil) self.class.save(self.id, filename, connection) end
Save the image as a tarball to an IO object.
# File lib/docker/image.rb, line 104 def save_stream(opts = {}, &block) self.class.save_stream(self.id, opts, connection, &block) end
Tag the Image
.
# File lib/docker/image.rb, line 43 def tag(opts = {}) self.info['RepoTags'] ||= [] connection.post(path_for(:tag), opts) repo = opts['repo'] || opts[:repo] tag = opts['tag'] || opts[:tag] || 'latest' self.info['RepoTags'] << "#{repo}:#{tag}" end
Return a String representation of the Image
.
# File lib/docker/image.rb, line 85 def to_s "Docker::Image { :id => #{self.id}, :info => #{self.info.inspect}, "\ ":connection => #{self.connection} }" end
Private Instance Methods
Convience method to get the Dockerfile for a file hash and a path to output to.
# File lib/docker/image.rb, line 344 def dockerfile_for(file_hash, output_path) dockerfile = +"from #{self.id}\n" file_hash.keys.each do |basename| dockerfile << "add #{basename} #{output_path}\n" end dockerfile end
Convenience method to return the path for a particular resource.
# File lib/docker/image.rb, line 337 def path_for(resource) "/images/#{self.id}/#{resource}" end