minfra-cli 1.6.2 → 1.7.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: 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