fpm-fry 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|