fpm-fry 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cabin/nice_output.rb +16 -1
- data/lib/fpm/fry/block_enumerator.rb +6 -3
- data/lib/fpm/fry/channel.rb +13 -0
- data/lib/fpm/fry/chroot.rb +2 -2
- data/lib/fpm/fry/client.rb +81 -6
- data/lib/fpm/fry/command.rb +11 -31
- data/lib/fpm/fry/command/cook.rb +19 -51
- data/lib/fpm/fry/detector.rb +43 -98
- data/lib/fpm/fry/docker_file.rb +3 -11
- data/lib/fpm/fry/exec.rb +76 -0
- data/lib/fpm/fry/inspector.rb +70 -0
- data/lib/fpm/fry/joined_io.rb +1 -1
- data/lib/fpm/fry/plugin/edit_staging.rb +1 -1
- data/lib/fpm/fry/plugin/init.rb +71 -42
- data/lib/fpm/fry/plugin/service.rb +108 -49
- data/lib/fpm/fry/recipe.rb +46 -21
- data/lib/fpm/fry/recipe/builder.rb +26 -13
- data/lib/fpm/fry/source.rb +14 -12
- data/lib/fpm/fry/source/{package.rb → archive.rb} +68 -31
- data/lib/fpm/fry/source/dir.rb +2 -5
- data/lib/fpm/fry/source/git.rb +70 -43
- data/lib/fpm/fry/source/patched.rb +14 -10
- data/lib/fpm/fry/with_data.rb +34 -0
- data/lib/fpm/package/docker.rb +15 -0
- metadata +5 -4
- data/lib/fpm/fry/os_db.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de6bc3a9f29acd7c147a4016c4906fd0a35c6481
|
4
|
+
data.tar.gz: afece6f8aea44147df5e357015115f9c74614071
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fea3ee2114b957eca0789a06faab401d88ff9269bf95ffab42ce79f367716d4b962b964e44aa03ef58087c50c1df5c904195f1ac44cde705bc17c5c0a9d2e63
|
7
|
+
data.tar.gz: ccee1a75f08a186ff5a44e673d297ca41e2ce6faee2b4df57715542eafbf8640b605e0f7c619958f8b4a7967abd76b8192eadd6e72d5ffcecb07ab1ca27c9949
|
data/lib/cabin/nice_output.rb
CHANGED
@@ -80,8 +80,23 @@ class Cabin::NiceOutput
|
|
80
80
|
@io.flush
|
81
81
|
end
|
82
82
|
|
83
|
+
private
|
84
|
+
|
83
85
|
def pp(hash)
|
84
|
-
hash.map{|k,v| ' '+k.to_s + ": " + v
|
86
|
+
hash.map{|k,v| ' '+k.to_s + ": " + pp_value(v) }.join("\n")
|
87
|
+
end
|
88
|
+
|
89
|
+
def pp_value(value)
|
90
|
+
case(value)
|
91
|
+
when String
|
92
|
+
if value.include? "\n"
|
93
|
+
return "\n\t" + value.gsub("\n","\n\t")
|
94
|
+
else
|
95
|
+
return value
|
96
|
+
end
|
97
|
+
else
|
98
|
+
return value.inspect
|
99
|
+
end
|
85
100
|
end
|
86
101
|
|
87
102
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
module FPM; module Fry
|
2
|
+
# Helper class that reads an IO in chunks.
|
3
|
+
#
|
4
|
+
# @api private
|
2
5
|
class BlockEnumerator < Struct.new(:io, :blocksize)
|
3
6
|
include Enumerable
|
4
7
|
|
5
|
-
# @param
|
6
|
-
# @param
|
7
|
-
def initialize(
|
8
|
+
# @param [IO] io
|
9
|
+
# @param [Numeric] blocksize
|
10
|
+
def initialize(io, blocksize = 128)
|
8
11
|
super
|
9
12
|
end
|
10
13
|
|
data/lib/fpm/fry/channel.rb
CHANGED
@@ -1,17 +1,30 @@
|
|
1
1
|
require 'cabin/channel'
|
2
2
|
module FPM; module Fry
|
3
|
+
# A {Cabin::Channel} with two additional features:
|
4
|
+
#
|
5
|
+
# - There is a new log level 'hint' which can point users to improvements.
|
6
|
+
# - Logging an Exception that responds to #data will merge in the data from
|
7
|
+
# this exception. This is used together with {FPM::Fry::WithData}
|
8
|
+
#
|
9
|
+
# @api internal
|
3
10
|
class Channel < Cabin::Channel
|
4
11
|
|
5
12
|
module Hint
|
13
|
+
# Logs a message with level 'hint'
|
14
|
+
#
|
15
|
+
# @param [String] message
|
16
|
+
# @param [Hash] data
|
6
17
|
def hint( message, data = {} )
|
7
18
|
return unless hint?
|
8
19
|
log(message, data.merge(level: :hint))
|
9
20
|
end
|
10
21
|
|
22
|
+
# True if hints should be displayed
|
11
23
|
def hint?
|
12
24
|
!defined?(@hint) || @hint
|
13
25
|
end
|
14
26
|
|
27
|
+
# Switched hints on or off
|
15
28
|
def hint=( bool )
|
16
29
|
@hint = !!bool
|
17
30
|
end
|
data/lib/fpm/fry/chroot.rb
CHANGED
@@ -14,7 +14,7 @@ module FPM ; module Fry
|
|
14
14
|
|
15
15
|
# Returns all directory entries like Dir.entries.
|
16
16
|
# @param [String] path
|
17
|
-
# @
|
17
|
+
# @return [Array<String>] entries
|
18
18
|
def entries(path)
|
19
19
|
dir = rebase(path)
|
20
20
|
return Dir.entries(dir)
|
@@ -34,7 +34,7 @@ module FPM ; module Fry
|
|
34
34
|
|
35
35
|
# Yields all entries recursively like Find.find.
|
36
36
|
# @param [String] path
|
37
|
-
# @
|
37
|
+
# @yield entry
|
38
38
|
# @yieldparam [String] entry
|
39
39
|
def find(path, &block)
|
40
40
|
if stat(path).directory?
|
data/lib/fpm/fry/client.rb
CHANGED
@@ -1,15 +1,27 @@
|
|
1
|
+
require 'cabin'
|
1
2
|
require 'excon'
|
2
3
|
require 'rubygems/package'
|
3
4
|
require 'json'
|
4
5
|
require 'fileutils'
|
5
6
|
require 'forwardable'
|
6
7
|
require 'fpm/fry/tar'
|
7
|
-
|
8
|
-
module FPM; module Fry; end ; end
|
9
|
-
|
8
|
+
require 'fpm/fry/with_data'
|
10
9
|
class FPM::Fry::Client
|
11
10
|
|
11
|
+
# Raised when a file wasn't found inside a container
|
12
12
|
class FileNotFound < StandardError
|
13
|
+
include FPM::Fry::WithData
|
14
|
+
end
|
15
|
+
|
16
|
+
# Raised when a container wasn't found.
|
17
|
+
class ContainerNotFound < StandardError
|
18
|
+
include FPM::Fry::WithData
|
19
|
+
end
|
20
|
+
|
21
|
+
# Raised when trying to read file that can't be read e.g. because it's a
|
22
|
+
# directory.
|
23
|
+
class NotAFile < StandardError
|
24
|
+
include FPM::Fry::WithData
|
13
25
|
end
|
14
26
|
|
15
27
|
extend Forwardable
|
@@ -41,6 +53,7 @@ class FPM::Fry::Client
|
|
41
53
|
end
|
42
54
|
end
|
43
55
|
|
56
|
+
# @return [String] docker server api version
|
44
57
|
def server_version
|
45
58
|
@server_version ||= begin
|
46
59
|
res = agent.get(
|
@@ -51,6 +64,7 @@ class FPM::Fry::Client
|
|
51
64
|
end
|
52
65
|
end
|
53
66
|
|
67
|
+
# @return [String] docker cert path from environment
|
54
68
|
def self.docker_cert_path
|
55
69
|
ENV.fetch('DOCKER_CERT_PATH',File.join(Dir.home, '.docker'))
|
56
70
|
end
|
@@ -72,12 +86,17 @@ class FPM::Fry::Client
|
|
72
86
|
return to_enum(:read, name, resource) unless block_given?
|
73
87
|
res = agent.get(
|
74
88
|
path: url('containers',name,'archive'),
|
75
|
-
query:
|
89
|
+
query: {'path' => resource},
|
76
90
|
headers: { 'Content-Type' => 'application/json' },
|
77
91
|
expects: [200,404,500]
|
78
92
|
)
|
79
|
-
if res.status
|
80
|
-
|
93
|
+
if [404,500].include? res.status
|
94
|
+
body_message = Hash[JSON.load(res.body).map{|k,v| ["docker.#{k}",v] }] rescue {'docker.message' => res.body}
|
95
|
+
body_message['docker.container'] = name
|
96
|
+
if body_message['docker.message'] =~ /\ANo such container:/
|
97
|
+
raise ContainerNotFound.new("container not found", body_message)
|
98
|
+
end
|
99
|
+
raise FileNotFound.new("file not found", {'path' => resource}.merge(body_message))
|
81
100
|
end
|
82
101
|
sio = StringIO.new(res.body)
|
83
102
|
tar = ::Gem::Package::TarReader.new( sio )
|
@@ -86,6 +105,41 @@ class FPM::Fry::Client
|
|
86
105
|
end
|
87
106
|
end
|
88
107
|
|
108
|
+
# Gets the file contents while following symlinks
|
109
|
+
# @param [String] name the container name
|
110
|
+
# @param [String] resource the file name
|
111
|
+
# @return [String] content
|
112
|
+
# @raise [NotAFile] when the file has no readable content
|
113
|
+
# @raise [FileNotFound] when the file does not exist
|
114
|
+
# @api docker
|
115
|
+
def read_content(name, resource)
|
116
|
+
read(name, resource) do |file|
|
117
|
+
if file.header.typeflag == "2"
|
118
|
+
return read_content(name, File.absolute_path(file.header.linkname,File.dirname(resource)))
|
119
|
+
end
|
120
|
+
if file.header.typeflag != "0"
|
121
|
+
raise NotAFile.new("not a file", {'path' => resource})
|
122
|
+
end
|
123
|
+
return file.read
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Gets the target of a symlink
|
128
|
+
# @param [String] name the container name
|
129
|
+
# @param [String] resource the file name
|
130
|
+
# @return [String] target
|
131
|
+
# @return [nil] if resource is not a symlink
|
132
|
+
# @api docker
|
133
|
+
def link_target(name, resource)
|
134
|
+
read(name, resource) do |file|
|
135
|
+
if file.header.typeflag == "2"
|
136
|
+
return File.absolute_path(file.header.linkname,File.dirname(resource))
|
137
|
+
end
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
|
89
143
|
def copy(name, resource, map, options = {})
|
90
144
|
ex = FPM::Fry::Tar::Extractor.new(logger: @logger)
|
91
145
|
base = File.dirname(resource)
|
@@ -105,6 +159,27 @@ class FPM::Fry::Client
|
|
105
159
|
return JSON.parse(res.body)
|
106
160
|
end
|
107
161
|
|
162
|
+
def pull(image)
|
163
|
+
agent.post(path: url('images','create'), query: {'fromImage' => image})
|
164
|
+
end
|
165
|
+
|
166
|
+
def create(image)
|
167
|
+
res = agent.post(
|
168
|
+
headers: { 'Content-Type' => 'application/json' },
|
169
|
+
path: url('containers','create'),
|
170
|
+
expects: [201],
|
171
|
+
body: JSON.generate('Image' => image)
|
172
|
+
)
|
173
|
+
return JSON.parse(res.body)['Id']
|
174
|
+
end
|
175
|
+
|
176
|
+
def destroy(container)
|
177
|
+
agent.delete(
|
178
|
+
path: url('containers',container),
|
179
|
+
expects: [204]
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
108
183
|
def agent
|
109
184
|
@agent ||= agent_for(docker_url, tls)
|
110
185
|
end
|
data/lib/fpm/fry/command.rb
CHANGED
@@ -23,6 +23,7 @@ module FPM; module Fry
|
|
23
23
|
def initialize(invocation_path, ctx = {}, parent_attribute_values = {})
|
24
24
|
super
|
25
25
|
@ui = ctx.fetch(:ui){ UI.new }
|
26
|
+
@client = ctx[:client]
|
26
27
|
end
|
27
28
|
|
28
29
|
def parse(attrs)
|
@@ -45,48 +46,27 @@ module FPM; module Fry
|
|
45
46
|
|
46
47
|
attr_writer :client
|
47
48
|
|
48
|
-
subcommand 'detect', 'Detects distribution from an image
|
49
|
+
subcommand 'detect', 'Detects distribution from an image' do
|
49
50
|
|
50
|
-
|
51
|
-
option '--container', 'container', 'Docker container to detect'
|
52
|
-
option '--distribution', 'distribution', 'Distribution name to detect'
|
51
|
+
parameter 'image', 'Docker image to detect'
|
53
52
|
|
54
53
|
attr :ui
|
55
54
|
extend Forwardable
|
56
55
|
def_delegators :ui, :logger
|
57
56
|
|
58
57
|
def execute
|
59
|
-
require 'fpm/fry/
|
58
|
+
require 'fpm/fry/inspector'
|
60
59
|
require 'fpm/fry/detector'
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
elsif container
|
67
|
-
d = Detector::Container.new(client, container)
|
68
|
-
else
|
69
|
-
logger.error("Please supply either --image, --distribution or --container")
|
70
|
-
return 1
|
71
|
-
end
|
72
|
-
|
73
|
-
begin
|
74
|
-
if d.detect!
|
75
|
-
data = {distribution: d.distribution, version: d.version}
|
76
|
-
if i = OsDb[d.distribution]
|
77
|
-
data[:flavour] = i[:flavour]
|
78
|
-
else
|
79
|
-
data[:flavour] = "unknown"
|
80
|
-
end
|
81
|
-
logger.info("Detected distribution",data)
|
61
|
+
Inspector.for_image(client, image) do | inspector |
|
62
|
+
begin
|
63
|
+
data = Detector.detect(inspector)
|
64
|
+
logger.info("Detected the following parameters",data)
|
82
65
|
return 0
|
83
|
-
|
84
|
-
logger.error(
|
85
|
-
return
|
66
|
+
rescue => e
|
67
|
+
logger.error(e)
|
68
|
+
return 1
|
86
69
|
end
|
87
|
-
rescue => e
|
88
|
-
logger.error(e)
|
89
|
-
return 3
|
90
70
|
end
|
91
71
|
end
|
92
72
|
|
data/lib/fpm/fry/command/cook.rb
CHANGED
@@ -2,7 +2,6 @@ require 'fpm/fry/command'
|
|
2
2
|
module FPM; module Fry
|
3
3
|
class Command::Cook < Command
|
4
4
|
|
5
|
-
option '--distribution', 'distribution', 'Distribution like ubuntu-12.04'
|
6
5
|
option '--keep', :flag, 'Keep the container after build'
|
7
6
|
option '--overwrite', :flag, 'Overwrite package', default: true
|
8
7
|
|
@@ -22,40 +21,19 @@ module FPM; module Fry
|
|
22
21
|
@tls = nil
|
23
22
|
require 'digest'
|
24
23
|
require 'fileutils'
|
24
|
+
require 'fpm/fry/with_data'
|
25
25
|
require 'fpm/fry/recipe'
|
26
26
|
require 'fpm/fry/recipe/builder'
|
27
27
|
require 'fpm/fry/detector'
|
28
28
|
require 'fpm/fry/docker_file'
|
29
29
|
require 'fpm/fry/stream_parser'
|
30
|
-
require 'fpm/fry/os_db'
|
31
30
|
require 'fpm/fry/block_enumerator'
|
32
31
|
require 'fpm/fry/build_output_parser'
|
32
|
+
require 'fpm/fry/inspector'
|
33
|
+
require 'fpm/fry/plugin/config'
|
33
34
|
super
|
34
35
|
end
|
35
36
|
|
36
|
-
def detector
|
37
|
-
@detector || begin
|
38
|
-
if distribution
|
39
|
-
d = Detector::String.new(distribution)
|
40
|
-
else
|
41
|
-
d = Detector::Image.new(client, image)
|
42
|
-
end
|
43
|
-
self.detector=d
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def detector=(d)
|
48
|
-
unless d.detect!
|
49
|
-
raise "Unable to detect distribution from given image"
|
50
|
-
end
|
51
|
-
@detector = d
|
52
|
-
end
|
53
|
-
|
54
|
-
def flavour
|
55
|
-
@flavour ||= OsDb.fetch(detector.distribution,{flavour: "unknown"})[:flavour]
|
56
|
-
end
|
57
|
-
attr_writer :flavour
|
58
|
-
|
59
37
|
def output_class
|
60
38
|
@output_class ||= begin
|
61
39
|
logger.debug("Autodetecting package type",flavour: flavour)
|
@@ -75,19 +53,22 @@ module FPM; module Fry
|
|
75
53
|
|
76
54
|
def builder
|
77
55
|
@builder ||= begin
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
b.load_file( recipe )
|
56
|
+
b = nil
|
57
|
+
Inspector.for_image(client, image) do |inspector|
|
58
|
+
variables = Detector.detect(inspector)
|
59
|
+
logger.debug("Loading recipe",variables: variables, recipe: recipe)
|
60
|
+
b = Recipe::Builder.new(variables, logger: ui.logger, inspector: inspector)
|
61
|
+
b.load_file( recipe )
|
62
|
+
end
|
86
63
|
b
|
87
64
|
end
|
88
65
|
end
|
89
66
|
attr_writer :builder
|
90
67
|
|
68
|
+
def flavour
|
69
|
+
builder.variables[:flavour]
|
70
|
+
end
|
71
|
+
|
91
72
|
def cache
|
92
73
|
@cache ||= builder.recipe.source.build_cache(tmpdir)
|
93
74
|
end
|
@@ -168,22 +149,12 @@ module FPM; module Fry
|
|
168
149
|
if flavour == 'debian'
|
169
150
|
case(update)
|
170
151
|
when 'auto'
|
171
|
-
|
172
|
-
|
173
|
-
headers: {'Content-Type' => 'application/json'},
|
174
|
-
body: body,
|
175
|
-
expects: [201]
|
176
|
-
)
|
177
|
-
body = JSON.parse(res.body)
|
178
|
-
container = body.fetch('Id')
|
179
|
-
begin
|
180
|
-
client.read( container, '/var/lib/apt/lists') do |file|
|
152
|
+
Inspector.for_image(client, image) do |inspector|
|
153
|
+
inspector.read('/var/lib/apt/lists') do |file|
|
181
154
|
next if file.header.name == 'lists/'
|
182
155
|
logger.hint("/var/lib/apt/lists is not empty, you could try to speed up builds with --update=never", documentation: 'https://github.com/xing/fpm-fry/wiki/The-update-parameter')
|
183
|
-
|
156
|
+
break
|
184
157
|
end
|
185
|
-
ensure
|
186
|
-
client.delete(path: client.url('containers',container))
|
187
158
|
end
|
188
159
|
return true
|
189
160
|
when 'always'
|
@@ -242,7 +213,7 @@ module FPM; module Fry
|
|
242
213
|
return yield container
|
243
214
|
ensure
|
244
215
|
unless keep?
|
245
|
-
client.
|
216
|
+
client.destroy(container)
|
246
217
|
end
|
247
218
|
end
|
248
219
|
end
|
@@ -359,11 +330,8 @@ module FPM; module Fry
|
|
359
330
|
def execute
|
360
331
|
# force some eager loading
|
361
332
|
lint_recipe_file!
|
362
|
-
detector
|
363
|
-
flavour
|
364
|
-
output_class
|
365
|
-
lint_output_class!
|
366
333
|
builder
|
334
|
+
lint_output_class!
|
367
335
|
lint_recipe!
|
368
336
|
cache
|
369
337
|
|
data/lib/fpm/fry/detector.rb
CHANGED
@@ -1,117 +1,62 @@
|
|
1
|
-
require 'fpm/fry/
|
1
|
+
require 'fpm/fry/detector'
|
2
2
|
module FPM; module Fry
|
3
3
|
|
4
4
|
module Detector
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
# Detects a set of basic properties about an image.
|
6
|
+
#
|
7
|
+
# @param [Inspector] inspector
|
8
|
+
# @return [Hash<Symbol, String>]
|
9
|
+
def self.detect(inspector)
|
10
|
+
found = {}
|
11
|
+
if inspector.exists? '/usr/bin/apt-get'
|
12
|
+
found[:flavour] = 'debian'
|
13
|
+
elsif inspector.exists? '/bin/rpm'
|
14
|
+
found[:flavour] = 'redhat'
|
13
15
|
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
client.read(container,'/etc/lsb-release') do |file|
|
24
|
-
file.read.each_line do |line|
|
25
|
-
case(line)
|
26
|
-
when /\ADISTRIB_ID=/ then
|
27
|
-
@distribution = $'.strip.downcase
|
28
|
-
when /\ADISTRIB_RELEASE=/ then
|
29
|
-
@version = $'.strip
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
return !!(@distribution and @version)
|
34
|
-
rescue Client::FileNotFound
|
35
|
-
end
|
36
|
-
begin
|
37
|
-
client.read(container,'/etc/debian_version') do |file|
|
38
|
-
content = file.read
|
39
|
-
if /\A\d+(?:\.\d+)+\Z/ =~ content
|
40
|
-
@distribution = 'debian'
|
41
|
-
@version = content.strip
|
42
|
-
end
|
43
|
-
end
|
44
|
-
return !!(@distribution and @version)
|
45
|
-
rescue Client::FileNotFound
|
46
|
-
end
|
47
|
-
begin
|
48
|
-
client.read(container,'/etc/redhat-release') do |file|
|
49
|
-
if file.header.typeflag == "2" # centos links this file
|
50
|
-
client.read(container,File.absolute_path(file.header.linkname,'/etc')) do |file|
|
51
|
-
detect_redhat_release(file)
|
52
|
-
end
|
53
|
-
else
|
54
|
-
detect_redhat_release(file)
|
55
|
-
end
|
16
|
+
begin
|
17
|
+
inspector.read_content('/etc/lsb-release').each_line do |line|
|
18
|
+
case(line)
|
19
|
+
when /\ADISTRIB_ID=/ then
|
20
|
+
found[:distribution] = $'.strip.downcase
|
21
|
+
when /\ADISTRIB_RELEASE=/ then
|
22
|
+
found[:release] = $'.strip
|
23
|
+
when /\ADISTRIB_CODENAME=/ then
|
24
|
+
found[:codename] = $'.strip
|
56
25
|
end
|
57
|
-
return !!(@distribution and @version)
|
58
|
-
rescue Client::FileNotFound
|
59
26
|
end
|
60
|
-
|
27
|
+
rescue Client::FileNotFound
|
61
28
|
end
|
62
29
|
|
63
|
-
|
64
|
-
|
65
|
-
file.read.each_line do |line|
|
30
|
+
begin
|
31
|
+
inspector.read_content('/etc/os-release').each_line do |line|
|
66
32
|
case(line)
|
67
|
-
when /\
|
68
|
-
|
69
|
-
|
33
|
+
when /\AVERSION=\"(\w+) \((\w+)\)\"/ then
|
34
|
+
found[:release] ||= $1
|
35
|
+
found[:codename] ||= $2
|
70
36
|
end
|
71
37
|
end
|
38
|
+
rescue Client::FileNotFound
|
72
39
|
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
attr :distribution
|
81
|
-
attr :version
|
82
|
-
|
83
|
-
def initialize(client, image, factory = Container)
|
84
|
-
super
|
85
|
-
end
|
86
|
-
|
87
|
-
def detect!
|
88
|
-
body = JSON.generate({"Image" => image, "Cmd" => "exit 0"})
|
89
|
-
begin
|
90
|
-
res = client.post( path: client.url('containers','create'),
|
91
|
-
headers: {'Content-Type' => 'application/json'},
|
92
|
-
body: body,
|
93
|
-
expects: [201]
|
94
|
-
)
|
95
|
-
rescue Excon::Errors::NotFound
|
96
|
-
raise ImageNotFound, "Image #{image.inspect} not found. Did you do a `docker pull #{image}` before?"
|
40
|
+
begin
|
41
|
+
content = inspector.read_content('/etc/debian_version')
|
42
|
+
if /\A\d+(?:\.\d+)+\Z/ =~ content
|
43
|
+
found[:distribution] ||= 'debian'
|
44
|
+
found[:release] = content.strip
|
97
45
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
return false
|
46
|
+
rescue Client::FileNotFound
|
47
|
+
end
|
48
|
+
begin
|
49
|
+
content = inspector.read_content('/etc/redhat-release')
|
50
|
+
content.each_line do |line|
|
51
|
+
case(line)
|
52
|
+
when /\A(\w+)(?: Linux)? release ([\d\.]+)/ then
|
53
|
+
found[:distribution] ||= $1.strip.downcase
|
54
|
+
found[:release] = $2.strip
|
108
55
|
end
|
109
|
-
ensure
|
110
|
-
client.delete(path: client.url('containers',container))
|
111
56
|
end
|
57
|
+
rescue Client::FileNotFound
|
112
58
|
end
|
59
|
+
return found
|
113
60
|
end
|
114
|
-
|
115
|
-
|
116
61
|
end
|
117
62
|
end ; end
|