Class: FPM::Fry::Client

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/fpm/fry/client.rb

Defined Under Namespace

Classes: FileNotFound

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Client



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/fpm/fry/client.rb', line 20

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.exists?(@tls[k])
        raise ArgumentError.new("#{k} #{@tls[k]} doesn't exist. Did you set DOCKER_CERT_PATH correctly?")
      end
    end
  else
    @tls = {}
  end
end

Instance Attribute Details

#docker_urlObject (readonly)

Returns the value of attribute docker_url.



18
19
20
# File 'lib/fpm/fry/client.rb', line 18

def docker_url
  @docker_url
end

#loggerObject (readonly)

Returns the value of attribute logger.



18
19
20
# File 'lib/fpm/fry/client.rb', line 18

def logger
  @logger
end

#tlsObject (readonly)

Returns the value of attribute tls.



18
19
20
# File 'lib/fpm/fry/client.rb', line 18

def tls
  @tls
end

Class Method Details

.docker_cert_pathObject



54
55
56
# File 'lib/fpm/fry/client.rb', line 54

def self.docker_cert_path
  ENV.fetch('DOCKER_CERT_PATH',File.join(Dir.home, '.docker'))
end

.docker_urlObject



58
59
60
# File 'lib/fpm/fry/client.rb', line 58

def self.docker_url
  ENV.fetch('DOCKER_HOST'.freeze, 'unix:///var/run/docker.sock')
end

Instance Method Details

#agentObject



109
110
111
# File 'lib/fpm/fry/client.rb', line 109

def agent
  @agent ||= agent_for(docker_url, tls)
end

#agent_for(uri, tls) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/fpm/fry/client.rb', line 117

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
  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?Boolean



113
114
115
# File 'lib/fpm/fry/client.rb', line 113

def broken_symlinks?
  return true
end

#changes(name) ⇒ Object



103
104
105
106
107
# File 'lib/fpm/fry/client.rb', line 103

def changes(name)
  res = agent.get(path: url('containers',name,'changes'))
  raise res.reason if res.status != 200
  return JSON.parse(res.body)
end

#copy(name, resource, map, options = {}) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/fpm/fry/client.rb', line 90

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

#read(name, resource) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fpm/fry/client.rb', line 71

def read(name, resource)
  return to_enum(:read, name, resource) unless block_given?
  body = JSON.generate({'Resource' => resource})
  res = agent.post(
    path: url('containers',name,'copy'),
    headers: { 'Content-Type' => 'application/json' },
    body: body,
    expects: [200,500]
  )
  if res.status == 500
    raise FileNotFound, "File #{resource.inspect} not found: #{res.body}"
  end
  sio = StringIO.new(res.body)
  tar = ::Gem::Package::TarReader.new( sio )
  tar.each do |entry|
    yield entry
  end
end

#server_versionObject



44
45
46
47
48
49
50
51
52
# File 'lib/fpm/fry/client.rb', line 44

def server_version
  @server_version ||= begin
    res = agent.get(
      expects: [200],
      path: '/version'
    )
    JSON.parse(res.body)
  end
end

#tls?Boolean



62
63
64
# File 'lib/fpm/fry/client.rb', line 62

def tls?
  tls.any?
end

#url(*path) ⇒ Object



67
68
69
# File 'lib/fpm/fry/client.rb', line 67

def url(*path)
  ['', "v"+server_version['ApiVersion'],*path].join('/')
end