fpm-fry 0.7.2.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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