fpm-fry 0.7.2.1 → 0.8.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/fpm/fry/client.rb +26 -12
- data/lib/fpm/fry/command/cook.rb +77 -71
- data/lib/fpm/fry/command.rb +1 -1
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c84a20f83300f3f9793e0680dc5573be7e579303df7420ef9872855824ffcc8
|
4
|
+
data.tar.gz: 3dd82f0cc8368c27ed708fee9ac233901004bd8fca5b14fac0d5d911c2a8499a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1954a12b44d375a0f07b664eb5eaf705ef772b4e67ec8fd4723675e0bbfc888006a2997cb4d3826cd1cd5fc71dc08051aa38e4b8fca1ae0e8f6b7dd50e8b8b2a
|
7
|
+
data.tar.gz: 23f211f530e0ddd1eda1fffc77bfddbec8d397c9746096b22cb95875c8a60daf6e829d8d9533728eabe65aa4e49de6a74af2ec521ed8e51ced483cf58b464e76
|
data/lib/fpm/fry/client.rb
CHANGED
@@ -22,6 +22,10 @@ class FPM::Fry::Client
|
|
22
22
|
include FPM::Fry::WithData
|
23
23
|
end
|
24
24
|
|
25
|
+
class ContainerDeletionFailed < StandardError
|
26
|
+
include FPM::Fry::WithData
|
27
|
+
end
|
28
|
+
|
25
29
|
# Raised when trying to read file that can't be read e.g. because it's a
|
26
30
|
# directory.
|
27
31
|
class NotAFile < StandardError
|
@@ -111,7 +115,7 @@ class FPM::Fry::Client
|
|
111
115
|
)
|
112
116
|
end
|
113
117
|
rescue Excon::Error => e
|
114
|
-
|
118
|
+
logger.error("unexpected response when reading resource: url: #{url}, error: #{e}")
|
115
119
|
raise
|
116
120
|
end
|
117
121
|
if [404,500].include? res.status
|
@@ -165,14 +169,14 @@ class FPM::Fry::Client
|
|
165
169
|
end
|
166
170
|
|
167
171
|
def copy(name, resource, map, options = {})
|
168
|
-
ex = FPM::Fry::Tar::Extractor.new(logger:
|
172
|
+
ex = FPM::Fry::Tar::Extractor.new(logger: logger)
|
169
173
|
base = File.dirname(resource)
|
170
174
|
read(name, resource) do | entry |
|
171
175
|
file = File.join(base, entry.full_name).chomp('/')
|
172
176
|
file = file.sub(%r"\A\./",'')
|
173
177
|
to = map[file]
|
174
178
|
next unless to
|
175
|
-
|
179
|
+
logger.debug("Copy",name: file, to: to)
|
176
180
|
ex.extract_entry(to, entry, options)
|
177
181
|
end
|
178
182
|
end
|
@@ -182,11 +186,11 @@ class FPM::Fry::Client
|
|
182
186
|
res = agent.get(path: url, expects: [200, 204])
|
183
187
|
return JSON.parse(res.body)
|
184
188
|
rescue Excon::Error => e
|
185
|
-
|
189
|
+
logger.error("could not retrieve changes for: #{name}, url: #{url}, error: #{e}")
|
186
190
|
raise
|
187
191
|
end
|
188
192
|
|
189
|
-
def pull(image)
|
193
|
+
def pull(image, platform: nil)
|
190
194
|
last_status = ""
|
191
195
|
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
192
196
|
chunk.each_line do |line|
|
@@ -204,7 +208,9 @@ class FPM::Fry::Client
|
|
204
208
|
end
|
205
209
|
end
|
206
210
|
end
|
207
|
-
|
211
|
+
query = {'fromImage' => image}
|
212
|
+
query['platform'] = platform if platform
|
213
|
+
agent.post(path: url('images','create'), query: query, :response_block => streamer)
|
208
214
|
end
|
209
215
|
|
210
216
|
def delete(image)
|
@@ -220,27 +226,35 @@ class FPM::Fry::Client
|
|
220
226
|
)
|
221
227
|
data = JSON.parse(res.body)
|
222
228
|
if res.status != 201
|
223
|
-
|
229
|
+
logger.error(data["message"])
|
224
230
|
if res.status == 404
|
225
|
-
|
231
|
+
logger.info("execute docker pull #{image} first or specify --pull argument for fpm-fry")
|
226
232
|
end
|
227
233
|
raise ContainerCreationFailed.new("could not create container from #{image}", message: data["message"])
|
228
234
|
end
|
229
235
|
data['Id']
|
230
236
|
rescue Excon::Error => e
|
231
|
-
|
237
|
+
logger.error("could not create container from #{image}, url: #{url}, error: #{e}")
|
232
238
|
raise
|
233
239
|
end
|
234
240
|
|
235
241
|
def destroy(container)
|
236
242
|
return unless container
|
243
|
+
|
237
244
|
url = self.url('containers', container)
|
238
|
-
agent.delete(
|
245
|
+
res = agent.delete(
|
239
246
|
path: url,
|
240
|
-
expects: [204]
|
247
|
+
expects: [204, 409]
|
241
248
|
)
|
249
|
+
return unless res.status == 409
|
250
|
+
data = JSON.parse(res.body) rescue ({"message" => "could not parse response body: '#{res.body}'"})
|
251
|
+
if data["message"] =~ /removal of container .* is already in progress/
|
252
|
+
logger.info(data["message"])
|
253
|
+
else
|
254
|
+
raise ContainerDeletionFailed.new("could not destroy container #{container}", data)
|
255
|
+
end
|
242
256
|
rescue Excon::Error => e
|
243
|
-
|
257
|
+
logger.error("could not destroy container: #{container}, url: #{url}, error: #{e}")
|
244
258
|
raise
|
245
259
|
end
|
246
260
|
|
data/lib/fpm/fry/command/cook.rb
CHANGED
@@ -2,6 +2,10 @@ require 'fpm/fry/command'
|
|
2
2
|
module FPM; module Fry
|
3
3
|
class Command::Cook < Command
|
4
4
|
|
5
|
+
class BuildFailed < StandardError
|
6
|
+
include FPM::Fry::WithData
|
7
|
+
end
|
8
|
+
|
5
9
|
option '--keep', :flag, 'Keep the container after build'
|
6
10
|
option '--overwrite', :flag, 'Overwrite package', default: true
|
7
11
|
option '--verbose', :flag, 'Verbose output', default: false
|
@@ -20,7 +24,7 @@ module FPM; module Fry
|
|
20
24
|
parameter 'image', 'Docker image to build from'
|
21
25
|
parameter '[recipe]', 'Recipe file to cook', default: 'recipe.rb'
|
22
26
|
|
23
|
-
def initialize(invocation_path, ctx = {}
|
27
|
+
def initialize(invocation_path, ctx = {})
|
24
28
|
@tls = nil
|
25
29
|
require 'digest'
|
26
30
|
require 'fileutils'
|
@@ -205,86 +209,88 @@ module FPM; module Fry
|
|
205
209
|
end
|
206
210
|
|
207
211
|
def pull_base_image!
|
208
|
-
client.pull(image)
|
212
|
+
client.pull(image, platform: platform)
|
209
213
|
rescue Excon::Error
|
210
214
|
logger.error "could not pull base image #{image}"
|
211
215
|
raise
|
212
216
|
end
|
213
217
|
|
214
218
|
def build!
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
args[:query] = { platform: platform } if platform
|
226
|
-
res = client.post(args)
|
227
|
-
JSON.parse(res.body)
|
228
|
-
rescue Excon::Error
|
229
|
-
logger.error "could not create #{build_image}, url: #{url}"
|
230
|
-
raise
|
231
|
-
end
|
232
|
-
container = body['Id']
|
233
|
-
begin
|
234
|
-
begin
|
235
|
-
url = client.url('containers',container,'start')
|
236
|
-
client.post(
|
237
|
-
headers: {
|
238
|
-
'Content-Type' => 'application/json'
|
239
|
-
},
|
240
|
-
path: url,
|
241
|
-
expects: [204],
|
242
|
-
body: JSON.generate({})
|
243
|
-
)
|
244
|
-
rescue Excon::Error
|
245
|
-
logger.error "could not start container #{container}, url: #{url}"
|
246
|
-
raise
|
247
|
-
end
|
219
|
+
container = create_build_container
|
220
|
+
start_build_container(container)
|
221
|
+
attach_to_build_container_and_stream_logs(container)
|
222
|
+
wait_for_build_container_to_shut_down(container)
|
223
|
+
yield container
|
224
|
+
ensure
|
225
|
+
unless keep?
|
226
|
+
client.destroy(container) if container
|
227
|
+
end
|
228
|
+
end
|
248
229
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
230
|
+
def create_build_container
|
231
|
+
url = client.url('containers','create')
|
232
|
+
args = {
|
233
|
+
headers: {
|
234
|
+
'Content-Type' => 'application/json'
|
235
|
+
},
|
236
|
+
path: url,
|
237
|
+
expects: [201],
|
238
|
+
body: JSON.generate({"Image" => build_image})
|
239
|
+
}
|
240
|
+
args[:query] = { platform: platform } if platform
|
241
|
+
res = client.post(args)
|
242
|
+
JSON.parse(res.body)['Id']
|
243
|
+
rescue Excon::Error
|
244
|
+
logger.error "could not create #{build_image}, url: #{url}"
|
245
|
+
raise
|
246
|
+
end
|
266
247
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
248
|
+
def start_build_container(container)
|
249
|
+
url = client.url('containers',container,'start')
|
250
|
+
client.post(
|
251
|
+
headers: {
|
252
|
+
'Content-Type' => 'application/json'
|
253
|
+
},
|
254
|
+
path: url,
|
255
|
+
expects: [204],
|
256
|
+
body: JSON.generate({})
|
257
|
+
)
|
258
|
+
rescue Excon::Error
|
259
|
+
logger.error "could not start container #{container}, url: #{url}"
|
260
|
+
raise
|
261
|
+
end
|
281
262
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
263
|
+
def attach_to_build_container_and_stream_logs(container)
|
264
|
+
url = client.url('containers',container,'attach?stderr=1&stdout=1&stream=1&logs=1')
|
265
|
+
client.post(
|
266
|
+
path: url,
|
267
|
+
body: '',
|
268
|
+
expects: [200],
|
269
|
+
middlewares: [
|
270
|
+
StreamParser.new(out,err),
|
271
|
+
Excon::Middleware::Expects,
|
272
|
+
Excon::Middleware::Instrumentor,
|
273
|
+
Excon::Middleware::Mock
|
274
|
+
]
|
275
|
+
)
|
276
|
+
rescue Excon::Error
|
277
|
+
logger.error "could not attach to container #{container}, url: #{url}"
|
278
|
+
raise
|
279
|
+
end
|
280
|
+
|
281
|
+
def wait_for_build_container_to_shut_down(container)
|
282
|
+
res = client.post(
|
283
|
+
path: client.url('containers',container,'wait'),
|
284
|
+
expects: [200],
|
285
|
+
body: ''
|
286
|
+
)
|
287
|
+
json = JSON.parse(res.body)
|
288
|
+
if json["StatusCode"] != 0
|
289
|
+
raise BuildFailed.new("Build script failed with non zero exit code", json)
|
287
290
|
end
|
291
|
+
rescue Excon::Error
|
292
|
+
logger.error "could not wait successfully for container #{container}, url: #{url}"
|
293
|
+
raise
|
288
294
|
end
|
289
295
|
|
290
296
|
def input_package(container)
|
data/lib/fpm/fry/command.rb
CHANGED
@@ -23,7 +23,7 @@ module FPM; module Fry
|
|
23
23
|
extend Forwardable
|
24
24
|
def_delegators :ui, :out, :err, :logger, :tmpdir
|
25
25
|
|
26
|
-
def initialize(invocation_path, ctx = {}
|
26
|
+
def initialize(invocation_path, ctx = {})
|
27
27
|
super
|
28
28
|
@ui = ctx.fetch(:ui){ UI.new(tmpdir: dir) }
|
29
29
|
@client = ctx[:client]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fpm-fry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maxime Lagresle
|
@@ -10,10 +10,11 @@ authors:
|
|
10
10
|
- Hannes Georg
|
11
11
|
- Julian Tabel
|
12
12
|
- Dennis Konert
|
13
|
+
- Bruno Escherl
|
13
14
|
autorequire:
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
|
-
date: 2024-
|
17
|
+
date: 2024-12-12 00:00:00.000000000 Z
|
17
18
|
dependencies:
|
18
19
|
- !ruby/object:Gem::Dependency
|
19
20
|
name: excon
|
@@ -35,14 +36,28 @@ dependencies:
|
|
35
36
|
requirements:
|
36
37
|
- - "~>"
|
37
38
|
- !ruby/object:Gem::Version
|
38
|
-
version: '1.
|
39
|
+
version: '1.16'
|
39
40
|
type: :runtime
|
40
41
|
prerelease: false
|
41
42
|
version_requirements: !ruby/object:Gem::Requirement
|
42
43
|
requirements:
|
43
44
|
- - "~>"
|
44
45
|
- !ruby/object:Gem::Version
|
45
|
-
version: '1.
|
46
|
+
version: '1.16'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: clamp
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.1.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.1.0
|
46
61
|
description: deep-fried package builder
|
47
62
|
email: dennis.konert@new-work.se
|
48
63
|
executables:
|
@@ -121,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
136
|
- !ruby/object:Gem::Version
|
122
137
|
version: '0'
|
123
138
|
requirements: []
|
124
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.5.22
|
125
140
|
signing_key:
|
126
141
|
specification_version: 4
|
127
142
|
summary: FPM Fry
|