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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4775633d070116e35a3bdfb7bdb0359d8af49b29b08f9b68e862b5dfd6a0a91d
4
- data.tar.gz: b6b317af4559f1deeca752e42a96c9973885e1014caa0fd5fac22d6653644617
3
+ metadata.gz: 5c84a20f83300f3f9793e0680dc5573be7e579303df7420ef9872855824ffcc8
4
+ data.tar.gz: 3dd82f0cc8368c27ed708fee9ac233901004bd8fca5b14fac0d5d911c2a8499a
5
5
  SHA512:
6
- metadata.gz: c05ab42fc6a12903c1987313a07cdb27b7fcbd46bf3b995f20745a7da7c358b1e00ffde004eeebdcf99a4ebe05069fb6f45e9c77b7d0a2de9c19874e9f70a86d
7
- data.tar.gz: af93127bbfc24a0bf3de4250523e86004ec49548b4517e2f55b2ddb3bb30639f669889e2ee8b83bd58a8b21d2ff314b290c60c380be3962ef69882b6752c69c0
6
+ metadata.gz: 1954a12b44d375a0f07b664eb5eaf705ef772b4e67ec8fd4723675e0bbfc888006a2997cb4d3826cd1cd5fc71dc08051aa38e4b8fca1ae0e8f6b7dd50e8b8b2a
7
+ data.tar.gz: 23f211f530e0ddd1eda1fffc77bfddbec8d397c9746096b22cb95875c8a60daf6e829d8d9533728eabe65aa4e49de6a74af2ec521ed8e51ced483cf58b464e76
@@ -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
- @logger.error("unexpected response when reading resource: url: #{url}, error: #{e}")
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: @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
- @logger.debug("Copy",name: file, to: to)
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
- @logger.error("could not retrieve changes for: #{name}, url: #{url}, error: #{e}")
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
- agent.post(path: url('images','create'), query: {'fromImage' => image}, :response_block => streamer)
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
- @logger.error(data["message"])
229
+ logger.error(data["message"])
224
230
  if res.status == 404
225
- @logger.info("execute docker pull #{image} first or specify --pull argument for fpm-fry")
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
- @logger.error("could not create container from #{image}, url: #{url}, error: #{e}")
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
- @logger.error("could not destroy container: #{container}, url: #{url}, error: #{e}")
257
+ logger.error("could not destroy container: #{container}, url: #{url}, error: #{e}")
244
258
  raise
245
259
  end
246
260
 
@@ -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 = {}, parent_attribute_values = {})
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
- body = begin
216
- url = client.url('containers','create')
217
- args = {
218
- headers: {
219
- 'Content-Type' => 'application/json'
220
- },
221
- path: url,
222
- expects: [201],
223
- body: JSON.generate({"Image" => build_image})
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
- begin
250
- url = client.url('containers',container,'attach?stderr=1&stdout=1&stream=1&logs=1')
251
- client.post(
252
- path: url,
253
- body: '',
254
- expects: [200],
255
- middlewares: [
256
- StreamParser.new(out,err),
257
- Excon::Middleware::Expects,
258
- Excon::Middleware::Instrumentor,
259
- Excon::Middleware::Mock
260
- ]
261
- )
262
- rescue Excon::Error
263
- logger.error "could not attach to container #{container}, url: #{url}"
264
- raise
265
- end
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
- begin
268
- res = client.post(
269
- path: client.url('containers',container,'wait'),
270
- expects: [200],
271
- body: ''
272
- )
273
- json = JSON.parse(res.body)
274
- if json["StatusCode"] != 0
275
- raise Fry::WithData("Build failed", exit_code: json["StatusCode"])
276
- end
277
- rescue Excon::Error
278
- logger.error "could not wait successfully for container #{container}, url: #{url}"
279
- raise
280
- end
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
- yield container
283
- ensure
284
- unless keep?
285
- client.destroy(container)
286
- end
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)
@@ -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 = {}, parent_attribute_values = {})
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.7.2.1
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-02-09 00:00:00.000000000 Z
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.13'
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.13'
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.4.19
139
+ rubygems_version: 3.5.22
125
140
  signing_key:
126
141
  specification_version: 4
127
142
  summary: FPM Fry