squared 0.4.7 → 0.4.9

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.
@@ -4,8 +4,6 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Docker < Base
7
- include Prompt
8
-
9
7
  COMPOSEFILE = %w[compose.yaml compose.yml docker-compose.yaml compose.yml docker-compose.yml].freeze
10
8
  BAKEFILE = %w[docker-bake.json docker-bake.hcl docker-bake.override.json docker-bake.override.hcl].freeze
11
9
  DIR_DOCKER = (COMPOSEFILE + BAKEFILE).freeze
@@ -37,15 +35,15 @@ module Squared
37
35
  run: %w[d|detach init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet
38
36
  read-only rm runtime t|tty add-host=q annotation=q a|attach=b blkio-weight-device=i cap-add=b
39
37
  cap-drop=b cgroup-parent=b cgroupns=b cidfile=p detach-keys=q device=q device-cgroup-rule=q
40
- device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
41
- disable-content-trust=b? dns=e dns-option=e dns-search=e domainname=b entrypoint=q e|env=qq
42
- env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b health-retries=i
43
- health-start-interval=b health-start-period=b health-timeout=b h|hostname=e io-maxbandwidth=b
44
- io-maxiops=b ip=b ip6=e ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b
45
- link-local-ip=b log-driver=b log-opt=q mac-address=e memory-swappiness=b mount=qq name=b network=b
46
- network-alias=b oom-score-adj=b pid=b platform=b p|publish=e pull=b restart=b runtime=b
47
- security-opt=q shm-size=b sig-proxy=b? stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q
48
- ulimit=q user=e userns=b uts=b v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
38
+ device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q disable-content-trust=b?
39
+ dns=e dns-option=e dns-search=e domainname=b entrypoint=q e|env=qq env-file=p expose=e gpus=q
40
+ group-add=b health-cmd=q health-interval=b health-retries=i health-start-interval=b
41
+ health-start-period=b health-timeout=b h|hostname=e io-maxbandwidth=b io-maxiops=b ip=b ip6=e ipc=b
42
+ isolation=b kernel-memory=b l|label=q label-file=p link=b link-local-ip=b log-driver=b log-opt=q
43
+ mac-address=e memory-swappiness=b mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b
44
+ platform=b p|publish=e pull=b restart=b runtime=b security-opt=q shm-size=b sig-proxy=b?
45
+ stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q user=e userns=b uts=b
46
+ v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
49
47
  exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
50
48
  w|workdir=q].freeze,
51
49
  update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
@@ -125,7 +123,7 @@ module Squared
125
123
  return unless ref?(Docker.ref)
126
124
 
127
125
  namespace name do
128
- @@tasks[Docker.ref].each do |action, flags|
126
+ Docker.subtasks do |action, flags|
129
127
  next if @pass.include?(action)
130
128
 
131
129
  namespace action do
@@ -151,31 +149,38 @@ module Squared
151
149
  when :build, :up
152
150
  format_desc action, flag, 'opts*,service*'
153
151
  task flag do |_, args|
154
- composex flag, args.to_a
152
+ compose! flag, args.to_a
155
153
  end
156
154
  when :exec, :run
157
155
  format_desc action, flag, "service,command#{flag == :exec ? '' : '?'},args*,opts*"
158
156
  task flag, [:service] do |_, args|
159
157
  service = param_guard(action, flag, args: args, key: :service)
160
- composex(flag, args.extras, service: service)
158
+ compose!(flag, args.extras, service: service)
161
159
  end
162
160
  end
163
161
  when 'container'
164
162
  case flag
165
163
  when :exec, :commit
166
- format_desc(action, flag, 'id/name,opts*', after: flag == :exec ? 'args+' : 'tag?')
164
+ format_desc(action, flag, flag == :exec ? 'id/name,opts*,args+' : 'id/name,tag?,opts*')
167
165
  task flag, [:id] do |_, args|
168
- id = param_guard(action, flag, args: args, key: :id)
169
- container(flag, args.extras, id: id)
166
+ if flag == :exec && !args.id
167
+ choice_command flag
168
+ else
169
+ id = param_guard(action, flag, args: args, key: :id)
170
+ container(flag, args.extras, id: id)
171
+ end
170
172
  end
171
173
  when :run
172
174
  format_desc action, flag, 'image,opts*,args*'
173
175
  task flag, [:image] do |_, args|
174
- image = param_guard(action, flag, args: args, key: :image)
175
- container(flag, args.extras, id: image)
176
+ if args.image
177
+ container(flag, args.extras, id: args.image)
178
+ else
179
+ choice_command flag
180
+ end
176
181
  end
177
182
  else
178
- format_desc(action, flag, 'opts*', after: "id/name#{flag == :update ? '+' : '*'}")
183
+ format_desc(action, flag, 'opts*,id/name', after: flag == :update ? '+' : '*')
179
184
  task flag do |_, args|
180
185
  container flag, args.to_a
181
186
  end
@@ -188,7 +193,7 @@ module Squared
188
193
  tag = param_guard(action, flag, args: args, key: :tag)
189
194
  image(flag, args.extras, id: tag)
190
195
  end
191
- else
196
+ when :list, :rm
192
197
  format_desc(action, flag, flag == :rm ? 'id*,opts*' : 'opts*,args*')
193
198
  task flag do |_, args|
194
199
  image flag, args.to_a
@@ -197,8 +202,11 @@ module Squared
197
202
  when 'network'
198
203
  format_desc action, flag, 'target,opts*'
199
204
  task flag, [:target] do |_, args|
200
- target = param_guard(action, flag, args: args, key: :target)
201
- network(flag, args.extras, target: target)
205
+ if args.target
206
+ network(flag, args.extras, target: args.target)
207
+ else
208
+ choice_command flag
209
+ end
202
210
  end
203
211
  end
204
212
  end
@@ -251,13 +259,13 @@ module Squared
251
259
  when :build
252
260
  case @secrets
253
261
  when String
254
- quote_option('secret', @secrets, double: true)
262
+ ret << quote_option('secret', @secrets, double: true)
255
263
  when Hash
256
264
  append = lambda do |type|
257
265
  as_a(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
258
266
  end
259
- append.(:file)
260
- append.(:env)
267
+ append.call(:file)
268
+ append.call(:env)
261
269
  else
262
270
  as_a(@secrets).each { |arg| ret << quote_option('secret', arg) }
263
271
  end
@@ -297,14 +305,14 @@ module Squared
297
305
  end
298
306
  end
299
307
  op.append(args, escape: true)
300
- contextdir(context) if context
308
+ contextdir context if context
301
309
  end
302
310
  end
303
311
  op.clear(pass: false)
304
312
  run(from: :"buildx:#{flag}")
305
313
  end
306
314
 
307
- def composex(flag, opts = [], service: nil)
315
+ def compose!(flag, opts = [], service: nil)
308
316
  cmd, opts = docker_session('compose', opts: opts)
309
317
  op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
310
318
  append_file filetype unless op.arg?('f', 'file')
@@ -351,7 +359,7 @@ module Squared
351
359
  args << k
352
360
  next
353
361
  when 'source', 'src', 'destination', 'dst', 'target'
354
- v = basepath(v)
362
+ v = path + v
355
363
  v = shell_quote(v, option: false, force: false) if q == ''
356
364
  tmpfs = false if k[0] == 's'
357
365
  end
@@ -410,7 +418,7 @@ module Squared
410
418
  when :rm
411
419
  status = %w[created exited dead]
412
420
  end
413
- ps = docker_output('ps -a', *status.map { |s| "--filter='status=#{s}'" })
421
+ ps = docker_output('ps -a', *status.map { |s| "--filter=\"status=#{s}\"" })
414
422
  list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
415
423
  run(cmd.temp(img), from: from)
416
424
  end
@@ -449,8 +457,7 @@ module Squared
449
457
  op << id
450
458
  else
451
459
  if op.empty?
452
- list_image(flag, docker_output('image', 'ls', '-a'), from: from) do |val|
453
- puts val
460
+ list_image(flag, docker_output('image ls -a'), from: from) do |val|
454
461
  image(:rm, opts, sync: sync, id: val)
455
462
  end
456
463
  else
@@ -480,7 +487,7 @@ module Squared
480
487
  op.clear
481
488
  from = :"network:#{flag}"
482
489
  list_image(flag, docker_output('ps -a'), from: from) do |img|
483
- puts 'Success' if run(cmd.temp(target, img), from: from) == true && stdout? && banner?
490
+ print_success if success?(run(cmd.temp(target, img), from: from))
484
491
  end
485
492
  end
486
493
 
@@ -522,6 +529,9 @@ module Squared
522
529
  end
523
530
 
524
531
  def append_command(flag, val, list, target: @session, from: nil)
532
+ if (args = env('DOCKER_ARGS'))
533
+ list << args
534
+ end
525
535
  case flag
526
536
  when :run
527
537
  unless session_arg?('name', target: target)
@@ -532,13 +542,13 @@ module Squared
532
542
  raise_error('no command args', hint: from) if list.empty?
533
543
  end
534
544
  target << val << list.shift
535
- target << shell_quote(list.join(' && '), double: true, option: false) unless list.empty?
545
+ target << list.join(' && ') unless list.empty?
536
546
  end
537
547
 
538
548
  def append_file(type, target: @session)
539
549
  return unless type == 2 || type == 4 || @file.is_a?(Array)
540
550
 
541
- files = as_a(@file).map { |val| quote_option('file', basepath(val)) }
551
+ files = as_a(@file).map { |val| quote_option('file', path + val) }
542
552
  if target.is_a?(Set)
543
553
  target.merge(files)
544
554
  else
@@ -569,11 +579,11 @@ module Squared
569
579
  end
570
580
  end
571
581
 
572
- def list_image(flag, cmd, hint: nil, from: nil, no: true, &blk)
582
+ def list_image(flag, cmd, hint: nil, from: nil, no: true)
573
583
  pwd_set do
574
584
  found = false
575
585
  index = 0
576
- pat = /^(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':').first})(?:[_.,:-]|$)/
586
+ pat = /^(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})(?:[_.,:-]|$)/
577
587
  IO.popen(session_done(cmd << '--format=json')).each do |line|
578
588
  data = JSON.parse(line)
579
589
  id = data['ID']
@@ -586,7 +596,7 @@ module Squared
586
596
  id
587
597
  end)
588
598
  ee = data['Image'] || rt || aa
589
- next unless ee.match?(pat) || aa.match?(pat)
599
+ next unless option('all') || ee.match?(pat) || aa.match?(pat)
590
600
 
591
601
  bb = index.succ.to_s
592
602
  cc = bb.size + 1
@@ -618,7 +628,7 @@ module Squared
618
628
  next unless confirm("#{h + b}? [#{c}] ", d, timeout: 60)
619
629
 
620
630
  puts if @@print_order == 0
621
- blk.call id
631
+ yield id
622
632
  end
623
633
  puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) unless found
624
634
  end
@@ -646,6 +656,35 @@ module Squared
646
656
  confirm("#{a} #{b}#{c ? " as #{c}" : ''}? [y/N] ", 'N', timeout: 60)
647
657
  end
648
658
 
659
+ def choice_command(flag)
660
+ msg, cmd, index = case flag
661
+ when :run
662
+ ['Choose an image', 'images -a', 2]
663
+ when :exec
664
+ ['Choose a container', 'ps -a', 0]
665
+ else
666
+ ['Choose a network', 'network ls', 0]
667
+ end
668
+ lines = `#{docker_output(cmd)}`.lines
669
+ header = lines.shift
670
+ if lines.empty?
671
+ puts log_message(Logger::INFO, 'none found', subject: name, hint: "docker #{cmd}")
672
+ else
673
+ puts " # #{header}"
674
+ case flag
675
+ when :run, :exec
676
+ values = [['Options', flag == :run], ['Arguments', flag == :exec]]
677
+ cmd = flag.to_s
678
+ else
679
+ values = [['Options', false], ['Container', true]]
680
+ cmd = "network #{flag}"
681
+ end
682
+ out, opts, args = choice_index(msg, lines, values: values)
683
+ ret = run docker_output(cmd, opts, '--', out.split(/\s+/)[index], args)
684
+ print_success if success?(ret && cmd.start_with?('network'))
685
+ end
686
+ end
687
+
649
688
  def filetype(val = dockerfile)
650
689
  case File.extname(val)
651
690
  when '.hcl', '.json'
@@ -662,7 +701,7 @@ module Squared
662
701
  end
663
702
 
664
703
  def contextdir(val = nil)
665
- val && projectpath?(val) ? shell_quote(basepath(val)) : '.'
704
+ val && projectpath?(val) ? shell_quote(path + val) : '.'
666
705
  end
667
706
 
668
707
  def tagname(val)