kaiser 0.6.4 → 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: 9f8047763773bfe748430378babb51a03b464f203653f65b18c914c9dcc0fc5d
4
- data.tar.gz: f5f4f0965aa9cd5f8b54e5812e8f5810cd96db4140bc5efcfb4483b04394cf81
3
+ metadata.gz: 54e276a77032f484d216acc213a7c9157c8d5afd3c241c95c81c68845cd94dd7
4
+ data.tar.gz: cd24e7b599320b2c6e6ef94bc2c0fcb27f02f82fa6bbe6fda7919af2de5ce862
5
5
  SHA512:
6
- metadata.gz: 2c8500f56e296379d71bbde647cc5c55fdb44079d4ebf149ce2791c1b0aff279c590192baa02953d2b8c87c1a335796b84d410786a032aa0ba23ef059398477c
7
- data.tar.gz: 1c301bf576a3b1eab3a6fa785b37a9e58afa0c35c2bc9ede6c10bc6bea8a38c87f89fee1817d8dd6938ca32d2d4d667feff7638eeb1f7316b6a203c69be7713c
6
+ metadata.gz: d24d16515b2832b274adeeda21ecec02295394ad7b093874832cf7af154693fb5a8d0a7975e053fe7ecc0b24b380b8ff4864af1cd0acd95b8cf6343b273e29eb
7
+ data.tar.gz: e0aa642762fc2b3af586fbb1967c829d959854c645a282e73869713b3385279a2b891baade25f474b547c6d302052cf16450b9ddc08366722d740bf1530db5db
data/README.md CHANGED
@@ -31,23 +31,30 @@ Simply clone the repo and run
31
31
 
32
32
  ```
33
33
  cd kaiser
34
+ bundle
34
35
  docker build -t degica/kaiser .
35
36
  ```
36
37
 
37
38
  And then add the following line to your `.bashrc` or `.bash_profile`
38
39
 
39
40
  ```
40
- alias kaiser='docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/.kaiser:/root/.kaiser -v `pwd`:`pwd` -e CONTEXT_DIR="`pwd`" degica/kaiser'
41
+ alias kaiser='docker run --pull=always --rm -ti -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/.kaiser:/root/.kaiser -v `pwd`:`pwd` -e CONTEXT_DIR="`pwd`" degicadev/kaiser'
41
42
  ```
42
43
 
43
44
  Or if you use fish
44
45
 
45
46
  ```
46
47
  function kaiser
47
- docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/.kaiser:/root/.kaiser -v (pwd):(pwd) -e CONTEXT_DIR=(pwd) degica/kaiser $argv
48
+ docker run --pull=always --rm -ti -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/.kaiser:/root/.kaiser -v (pwd):(pwd) -e CONTEXT_DIR=(pwd) degicadev/kaiser $argv
48
49
  end
49
50
  ```
50
51
 
52
+ Confirm it is working by running
53
+
54
+ ```
55
+ kaiser -h
56
+ ```
57
+
51
58
  ## Usage
52
59
 
53
60
  You'll need a Dockerfile and a Kaiserfile. The Kaiserfile should be placed in the project root directory, with contents like this:
data/exe/kaiser CHANGED
@@ -5,7 +5,6 @@ require 'optimist'
5
5
  require 'fileutils'
6
6
  require 'yaml'
7
7
  require 'json'
8
- require 'pty'
9
8
  require 'erb'
10
9
 
11
10
  require 'kaiser'
data/lib/kaiser/cli.rb CHANGED
@@ -8,6 +8,12 @@ module Kaiser
8
8
  class Cli
9
9
  extend Kaiser::CliOptions
10
10
 
11
+ attr_reader :use_kaiserfile
12
+
13
+ def initialize
14
+ @use_kaiserfile = true
15
+ end
16
+
11
17
  def set_config
12
18
  # This is here for backwards compatibility since it can be used in Kaiserfiles.
13
19
  # It would be a good idea to deprecate this and make it more abstract.
@@ -19,7 +25,7 @@ module Kaiser
19
25
  @out = Config.out
20
26
  @info_out = Config.info_out
21
27
 
22
- @kaiserfile.validate!
28
+ @kaiserfile.validate! if @use_kaiserfile
23
29
  end
24
30
 
25
31
  # At first I did this in the constructor but the problem with that is Optimist
@@ -37,7 +43,7 @@ module Kaiser
37
43
  Optimist.options do
38
44
  banner u
39
45
 
40
- global_opts.each { |o| opt *o }
46
+ global_opts.each { |o| opt(*o) }
41
47
  end
42
48
  end
43
49
 
@@ -56,12 +62,12 @@ module Kaiser
56
62
  # easily use ARGV.shift to access its own subcommands.
57
63
  ARGV.shift
58
64
 
59
- Kaiser::Config.load(Dir.pwd)
65
+ Kaiser::Config.load(Dir.pwd, use_kaiserfile: cmd.use_kaiserfile)
60
66
 
61
67
  # We do all this work in here instead of the exe/kaiser file because we
62
68
  # want -h options to output before we check if a Kaiserfile exists.
63
69
  # If we do it in exe/kaiser, people won't be able to check help messages
64
- # unless they create a Kaiserfile firest.
70
+ # unless they create a Kaiserfile first.
65
71
  if opts[:quiet]
66
72
  Config.out = File.open(File::NULL, 'w')
67
73
  Config.info_out = File.open(File::NULL, 'w')
@@ -104,11 +110,7 @@ module Kaiser
104
110
  services.each do |service|
105
111
  Config.info_out.puts "Starting service: #{service.name}"
106
112
  run_if_dead(
107
- service.shared_name,
108
- "docker run -d
109
- --name #{service.shared_name}
110
- --network #{Config.config[:networkname]}
111
- #{service.image}"
113
+ service.shared_name, service.start_docker_command
112
114
  )
113
115
  end
114
116
  end
@@ -240,6 +242,10 @@ module Kaiser
240
242
  end
241
243
 
242
244
  def attach_app
245
+ start_services
246
+
247
+ puts 'Attaching to app...'
248
+
243
249
  cmd = (ARGV || []).join(' ')
244
250
  killrm app_container_name
245
251
 
@@ -259,6 +265,8 @@ module Kaiser
259
265
  #{app_params}
260
266
  kaiser:#{envname}-#{current_branch} #{cmd}".tr("\n", ' ')
261
267
 
268
+ stop_services
269
+
262
270
  Config.out.puts 'Cleaning up...'
263
271
  end
264
272
 
@@ -390,6 +398,10 @@ module Kaiser
390
398
  @services ||= Config.kaiserfile.services.map { |name, info| Service.new(envname, name, info) }
391
399
  end
392
400
 
401
+ def force_platform
402
+ Config.kaiserfile.platform || ''
403
+ end
404
+
393
405
  def db_port
394
406
  Config.config[:envs][envname][:db_port]
395
407
  end
@@ -514,6 +526,19 @@ module Kaiser
514
526
  end
515
527
  end
516
528
 
529
+ def selenium_node_image
530
+ return ENV['OVERRIDE_SELENIUM_NODE_IMAGE'] unless ENV['OVERRIDE_SELENIUM_NODE_IMAGE'].nil?
531
+
532
+ if RUBY_PLATFORM.start_with?('arm64') || RUBY_PLATFORM.start_with?('aarch64')
533
+ # use the seleniarm image because its more stable in arm procs
534
+ # somehow the x64 image does not do well under qemu under arm
535
+ return 'seleniarm/standalone-chromium'
536
+ end
537
+
538
+ # default to x64 image
539
+ 'selenium/standalone-chrome-debug'
540
+ end
541
+
517
542
  def ensure_setup
518
543
  ensure_env
519
544
 
@@ -528,15 +553,16 @@ module Kaiser
528
553
  "docker run -d
529
554
  --name #{Config.config[:shared_names][:redis]}
530
555
  --network #{Config.config[:networkname]}
531
- redis:alpine"
556
+ redis:7-alpine"
532
557
  )
533
558
  run_if_dead(
534
559
  Config.config[:shared_names][:chrome],
535
560
  "docker run -d
536
561
  -p 5900:5900
562
+ --shm-size='2g'
537
563
  --name #{Config.config[:shared_names][:chrome]}
538
564
  --network #{Config.config[:networkname]}
539
- selenium/standalone-chrome-debug"
565
+ #{selenium_node_image}"
540
566
  )
541
567
  run_if_dead(
542
568
  Config.config[:shared_names][:nginx],
@@ -574,7 +600,7 @@ module Kaiser
574
600
 
575
601
  def container_dead?(container)
576
602
  x = JSON.parse(`docker inspect #{container} 2>/dev/null`)
577
- return true if x.length.zero? || x[0]['State']['Running'] == false
603
+ x.empty? || x[0]['State']['Running'] == false
578
604
  end
579
605
 
580
606
  def if_container_dead(container)
@@ -585,14 +611,14 @@ module Kaiser
585
611
 
586
612
  def create_if_volume_not_exist(vol)
587
613
  x = JSON.parse(`docker volume inspect #{vol} 2>/dev/null`)
588
- return unless x.length.zero?
614
+ return unless x.empty?
589
615
 
590
616
  CommandRunner.run! Config.out, "docker volume create #{vol}"
591
617
  end
592
618
 
593
619
  def create_if_network_not_exist(net)
594
620
  x = JSON.parse(`docker inspect #{net} 2>/dev/null`)
595
- return unless x.length.zero?
621
+ return unless x.empty?
596
622
 
597
623
  CommandRunner.run! Config.out, "docker network create #{net}"
598
624
  end
@@ -615,7 +641,7 @@ module Kaiser
615
641
 
616
642
  def killrm(container)
617
643
  x = JSON.parse(`docker inspect #{container} 2>/dev/null`)
618
- return if x.length.zero?
644
+ return if x.empty?
619
645
 
620
646
  CommandRunner.run Config.out, "docker kill #{container}" if x[0]['State'] && x[0]['State']['Running'] == true
621
647
  CommandRunner.run Config.out, "docker rm #{container}" if x[0]['State']
@@ -21,6 +21,11 @@ module Kaiser
21
21
  EOS
22
22
  end
23
23
 
24
+ def initialize
25
+ super
26
+ @use_kaiserfile = false
27
+ end
28
+
24
29
  def execute(_opts)
25
30
  cmd = ARGV.shift
26
31
 
@@ -14,7 +14,7 @@ module Kaiser
14
14
  end
15
15
 
16
16
  def execute(_opts)
17
- Config.config[:shared_names].each do |_, container_name|
17
+ Config.config[:shared_names].each_value do |container_name|
18
18
  killrm container_name
19
19
  end
20
20
 
@@ -28,14 +28,27 @@ module Kaiser
28
28
  end
29
29
  end
30
30
 
31
+ def build_cmd
32
+ platform_args = ''
33
+ platform_args = "--platform=#{force_platform}" unless force_platform.empty?
34
+ build_args = docker_build_args.map { |k, v| "--build-arg #{k}=#{v}" }
35
+ [
36
+ 'docker build',
37
+ "-t kaiser:#{envname}-#{current_branch}",
38
+ "-f #{tmp_dockerfile_name} #{Config.work_dir}",
39
+ platform_args,
40
+ build_args.join(' ').to_s
41
+ ]
42
+ end
43
+
31
44
  def setup_app
32
45
  Config.info_out.puts 'Setting up application'
33
46
  File.write(tmp_dockerfile_name, docker_file_contents)
34
- build_args = docker_build_args.map { |k, v| "--build-arg #{k}=#{v}" }
35
- CommandRunner.run! Config.out, "docker build
36
- -t kaiser:#{envname}-#{current_branch}
37
- -f #{tmp_dockerfile_name} #{Config.work_dir}
38
- #{build_args.join(' ')}"
47
+
48
+ CommandRunner.run! Config.out, build_cmd.join("\n\t"), env_vars: {
49
+ 'DOCKER_BUILDKIT' => '1',
50
+ 'BUILDKIT_PROGRESS' => 'plain'
51
+ }
39
52
  FileUtils.rm(tmp_dockerfile_name)
40
53
  end
41
54
  end
@@ -1,24 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pty'
3
4
  require 'English'
4
5
 
5
- # This is the command runner
6
6
  module Kaiser
7
- # Make running easy
7
+ # This is the command runner
8
+ # it abstracts away the complicated syntax required to deal with
9
+ # PTY and to pass the lines programmatically to the host application
10
+ # as well as to capture the return code at the end.
8
11
  class CommandRunner
9
- def self.run(out, cmd, &block)
12
+ def self.run(out, cmd, env_vars: {}, &block)
10
13
  out.puts "> #{cmd}"
11
- CommandRunner.new(out, cmd).run_command(&block)
14
+ CommandRunner.new(out, cmd, env_vars).run_command(&block)
12
15
  end
13
16
 
14
- def self.run!(out, cmd, &block)
15
- status = run(out, cmd, &block)
17
+ def self.run!(out, cmd, env_vars: {}, &block)
18
+ status = run(out, cmd, env_vars: env_vars, &block)
16
19
  raise Kaiser::CmdError.new(cmd, status) if status.to_s != '0'
17
20
  end
18
21
 
19
- def initialize(out, cmd)
22
+ def initialize(out, cmd, env_vars)
20
23
  @out = out
21
24
  @cmd = cmd.tr "\n", ' '
25
+ @env_vars = env_vars
22
26
  end
23
27
 
24
28
  def print_and_return_status(status = 0)
@@ -38,7 +42,7 @@ module Kaiser
38
42
  end
39
43
 
40
44
  def run_command(&block)
41
- PTY.spawn("#{@cmd} 2>&1") do |stdout, _stdin, pid|
45
+ PTY.spawn(@env_vars, "#{@cmd} 2>&1") do |stdout, _stdin, pid|
42
46
  print_lines(stdout, &block)
43
47
  Process.wait(pid)
44
48
  end
data/lib/kaiser/config.rb CHANGED
@@ -12,7 +12,7 @@ module Kaiser
12
12
  :kaiserfile,
13
13
  :config
14
14
 
15
- def load(work_dir)
15
+ def load(work_dir, use_kaiserfile: true)
16
16
  @work_dir = work_dir
17
17
  @config_dir = "#{ENV['HOME']}/.kaiser"
18
18
 
@@ -20,7 +20,6 @@ module Kaiser
20
20
 
21
21
  FileUtils.mkdir_p @config_dir
22
22
  @config_file = "#{@config_dir}/config.yml"
23
- @kaiserfile = Kaiserfile.new("#{@work_dir}/Kaiserfile")
24
23
 
25
24
  @config = {
26
25
  envnames: {},
@@ -39,8 +38,11 @@ module Kaiser
39
38
 
40
39
  load_config
41
40
 
42
- alt_kaiserfile = "#{ENV['HOME']}/kaiserfiles/Kaiserfile.#{@config[:envnames][work_dir]}"
43
- @kaiserfile = Kaiserfile.new(alt_kaiserfile) if File.exist?(alt_kaiserfile)
41
+ if use_kaiserfile
42
+ @kaiserfile = Kaiserfile.new("#{@work_dir}/Kaiserfile")
43
+ alt_kaiserfile = "#{ENV['HOME']}/kaiserfiles/Kaiserfile.#{@config[:envnames][work_dir]}"
44
+ @kaiserfile = Kaiserfile.new(alt_kaiserfile) if File.exist?(alt_kaiserfile)
45
+ end
44
46
 
45
47
  @config
46
48
  end
@@ -76,6 +76,10 @@ module Kaiser
76
76
  }
77
77
  end
78
78
 
79
+ def force_platform(platform_name)
80
+ @platform = platform_name
81
+ end
82
+
79
83
  def expose(port)
80
84
  @port = port
81
85
  end
@@ -98,10 +102,20 @@ module Kaiser
98
102
  @server_type = value
99
103
  end
100
104
 
101
- def service(name, image: name)
105
+ def service(name,
106
+ image: name,
107
+ command: nil,
108
+ binds: {},
109
+ env: {})
110
+
102
111
  raise "duplicate service #{name.inspect}" if @services.key?(name)
103
112
 
104
- @services[name] = { image: image }
113
+ @services[name] = {
114
+ image: image,
115
+ command: command,
116
+ binds: binds,
117
+ env: env
118
+ }
105
119
  end
106
120
  end
107
121
  end
@@ -18,5 +18,43 @@ module Kaiser
18
18
  def image
19
19
  @service_info[:image]
20
20
  end
21
+
22
+ def command
23
+ @service_info[:command].to_s
24
+ end
25
+
26
+ def binds
27
+ @service_info[:binds] || {}
28
+ end
29
+
30
+ def env
31
+ @service_info[:env] || {}
32
+ end
33
+
34
+ def start_docker_command
35
+ envstring = env.map do |k, v|
36
+ "-e #{k}=#{v}"
37
+ end.join(' ')
38
+
39
+ bindstring = binds.map do |k, v|
40
+ "-v #{k}:#{v}"
41
+ end.join(' ')
42
+
43
+ commandstring = command
44
+
45
+ cmd_array = [
46
+ 'docker run -d',
47
+ "--name #{shared_name}",
48
+ "--network #{Config.config[:networkname]}",
49
+ envstring,
50
+ bindstring,
51
+ image,
52
+ commandstring
53
+ ]
54
+
55
+ cmd_array.filter! { |x| !x.empty? }
56
+
57
+ cmd_array.join(' ')
58
+ end
21
59
  end
22
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kaiser
4
- VERSION = '0.6.4'
4
+ VERSION = '0.8.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kaiser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Siaw
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-18 00:00:00.000000000 Z
11
+ date: 2024-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -198,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
198
  - !ruby/object:Gem::Version
199
199
  version: '0'
200
200
  requirements: []
201
- rubygems_version: 3.1.2
201
+ rubygems_version: 3.3.26
202
202
  signing_key:
203
203
  specification_version: 4
204
204
  summary: Manage your monsters