minfra-cli 1.6.2 → 1.7.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: b5f12534bfcd73e84a69435f5cd58d9884d595a90c387518a663621c2a03e17a
4
- data.tar.gz: bd8bdc596ea6fef14fa55f187710b6841cd31df32447b76b63bf6bd4cf96e1ab
3
+ metadata.gz: 7266c109d03ea557a04e8219a7029de66167299ba21b918b85d8bb3161913203
4
+ data.tar.gz: 7097c3ced9f56d9d6d88a86ef02679a0e449b677ad74e9acb663c4fefab1c29e
5
5
  SHA512:
6
- metadata.gz: a15f204d44ba8432ff2a36d73b3e5069689dcc3307bb036e6492bbbc01fbbe8aeeb3fec40d098d28199658d32c487e6c10bc7a9391800800556f5972ca80e5ca
7
- data.tar.gz: 5dc1e214bf4a90d699c2cdbf47018c7966f303c4e990ff9aea1c5adaa09b7c50322ca34e765ae2f3b46fa2787e8609a0ee978e65a26eaee605875486c793cb25
6
+ metadata.gz: 46facd2f0d2783b7f57cbda7370ab0316b0363aa362765386951b3c7129de0156662100747d1f06aa46e7fe4bfbc7e441563cdadcf5e39e6a808537f7a6661dc
7
+ data.tar.gz: 87e9f9de9e9e5f3fd20cbc31f9dc651f4eb3fb8f4a460bdf967304a0bd0ae791ab4837526c18d6e98791a3edb829d9397efb2f553e389d971899a28a585108f9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 1.7.0
2
+ * rewrite of hooks system
3
+ * deprecation of me/kind.yaml.erb (breaking change as config/kind.yaml.erb the whole config object is passed
4
+ * improving Minfra::Cli::Runner to stream output
1
5
  # 1.6.2
2
6
  * fixing templater
3
7
  * generating Chart.yaml only once with the namespaces name
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- minfra-cli (1.0.1)
4
+ minfra-cli (1.7.0)
5
5
  activesupport (~> 6.1)
6
6
  erubis (~> 2.7)
7
7
  hashie (~> 3.5)
@@ -15,13 +15,13 @@ PATH
15
15
  GEM
16
16
  remote: https://rubygems.org/
17
17
  specs:
18
- activesupport (6.1.7)
18
+ activesupport (6.1.7.2)
19
19
  concurrent-ruby (~> 1.0, >= 1.0.2)
20
20
  i18n (>= 1.6, < 2)
21
21
  minitest (>= 5.1)
22
22
  tzinfo (~> 2.0)
23
23
  zeitwerk (~> 2.3)
24
- concurrent-ruby (1.1.10)
24
+ concurrent-ruby (1.2.0)
25
25
  diff-lcs (1.5.0)
26
26
  domain_name (0.5.20190701)
27
27
  unf (>= 0.0.5, < 1.0.0)
@@ -33,7 +33,7 @@ GEM
33
33
  optimist
34
34
  hiera-eyaml-gpg (0.7.4)
35
35
  hiera-eyaml (>= 1.3.8)
36
- highline (2.0.3)
36
+ highline (2.1.0)
37
37
  http-accept (1.7.0)
38
38
  http-cookie (1.0.5)
39
39
  domain_name (~> 0.5)
@@ -42,7 +42,7 @@ GEM
42
42
  mime-types (3.4.1)
43
43
  mime-types-data (~> 3.2015)
44
44
  mime-types-data (3.2022.0105)
45
- minitest (5.16.3)
45
+ minitest (5.17.0)
46
46
  netrc (0.11.0)
47
47
  optimist (3.0.1)
48
48
  rake (12.3.3)
@@ -67,12 +67,12 @@ GEM
67
67
  table_print (1.5.6)
68
68
  thor (1.2.1)
69
69
  timecop (0.9.5)
70
- tzinfo (2.0.5)
70
+ tzinfo (2.0.6)
71
71
  concurrent-ruby (~> 1.0)
72
72
  unf (0.1.4)
73
73
  unf_ext
74
74
  unf_ext (0.0.8.2)
75
- zeitwerk (2.6.0)
75
+ zeitwerk (2.6.6)
76
76
 
77
77
  PLATFORMS
78
78
  ruby
@@ -3,33 +3,11 @@ module Minfra
3
3
  class Command < Thor
4
4
  include Common
5
5
  include Logging
6
- include Hook
7
6
 
8
- attr_reader :minfra_config
9
- no_commands do
10
- def invoke_command(*args)
11
- begin
12
- subcommand_name = args.first.name.to_sym
13
- with_hook(subcommand_name) do
14
- @minfra_config = Minfra::Cli.config
15
- @minfra_config.load(options['environment']) if options['environment']
16
- @cli_args = args[1]
17
- super(*args)
18
- end
19
- rescue Minfra::Cli::Config::ConfigNotFoundError => err
20
- STDERR.puts(err.message)
21
- STDERR.puts "please run 'minfra setup dev'"
22
- exit 1
23
- rescue Minfra::Cli::Config::EnvironmentNotFoundError => err
24
- STDERR.puts(err.message)
25
- exit 1
26
- end
27
- end
28
- def cli_args
29
- @args
30
- end
31
-
32
- end
7
+ private
8
+ def minfra_config
9
+ Minfra::Cli.config
10
+ end
33
11
  end
34
12
  end
35
13
  end
@@ -6,7 +6,7 @@ module Minfra
6
6
  desc "describe", "get some info about your config (if it's setup)"
7
7
  option :environment, required: false, aliases: ['-e']
8
8
  def describe
9
- pp @minfra_config.describe(options[:environment])
9
+ pp minfra_config.describe(options[:environment])
10
10
  end
11
11
 
12
12
  desc "create", "create your development cluster"
@@ -18,8 +18,8 @@ module Minfra
18
18
  def upgrade
19
19
  info "Destroying existing dev cluster.."
20
20
  destroy
21
- Runner.run("mv #{@minfra_config.base_path.join('me','kind.yaml.erb')} #{@minfra_config.base_path.join('me','kind_old_' + Time.now.strftime("%Y_%m_%dT%H_%M_%SZ") + '.yaml.erb')}", print_stdout: true)
22
- Runner.run("mv #{@minfra_config.base_path.join('me', 'kube', 'config')} #{@minfra_config.base_path.join('me', 'kube', 'config_old_' + Time.now.strftime("%Y_%m_%dT%H_%M_%SZ"))}", print_stdout: true)
21
+ Runner.run("mv #{minfra_config.base_path.join('me','kind.yaml.erb')} #{minfra_config.base_path.join('me','kind_old_' + Time.now.strftime("%Y_%m_%dT%H_%M_%SZ") + '.yaml.erb')}", print_stdout: true)
22
+ Runner.run("mv #{minfra_config.base_path.join('me', 'kube', 'config')} #{minfra_config.base_path.join('me', 'kube', 'config_old_' + Time.now.strftime("%Y_%m_%dT%H_%M_%SZ"))}", print_stdout: true)
23
23
  Runner.run('yes | minfra setup dev', print_stdout: true) # On an existing cluster this should only ask for recreating the files that we moved previously
24
24
  info "Creating a new dev cluster.."
25
25
  create
@@ -40,7 +40,10 @@ module Minfra
40
40
 
41
41
  info "step: creating '#{kind_name}' kind cluster (can take some minutes)"
42
42
  kind_kube_path=Runner.run('echo $KUBECONFIG').to_s.strip
43
- info run(%{KIND_EXPERIMENTAL_DOCKER_NETWORK=#{kind_name} kind create cluster --name "#{kind_name}" --config #{@config.kind_config_path}})
43
+ kind_config=Templater.read(config.base_path.join('config','kind.yaml.erb'), params: {config: config})
44
+ File.write(config.kind_config_path, kind_config)
45
+
46
+ run(%{KIND_EXPERIMENTAL_DOCKER_NETWORK=#{kind_name} kind create cluster --name "#{kind_name}" --config #{@config.kind_config_path}})
44
47
 
45
48
  info "step: configuring kind"
46
49
  run %{docker exec #{kind_name}-control-plane bash -c "sed -e '/nameserver 127.0.0.11/ s/^#*/#/' /etc/resolv.conf | cat - >> /etc/resolv.conf"}
@@ -105,7 +108,7 @@ module Minfra
105
108
 
106
109
 
107
110
  run_cmd(["cd #{stack.release_path}",
108
- "git --no-pager diff #{stack.compose_path}",
111
+ "git --no-pager diff #{stack.release_path}",
109
112
  ], :bash, silence: true)
110
113
 
111
114
  errors = stack.check_plan
@@ -118,17 +121,12 @@ module Minfra
118
121
  end
119
122
 
120
123
  unless test
121
- unless @config.dev?
124
+ unless @config.dev? || options[:force]==true
122
125
  unless Ask.boolean("Are the changes ok?")
123
126
  exit_error("Deployment aborted!")
124
127
  end
125
128
  end
126
129
 
127
- # deploy_cmd = bash_cmd
128
- # deploy_cmd << "#{env_cmd} orchparty #{method} -c #{cluster} -f #{stack.stack_rb_path} -a #{stack.name}"
129
-
130
- reason_message = tag_changed_to(release_path: stack.release_path) if reason_message.blank?
131
-
132
130
  message = "deploying stack #{stack.name}: #{reason_message}."
133
131
  Minfra::Cli::Document.document(@config,"started #{message}")
134
132
  orch=Orchparty::App.new(cluster_name: cluster,
@@ -239,16 +237,6 @@ module Minfra
239
237
 
240
238
  private
241
239
 
242
- def tag_changed_to(release_path:)
243
- return '' if @config.dev? # We don't use messages in dev
244
-
245
- diff = run_cmd("cd #{release_path} && git --no-pager diff --unified=0 tags.json").split %r{(\d{4}_\d{2}_\d{2}T\d{2}_\d{2}_\d{2}Z)}
246
-
247
- raise ArgumentError.new "#{release_path}/tags.json has not changed - supply message" if diff.empty?
248
-
249
- diff[3]
250
- end
251
-
252
240
  def init(stack_name, env, deployment, explicit_cluster)
253
241
  template = Minfra::Cli::StackM::KubeStackTemplate.new(stack_name,
254
242
  config,
@@ -64,12 +64,12 @@ module Minfra
64
64
  end
65
65
 
66
66
  cmd = %{docker build #{"--target #{target}" if target} -t #{p.repo_name}:latest #{p.app_dir}}
67
- # Runner.run(cmd) # this gives us no output ... don't like that
68
- puts "running: #{cmd}"
69
- `#{cmd}` || exit(1)
67
+ res = Runner.run(cmd)
68
+ exit(1) if res.error?
69
+
70
70
  unless options[:noload]
71
71
  debug("loading int KIND")
72
- Runner.run(%{kind load docker-image #{p.repo_name}:latest --name #{@minfra_config.name}})
72
+ Runner.run(%{kind load docker-image #{p.repo_name}:latest --name #{minfra_config.name}})
73
73
  end
74
74
  end
75
75
 
@@ -103,7 +103,7 @@ module Minfra
103
103
 
104
104
  private
105
105
  def run_pre_repo
106
- Runner.run(%{#{@minfra_config.base_path.join('hooks','pre_repo.sh')}})
106
+ Runner.run(%{#{minfra_config.base_path.join('hooks','pre_repo.sh')}})
107
107
  end
108
108
  end
109
109
  end
@@ -17,13 +17,7 @@ module Minfra
17
17
  ensure_path_and_template(config.config_path, config.base_path.join('config','me_config.json.erb'))
18
18
  config.init!
19
19
  config.load('dev')
20
- templates_path=Minfra::Cli.root_path.join("templates")
21
- ensure_path_and_template(config.kube_config_path, templates_path.join('kube_config.yaml.erb'))
22
- ensure_path_and_template(config.kind_config_path, config.base_path.join('config','kind.yaml.erb'),
23
- {ip: config.project.kind.panel.ip,
24
- name: config.project.name,
25
- host_path: config.base_path
26
- })
20
+
27
21
  end
28
22
 
29
23
  def ensure_path_and_template(dest_path, template_path, params={})
@@ -10,7 +10,7 @@ module Minfra
10
10
  desc "describe","get information about a stack"
11
11
  option :environment, aliases: ['-e']
12
12
  def describe
13
- pp @minfra_config.describe(options["environment"])
13
+ pp minfra_config.describe(options["environment"])
14
14
  end
15
15
 
16
16
  desc "dashboard <stack_name>", "openening a dashboard for a stack"
@@ -30,6 +30,7 @@ module Minfra
30
30
  option :install, type: :boolean
31
31
  option :test, type: :boolean
32
32
  option :opts
33
+ option :force, type: :boolean
33
34
  def deploy(stack_name, message='')
34
35
  kube.deploy(stack_name, message)
35
36
  end
@@ -111,7 +112,7 @@ module Minfra
111
112
 
112
113
  private
113
114
  def kube
114
- Kube.new(options, @minfra_config)
115
+ Kube.new(options, minfra_config)
115
116
  end
116
117
  end
117
118
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module Minfra
4
3
  module Cli
5
4
  class Tag
@@ -15,13 +14,7 @@ module Minfra
15
14
  @format = format if format
16
15
 
17
16
  info 'Creating tag.'
18
- debug "Using .tags folder..."
19
- # write_tag_folder_file(message)
20
- #run_cmd(cmd_add_tag_info("#{@tags_folder}/#{tag_name}"), :system)
21
- #run_cmd(cmd_create_tag_commit, :system)
22
17
  run_cmd(cmd_tag_commit(message), :system)
23
- # info 'Pushing tag to remote.'
24
- # run_cmd(cmd_push, :system)
25
18
  run_cmd(cmd_push_tag, :system)
26
19
  end
27
20
 
@@ -68,14 +61,6 @@ module Minfra
68
61
  "#{git_current_branch}-REL-#{@now.strftime(@format)}"
69
62
  end
70
63
 
71
- def write_tag_folder_file(message)
72
- File.write("#{@tags_folder}/#{tag_name}", "#{message}\n")
73
- end
74
-
75
- def write_tag_file(_message)
76
- File.write(@tags_file.to_s, "#{tag_name}\n")
77
- end
78
-
79
64
  def run_cmd(cmd, _how = :system)
80
65
  Runner.run(cmd)
81
66
  end
@@ -42,7 +42,7 @@ module Minfra
42
42
  @status_path = @base_path.join('state')
43
43
  @kube_path=@me_path.join('kube')
44
44
  @kube_config_path=@kube_path.join('config')
45
- @kind_config_path=@me_path.join("kind.yaml.erb")
45
+ @kind_config_path=@me_path.join("kind.yaml")
46
46
 
47
47
  # @project_minfrarc_path = @base_path.join("config",'minfrarc.rb')
48
48
  # require @project_minfrarc_path if @project_minfrarc_path.exist?
@@ -1,43 +1,79 @@
1
1
  # no support for around hooks yet
2
2
 
3
+ class Thor
4
+ class Command
5
+ def run(instance, args = [])
6
+ arity = nil
7
+
8
+ if private_method?(instance)
9
+ instance.class.handle_no_command_error(name)
10
+ elsif public_method?(instance)
11
+ hooks=instance.instance_variable_get(:@_invocations).values.flatten
12
+ arity = instance.method(name).arity
13
+ Minfra::Cli.call_before_hooks(instance,hooks)
14
+ instance.__send__(name, *args)
15
+ Minfra::Cli.call_after_hooks(instance,hooks)
16
+ elsif local_method?(instance, :method_missing)
17
+ #Minfra::Cli.call_before_hooks(instance,hooks)
18
+ instance.__send__(:method_missing, name.to_sym, *args)
19
+ #Minfra::Cli.call_after_hooks(instance,hooks)
20
+ else
21
+ instance.class.handle_no_command_error(name)
22
+ end
23
+ rescue ArgumentError => e
24
+ handle_argument_error?(instance, e, caller) ? instance.class.handle_argument_error(self, e, args, arity) : (raise e)
25
+ rescue NoMethodError => e
26
+ handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (raise e)
27
+ end
28
+ end
29
+ end
30
+
3
31
  module Minfra
4
32
  module Cli
5
33
  module Hook
6
34
  class Hook
7
- def initialize(type, name, block)
35
+ def initialize(type, names, block)
8
36
  @type=type
9
- @name=name
37
+ @names=names
10
38
  @block=block
11
39
  end
12
40
 
13
- def match?(type, name)
14
- @type == type && @name == name
41
+ def match?(type, names)
42
+ @type == type && @names == names.map(&:to_sym)
15
43
  end
16
44
 
17
45
  def exec (obj)
18
46
  obj.instance_eval(&@block)
19
47
  end
20
-
21
48
  end
22
49
 
23
50
  class Hooker
51
+ include Logging
24
52
  def initialize(klass)
25
53
  @klass=klass
26
54
  @hooks=[]
27
55
  end
28
56
 
29
- def register_before(name, block)
30
- @hooks << Hook.new(:before, name, block)
57
+ def register_before(names, block)
58
+ @hooks << Hook.new(:before, names, block)
31
59
  end
32
60
 
33
- def register_after(name, block)
34
- @hooks << Hook.new(:after, name, block)
61
+ def register_after(names, block)
62
+ @hooks << Hook.new(:after, names, block)
35
63
  end
36
64
 
37
- def call(obj, name, &block)
38
- @hooks.select do |h| h.match?(:before, name) end.each do |h| h.exec(obj) end
39
- obj.instance_eval(&block)
40
- @hooks.select do |h| h.match?(:after, name) end.each do |h| h.exec(obj) end
65
+ def call_before_hooks(obj, names)
66
+ @hooks.select do |h| h.match?(:before, names) end.each do |h|
67
+ debug("Hook before: #{names.join(',')}")
68
+ h.exec(obj)
69
+ end
70
+ end
71
+
72
+ def call_after_hooks(obj,names)
73
+ @hooks.select do |h| h.match?(:after, names) end.each do |h|
74
+ debug("Hook after: #{names.join(',')}")
75
+ h.exec(obj)
76
+ end
41
77
  end
42
78
  end
43
79
 
@@ -46,19 +82,22 @@ module Minfra
46
82
  end
47
83
 
48
84
  module ClassMethods
49
- def hooks
50
- @hooker||=Hooker.new(self)
85
+ def after_hook(*names,&block)
86
+ hooks.register_after(names, block)
51
87
  end
52
- def after_hook(name,&block)
53
- hooks.register_after(name, block)
88
+ def before_hook(*names, &block)
89
+ hooks.register_before(names, block)
54
90
  end
55
- def before_hook(name, &block)
56
- hooks.register_before(name, block)
91
+ def call_before_hooks(obj,names)
92
+ @hooks.call_before_hooks(obj,names)
93
+ end
94
+ def call_after_hooks(obj,names)
95
+ @hooks.call_after_hooks(obj,names)
96
+ end
97
+ private
98
+ def hooks
99
+ @hooks||=Hooker.new(self)
57
100
  end
58
- end
59
-
60
- def with_hook(hook_name, &block)
61
- self.class.hooks.call(self, hook_name, &block)
62
101
  end
63
102
  end
64
103
  end
@@ -6,7 +6,7 @@ module Minfra
6
6
  option :cluster
7
7
  option :stack, required: true
8
8
  def kube(*args)
9
- kube = Kube.new(options, @minfra_config)
9
+ kube = Kube.new(options, minfra_config)
10
10
  kube.kubectl_command(args)
11
11
  end
12
12
 
@@ -4,13 +4,27 @@ module Minfra
4
4
  module Cli
5
5
  class Runner
6
6
  class Result
7
- attr_reader :stdout, :stderr
8
- def initialize(stdout,stderr, status)
9
- @stderr=stderr
10
- @stdout=stdout
11
- @status=status
7
+ include Logging
8
+
9
+ attr_writer :status
10
+
11
+ def initialize
12
+ @stderr_lines=[]
13
+ @stdout_lines=[]
14
+ @status=nil
12
15
  end
13
-
16
+
17
+ def add(line, stream=:stdout)
18
+ line.chomp!
19
+ if stream == :stdout
20
+ @stdout_lines << line
21
+ debug line
22
+ else
23
+ @stderr_lines << line
24
+ error line
25
+ end
26
+ end
27
+
14
28
  def success?
15
29
  @status.success?
16
30
  end
@@ -19,8 +33,16 @@ module Minfra
19
33
  !success?
20
34
  end
21
35
 
36
+ def stdout
37
+ @stdout_lines.join("\n")
38
+ end
39
+
40
+ def stderr
41
+ @stderr_lines.join("\n")
42
+ end
43
+
22
44
  def to_s
23
- @stdout.to_s
45
+ stdout
24
46
  end
25
47
  end
26
48
 
@@ -36,24 +58,37 @@ module Minfra
36
58
  end
37
59
 
38
60
  def run
39
- debug(@cmd)
61
+ debug("running: #{@cmd}")
40
62
  res=nil
41
63
  begin
42
- res=Result.new(*Open3.capture3(@cmd))
64
+ res=Result.new
65
+ # see: http://stackoverflow.com/a/1162850/83386
66
+ Open3.popen3(@cmd) do |stdin, stdout, stderr, thread|
67
+ # read each stream from a new thread
68
+ { :stdout => stdout, :stderr => stderr }.each do |key, stream|
69
+ Thread.new do
70
+ until (raw_line = stream.gets).nil? do
71
+ res.add(raw_line, key)
72
+ end
73
+ end
74
+ end
75
+ thread.join # don't exit until the external process is done
76
+ res.status = thread.value
77
+ end
43
78
  rescue
44
- end
45
- if res&.error?
46
- STDERR.puts "command failed: #{@cmd}"
47
- STDERR.puts res.stdout
48
- STDERR.puts res.stderr
49
79
  end
50
- if exit_on_error && res&.error?
51
- STDERR.puts "exiting on error"
80
+
81
+ if res.error?
82
+ error "command failed: #{@cmd}"
83
+ info res.stdout
84
+ error res.stderr
85
+ end
86
+ if exit_on_error && res.error?
87
+ info "exiting on error"
52
88
  exit 1
53
89
  end
54
90
  res
55
91
  end
56
-
57
92
  end
58
93
  end
59
94
  end
@@ -1,5 +1,5 @@
1
1
  module Minfra
2
2
  module Cli
3
- VERSION = '1.6.2'.freeze
3
+ VERSION = '1.7.0'.freeze
4
4
  end
5
5
  end
data/lib/minfra/cli.rb CHANGED
@@ -27,6 +27,7 @@ module Minfra
27
27
  module Cli
28
28
 
29
29
  extend Minfra::Cli::Logging
30
+ include Minfra::Cli::Hook
30
31
 
31
32
  def self.logger
32
33
  @logger
@@ -145,16 +146,5 @@ module Minfra
145
146
  end
146
147
  end
147
148
 
148
- def self.subcommand(name)
149
- @subcommands[name.to_sym]&.command
150
- end
151
-
152
- def self.before_hook(subcommand, command, &block)
153
- subcommand(subcommand).before_hook(command, &block)
154
- end
155
-
156
- def self.after_hook(subcommand, command, &block)
157
- subcommand(subcommand).after_hook(command, &block)
158
- end
159
149
  end
160
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minfra-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Schrammel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-12 00:00:00.000000000 Z
11
+ date: 2023-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor