class FPM::Fry::Client
Attributes
docker_url[RW]
Public Class Methods
docker_cert_path()
click to toggle source
@return [String] docker cert path from environment
# File lib/fpm/fry/client.rb, line 72 def self.docker_cert_path ENV.fetch('DOCKER_CERT_PATH',File.join(Dir.home, '.docker')) end
docker_url()
click to toggle source
# File lib/fpm/fry/client.rb, line 76 def self.docker_url ENV.fetch('DOCKER_HOST'.freeze, 'unix:///var/run/docker.sock') end
new(options = {})
click to toggle source
# File lib/fpm/fry/client.rb, line 32 def initialize(options = {}) @docker_url = options.fetch(:docker_url){ self.class.docker_url } @logger = options[:logger] if @logger.nil? @logger = Cabin::Channel.get end if options[:tls].nil? ? docker_url =~ %r!(\Ahttps://|:2376\z)! : options[:tls] # enable tls @tls = { client_cert: File.join(self.class.docker_cert_path,'cert.pem'), client_key: File.join(self.class.docker_cert_path, 'key.pem'), ssl_ca_file: File.join(self.class.docker_cert_path, 'ca.pem'), ssl_verify_peer: options.fetch(:tlsverify){ false } } [:client_cert, :client_key, :ssl_ca_file].each do |k| if !File.exist?(@tls[k]) raise ArgumentError.new("#{k} #{@tls[k]} doesn't exist. Did you set DOCKER_CERT_PATH correctly?") end end else @tls = {} end end
Public Instance Methods
agent()
click to toggle source
# File lib/fpm/fry/client.rb, line 214 def agent @agent ||= agent_for(docker_url, tls) end
agent_for( uri, tls )
click to toggle source
# File lib/fpm/fry/client.rb, line 222 def agent_for( uri, tls ) proto, address = uri.split('://',2) options = { read_timeout: 10000 }.merge( tls ) case(proto) when 'unix' uri = "unix:///" options[:socket] = address options[:host] = "" options[:hostname] = "" when 'tcp' if tls.any? return agent_for("https://#{address}", tls) else return agent_for("http://#{address}", tls) end when 'http', 'https' end logger.debug("Creating Agent", options.merge(uri: uri)) return Excon.new(uri, options) end
broken_symlinks?()
click to toggle source
# File lib/fpm/fry/client.rb, line 218 def broken_symlinks? return true end
changes(name)
click to toggle source
# File lib/fpm/fry/client.rb, line 176 def changes(name) url = url('containers',name,'changes') res = agent.get(path: url, expects: [200, 204]) return JSON.parse(res.body) rescue Excon::Error => e @logger.error("could not retrieve changes for: #{name}, url: #{url}, error: #{e}") raise end
copy(name, resource, map, options = {})
click to toggle source
# File lib/fpm/fry/client.rb, line 163 def copy(name, resource, map, options = {}) ex = FPM::Fry::Tar::Extractor.new(logger: @logger) base = File.dirname(resource) read(name, resource) do | entry | file = File.join(base, entry.full_name).chomp('/') file = file.sub(%r"\A\./",'') to = map[file] next unless to @logger.debug("Copy",name: file, to: to) ex.extract_entry(to, entry, options) end end
create(image)
click to toggle source
# File lib/fpm/fry/client.rb, line 189 def create(image) url = url('containers','create') res = agent.post( headers: { 'Content-Type' => 'application/json' }, path: url, body: JSON.generate('Image' => image) ) return JSON.parse(res.body)['Id'] rescue Excon::Error => e @logger.error("could not create image: #{image}, url: #{url}, error: #{e}") raise end
destroy(container)
click to toggle source
# File lib/fpm/fry/client.rb, line 202 def destroy(container) return unless container url = self.url('containers', container) agent.delete( path: url, expects: [204] ) rescue Excon::Error => e @logger.error("could not destroy container: #{container}, url: #{url}, error: #{e}") raise end
link_target(name, resource)
click to toggle source
Gets the target of a symlink @param [String] name the container name @param [String] resource the file name @return [String] target @return [nil] if resource is not a symlink @api docker
# File lib/fpm/fry/client.rb, line 153 def link_target(name, resource) read(name, resource) do |file| if file.header.typeflag == "2" return File.absolute_path(file.header.linkname,File.dirname(resource)) end return nil end return nil end
pull(image)
click to toggle source
# File lib/fpm/fry/client.rb, line 185 def pull(image) agent.post(path: url('images','create'), query: {'fromImage' => image}) end
read(name, resource) { |entry| ... }
click to toggle source
# File lib/fpm/fry/client.rb, line 88 def read(name, resource) return to_enum(:read, name, resource) unless block_given? url = nil res = begin if (server_version['ApiVersion'] < "1.20") url = self.url('containers', name, 'copy') agent.post( path: url, headers: { 'Content-Type' => 'application/json' }, body: JSON.generate({'Resource' => resource}), expects: [200,404,500] ) else url = self.url('containers', name, 'archive') agent.get( path: url, headers: { 'Content-Type' => 'application/json' }, query: {:path => resource}, expects: [200,404,500] ) end rescue Excon::Error => e @logger.error("unexpected response when reading resource: url: #{url}, error: #{e}") raise end if [404,500].include? res.status body_message = Hash[JSON.load(res.body).map{|k,v| ["docker.#{k}",v] }] rescue {'docker.message' => res.body} body_message['docker.container'] = name if body_message['docker.message'] =~ /\ANo such container:/ raise ContainerNotFound.new("container not found", body_message) end raise FileNotFound.new("file not found", {'path' => resource}.merge(body_message)) end sio = StringIO.new(res.body) tar = FPM::Fry::Tar::Reader.new( sio ) tar.each do |entry| yield entry end end
read_content(name, resource)
click to toggle source
Gets the file contents while following symlinks @param [String] name the container name @param [String] resource the file name @return [String] content @raise [NotAFile] when the file has no readable content @raise [FileNotFound] when the file does not exist @api docker
# File lib/fpm/fry/client.rb, line 135 def read_content(name, resource) read(name, resource) do |file| if file.header.typeflag == "2" return read_content(name, File.absolute_path(file.header.linkname,File.dirname(resource))) end if file.header.typeflag != "0" raise NotAFile.new("not a file", {'path' => resource}) end return file.read end end
server_version()
click to toggle source
@return [String] docker server api version
# File lib/fpm/fry/client.rb, line 57 def server_version @server_version ||= begin res = agent.get( expects: [200], path: '/version' ) JSON.parse(res.body) rescue Excon::Error => e @logger.error("could not read server version: url: /version, errorr #{e}") raise end end
tls?()
click to toggle source
# File lib/fpm/fry/client.rb, line 80 def tls? tls.any? end
url(*path)
click to toggle source
# File lib/fpm/fry/client.rb, line 84 def url(*path) ['', "v"+server_version['ApiVersion'], *path.compact].join('/') end