squared 0.4.15 → 0.4.17

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.
@@ -55,15 +55,15 @@ module Squared
55
55
  commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
56
56
  inspect: %w[s|size f|format=q].freeze,
57
57
  start: %w[a|attach i|interactive detach-keys=q].freeze,
58
- stop: %w[s|signal=b t|time=i].freeze,
59
- restart: %w[s|signal=b t|time=i].freeze,
58
+ stop: %w[s|signal=b t|time=i t|timeout=i].freeze,
59
+ restart: %w[s|signal=b t|time=i t|timeout=i].freeze,
60
60
  kill: %w[s|signal=b].freeze,
61
61
  stats: %w[no-trunc format|q].freeze
62
62
  }.freeze,
63
63
  image: {
64
64
  list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
65
65
  push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
66
- rm: %w[f|force no-prune].freeze,
66
+ rm: %w[f|force no-prune platform=b].freeze,
67
67
  save: %w[o|output=p platform=b].freeze
68
68
  }.freeze,
69
69
  network: {
@@ -73,8 +73,11 @@ module Squared
73
73
  }.freeze
74
74
  VAL_DOCKER = {
75
75
  run: {
76
- bind: %w[type source src destination dst target readonly ro bind-propagation].freeze,
77
- tmpfs: %w[type destination dst target tmpfs-size tmpfs-mode].freeze
76
+ common: %w[source src destination dst target readonly ro].freeze,
77
+ bind: %w[bind-propagation].freeze,
78
+ volume: %w[volume-subpath volume-nocopy volume-opt].freeze,
79
+ tmpfs: %w[tmpfs-size tmpfs-mode].freeze,
80
+ image: %w[image-path].freeze
78
81
  }.freeze
79
82
  }.freeze
80
83
  private_constant :COMPOSEFILE, :BAKEFILE, :OPT_DOCKER, :VAL_DOCKER
@@ -92,8 +95,9 @@ module Squared
92
95
  end
93
96
 
94
97
  subtasks({
95
- 'build' => %i[tag context bake].freeze,
98
+ 'build' => %i[tag context].freeze,
96
99
  'compose' => %i[build run exec up].freeze,
100
+ 'bake' => %i[build check].freeze,
97
101
  'image' => %i[list rm push tag save].freeze,
98
102
  'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
99
103
  rm].freeze,
@@ -124,11 +128,11 @@ module Squared
124
128
 
125
129
  def populate(*, **)
126
130
  super
127
- return unless ref?(Docker.ref)
131
+ return unless ref?(Docker.ref) || @only
128
132
 
129
133
  namespace name do
130
134
  Docker.subtasks do |action, flags|
131
- next if @pass.include?(action)
135
+ next if task_pass?(action)
132
136
 
133
137
  namespace action do
134
138
  flags.each do |flag|
@@ -141,18 +145,31 @@ module Squared
141
145
  param = param_guard(action, flag, args: args, key: flag)
142
146
  buildx(:build, args.extras, "#{flag}": param)
143
147
  end
144
- when :bake
148
+ end
149
+ when 'bake'
150
+ next unless bake?
151
+
152
+ case flag
153
+ when :build
145
154
  format_desc action, flag, ':?,opts*,target*,context?'
146
155
  task flag do |_, args|
147
156
  args = args.to_a
148
157
  if args.first == ':'
149
158
  choice_command :bake
150
159
  else
151
- buildx flag, args
160
+ buildx :bake, args
152
161
  end
153
162
  end
163
+ when :check
164
+ format_desc action, flag, 'target'
165
+ task flag, [:target] do |_, args|
166
+ target = param_guard(action, flag, args: args, key: :target)
167
+ buildx :bake, ['allow=fs.read=*', 'call=check', target]
168
+ end
154
169
  end
155
170
  when 'compose'
171
+ next unless compose?
172
+
156
173
  case flag
157
174
  when :build, :up
158
175
  format_desc action, flag, 'opts*,service*'
@@ -307,7 +324,7 @@ module Squared
307
324
  op.parse(OPT_DOCKER[:buildx][flag == :bake ? :bake : :build] + OPT_DOCKER[:buildx][:shared])
308
325
  case flag
309
326
  when :build, :context
310
- append_tag(tag || option('tag', ignore: false) || @tag)
327
+ append_tag(tag || option('tag', ignore: false) || self.tag)
311
328
  append_context context
312
329
  when :bake
313
330
  unless op.empty?
@@ -317,7 +334,7 @@ module Squared
317
334
  if projectpath?(val = args.pop)
318
335
  context = val
319
336
  else
320
- op.extras << val
337
+ op.push(val)
321
338
  end
322
339
  end
323
340
  op.append(args, escape: true)
@@ -339,7 +356,7 @@ module Squared
339
356
  when :build, :up
340
357
  op.append(escape: true)
341
358
  when :exec, :run
342
- append_command(flag, service, op.extras, from: from)
359
+ append_command flag, service, op.extras
343
360
  end
344
361
  run(from: from)
345
362
  end
@@ -356,44 +373,54 @@ module Squared
356
373
  when :run, :create, :exec
357
374
  if rc && !op.arg?('mount')
358
375
  run = VAL_DOCKER[:run]
359
- both = run[:bind] + run[:tmpfs]
360
- diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
361
- delim = Regexp.new(",\\s*(?=#{both.join('|')})")
376
+ all = collect_hash VAL_DOCKER[:run]
377
+ delim = Regexp.new(",\\s*(?=#{all.join('|')})")
362
378
  Array(@mounts).each do |val|
363
379
  args = []
364
- tmpfs = true
380
+ type = nil
365
381
  val.split(delim).each do |opt|
366
- k, v, q = split_option(opt)
367
- next unless both.include?(k)
368
-
382
+ k, v, q = split_option opt
369
383
  if k == 'type'
370
- tmpfs = false if v == 'bind'
371
- next
372
- elsif diff.include?(k)
373
- tmpfs = false
374
- end
375
- case k
376
- when 'readonly', 'ro'
377
- args << k
378
- next
379
- when 'source', 'src', 'destination', 'dst', 'target'
380
- v = path + v
381
- v = shell_quote(v, option: false, force: false) if q == ''
382
- tmpfs = false if k[0] == 's'
384
+ case v
385
+ when 'bind', 'volume', 'image', 'tmpfs'
386
+ type = v
387
+ else
388
+ raise_error("unknown type: #{v}", hint: flag)
389
+ end
390
+ elsif all.include?(k)
391
+ unless type
392
+ run.each_pair do |key, val|
393
+ if val.include?(k)
394
+ type = key.to_s unless key == :common
395
+ break
396
+ end
397
+ end
398
+ end
399
+ case k
400
+ when 'readonly', 'ro'
401
+ args << k
402
+ next
403
+ when 'source', 'src', 'destination', 'dst', 'target', 'volume-subpath', 'image-path'
404
+ v = path + v
405
+ v = shell_quote(v, option: false, force: false) if q == ''
406
+ end
407
+ args << "#{k}=#{q + v + q}"
408
+ elsif verbose
409
+ log_message(Logger::INFO, 'unrecognized option', subject: from, hint: k)
383
410
  end
384
- args << "#{k}=#{q + v + q}"
385
411
  end
386
- cmd << "--mount type=#{tmpfs ? 'tmpfs' : 'bind'},#{args.join(',')}"
412
+ raise_error('missing type', hint: flag) unless type
413
+ cmd << "--mount type=#{type},#{args.join(',')}"
387
414
  end
388
415
  end
389
- append_command(flag, id || tagmain, op.extras, from: from)
416
+ append_command(flag, id || tagmain, op.extras)
390
417
  when :update
391
- raise_error('missing container', hint: from) if op.empty?
418
+ raise_error('missing container', hint: flag) if op.empty?
392
419
  op.append(escape: true)
393
420
  when :commit
394
421
  latest = op.shift || tagmain
395
422
  cmd << id << latest
396
- raise_error("unknown args: #{op.join(', ')}", hint: from) unless op.empty?
423
+ raise_error("unknown args: #{op.join(', ')}", hint: flag) unless op.empty?
397
424
  return unless confirm_command(cmd.to_s, title: from, target: id, as: latest)
398
425
 
399
426
  registry = option('registry') || @registry
@@ -436,7 +463,7 @@ module Squared
436
463
  when :rm
437
464
  status = %w[created exited dead]
438
465
  end
439
- ps = docker_output('ps -a', *status.map { |s| "--filter=\"status=#{s}\"" })
466
+ ps = docker_output('ps -a', *status.map { |s| quote_option('filter', "status=#{s}") })
440
467
  list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
441
468
  run(cmd.temp(img), from: from)
442
469
  end
@@ -500,8 +527,8 @@ module Squared
500
527
  when :push
501
528
  id ||= option('tag', ignore: false) || tagmain
502
529
  registry ||= op.shift || option('registry') || @registry
503
- raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint: from) unless id && op.empty?
504
- raise_error('username/registry not provided', hint: from) unless registry
530
+ raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint: flag) unless id && op.empty?
531
+ raise_error('username/registry not provided', hint: flag) unless registry
505
532
  registry.chomp!('/')
506
533
  uri = shell_quote("#{registry}/#{id}")
507
534
  op << uri
@@ -535,6 +562,14 @@ module Squared
535
562
  super || dockerfile.exist?
536
563
  end
537
564
 
565
+ def compose?(file = dockerfile)
566
+ COMPOSEFILE.include?(File.basename(file))
567
+ end
568
+
569
+ def bake?(file = dockerfile)
570
+ BAKEFILE.include?(File.basename(file))
571
+ end
572
+
538
573
  def dockerfile(val = nil)
539
574
  if val == 'Dockerfile'
540
575
  @file = false
@@ -564,7 +599,7 @@ module Squared
564
599
  session('docker', *cmd, main: false, options: false, **kwargs)
565
600
  end
566
601
 
567
- def append_command(flag, val, list, target: @session, from: nil)
602
+ def append_command(flag, val, list, target: @session)
568
603
  if list.delete(':')
569
604
  list << readline('Enter command [args]', force: true)
570
605
  elsif (args = env('DOCKER_ARGS'))
@@ -573,15 +608,10 @@ module Squared
573
608
  case flag
574
609
  when :run
575
610
  unless session_arg?('name', target: target)
576
- target << basic_option('name', dnsname("#{name}_%s" % if RUBY_VERSION >= '3.1'
577
- require 'random/formatter'
578
- Random.new.alphanumeric(6)
579
- else
580
- (0...6).map { rand(97..122).chr }.join
581
- end))
611
+ target << basic_option('name', dnsname("#{name}_%s" % rand_s(6)))
582
612
  end
583
613
  when :exec
584
- raise_error('no command args', hint: from) if list.empty?
614
+ raise_error('no command args', hint: flag) if list.empty?
585
615
  end
586
616
  target << val << list.shift
587
617
  target << list.join(' && ') unless list.empty?
@@ -627,7 +657,7 @@ module Squared
627
657
  index = 0
628
658
  all = option('all', prefix: 'docker')
629
659
  y = from == :'image:rm' && option('y', prefix: 'docker')
630
- pat = /^(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})(?:[_.,:-]|$)/
660
+ pat = /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})\b/
631
661
  IO.popen(session_done(cmd << '--format=json')).each do |line|
632
662
  data = JSON.parse(line)
633
663
  id = data['ID']
@@ -676,14 +706,10 @@ module Squared
676
706
  end
677
707
  yield id
678
708
  end
679
- puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) if found || y
709
+ puts log_message(Logger::INFO, 'none detected', subject: name, hint: hint || from) if !found && !y
680
710
  end
681
711
  rescue StandardError => e
682
- log.error e
683
- ret = on(:error, from, e)
684
- raise if exception && ret != true
685
-
686
- warn log_message(Logger::WARN, e, pass: true) if warning?
712
+ on_error e, from
687
713
  end
688
714
 
689
715
  def confirm_command(*args, title: nil, target: nil, as: nil)
@@ -740,7 +766,7 @@ module Squared
740
766
  cmd = docker_output ctx
741
767
  case flag
742
768
  when :tag
743
- args = tagjoin @registry, @tag
769
+ args = tagjoin @registry, tag
744
770
  when :save
745
771
  opts = "#{opts}.tar" unless opts.end_with?('.tar')
746
772
  cmd << quote_option('output', File.expand_path(opts))
@@ -751,11 +777,7 @@ module Squared
751
777
  else
752
778
  cmd << opts << '--'
753
779
  end
754
- cmd.merge(if out.is_a?(Array)
755
- out.map! { |val| parse.call(val) }
756
- else
757
- [parse.call(out)]
758
- end)
780
+ cmd.merge(Array(out).map! { |val| parse.call(val) })
759
781
  cmd << args
760
782
  print_success if success?(run(cmd)) && ctx.match?(/\A(?:network|tag|save)/)
761
783
  end
@@ -803,14 +825,6 @@ module Squared
803
825
  def tagmain
804
826
  tag.is_a?(Array) ? tag.first : tag
805
827
  end
806
-
807
- def compose?(file = dockerfile)
808
- COMPOSEFILE.include?(File.basename(file))
809
- end
810
-
811
- def bake?(file = dockerfile)
812
- BAKEFILE.include?(File.basename(file))
813
- end
814
828
  end
815
829
 
816
830
  Application.implement Docker