escli 1.0.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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +41 -0
  7. data/Rakefile +10 -0
  8. data/bin/escli +5 -0
  9. data/bin/setup +8 -0
  10. data/escli.gemspec +34 -0
  11. data/lib/canzea/cli/canzea.rb +323 -0
  12. data/lib/canzea/cli/escli.rb +207 -0
  13. data/lib/canzea/commands/add-env.rb +64 -0
  14. data/lib/canzea/commands/apply-config.rb +50 -0
  15. data/lib/canzea/commands/config-git-commit.rb +78 -0
  16. data/lib/canzea/commands/ecosystem/ecosystem.rb +66 -0
  17. data/lib/canzea/commands/ecosystem/resources.rb +82 -0
  18. data/lib/canzea/commands/gen-user.rb +22 -0
  19. data/lib/canzea/commands/get-catalog.rb +46 -0
  20. data/lib/canzea/commands/login.rb +50 -0
  21. data/lib/canzea/commands/prepare-plan.rb +82 -0
  22. data/lib/canzea/commands/push-config.rb +283 -0
  23. data/lib/canzea/commands/register-metadata.rb +79 -0
  24. data/lib/canzea/commands/remote-bootstrap.rb +38 -0
  25. data/lib/canzea/commands/remote-run.rb +37 -0
  26. data/lib/canzea/commands/update-config.rb +26 -0
  27. data/lib/canzea/config.rb +35 -0
  28. data/lib/canzea/core/audit.rb +86 -0
  29. data/lib/canzea/core/prepare-environment.rb +194 -0
  30. data/lib/canzea/core/registry.rb +191 -0
  31. data/lib/canzea/core/ssh-base-cmd-class.rb +103 -0
  32. data/lib/canzea/core/template-runner.rb +41 -0
  33. data/lib/canzea/core/trace-component.rb +171 -0
  34. data/lib/canzea/core/trace-runner.rb +108 -0
  35. data/lib/canzea/environment.rb +6 -0
  36. data/lib/canzea/helper-run-class.rb +89 -0
  37. data/lib/canzea/plan-step-class.rb +210 -0
  38. data/lib/canzea/registry.rb +12 -0
  39. data/lib/canzea/version.rb +3 -0
  40. metadata +201 -0
@@ -0,0 +1,108 @@
1
+ require 'json'
2
+ require 'open3'
3
+ require 'stringio'
4
+ require 'logger'
5
+ require 'canzea/core/audit'
6
+ require 'canzea/config'
7
+
8
+ def time_diff_milli(start, finish)
9
+ (finish - start) * 1000.0
10
+ end
11
+
12
+ def handleIO(stillOpen, ioArray, io, log)
13
+ if ioArray.include?(io)
14
+ begin
15
+ log.write(io.readpartial(4096))
16
+ rescue EOFError
17
+ stillOpen.delete_if{|s| s == io}
18
+ end
19
+ end
20
+ end
21
+
22
+ class RunnerWorker
23
+ def initialize (_raw)
24
+ @raw = _raw;
25
+ end
26
+
27
+ def run(command, start, lines, statusIndicator = false)
28
+ audit = Audit.new @raw
29
+
30
+ log = Logger.new(Canzea::config[:logging_root] + '/plans.log')
31
+
32
+ log.info("HANDLING: " + command)
33
+
34
+ l = command
35
+
36
+ audit.start( "#{lines + 1 }", l.chomp)
37
+
38
+ t1 = Time.now
39
+
40
+ workingDir = Canzea::config[:pwd]
41
+
42
+ pputs "Executing [#{workingDir}] #{l}"
43
+ Dir.chdir(workingDir){
44
+
45
+ Open3.popen3(ENV, l) {|stdin, stdout, stderr, wait_thr|
46
+ pid = wait_thr.pid # pid of the started process.
47
+
48
+ log_w = StringIO.new
49
+
50
+ stillOpen = [stdout, stderr]
51
+ while !stillOpen.empty?
52
+ fhs = select(stillOpen, nil, nil, nil)
53
+ handleIO(stillOpen, fhs[0], stdout, log_w)
54
+ handleIO(stillOpen, fhs[0], stderr, log_w)
55
+ end
56
+
57
+ exit_status = wait_thr.value # wait for it to finish
58
+
59
+ log_w.close_write
60
+
61
+ t2 = Time.now
62
+ msecs = time_diff_milli t1, t2
63
+
64
+ output = log_w.string
65
+
66
+ output.scan(/.{1,80}/).each do | line |
67
+ log.info("STDOUT: #{line}")
68
+ end
69
+
70
+ log.info("Exit Status = #{exit_status}")
71
+ log.info("Completed in (ms) : #{msecs}")
72
+
73
+ pputs "Exit Status = #{exit_status}"
74
+ output.split(/\n/).each do | line |
75
+ pputs "#{line}"
76
+ end
77
+
78
+
79
+ # if exit status is failure then exit right away
80
+
81
+ audit.complete("#{lines + 1}", l.chomp, exit_status.exitstatus, msecs, output)
82
+
83
+ if (statusIndicator)
84
+ audit.status("#{lines + 1}", l.chomp, exit_status.exitstatus, msecs, output)
85
+ end
86
+
87
+ if (@raw)
88
+ puts output
89
+ end
90
+
91
+ if exit_status.exitstatus != 0
92
+ abort()
93
+ end
94
+ }
95
+ }
96
+
97
+ lines += 1
98
+
99
+ return lines
100
+
101
+ end
102
+
103
+ def pputs (s)
104
+ if (@raw == false)
105
+ puts "-- #{s}"
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,6 @@
1
+ module Canzea
2
+
3
+ # if ENV.has_key?('CONSUL_URL') == false
4
+ # raise("CONSUL_URL environment variable is required to be set!")
5
+ # end
6
+ end
@@ -0,0 +1,89 @@
1
+ require 'json'
2
+ require 'logger'
3
+ require "base64"
4
+
5
+ require "canzea/core/prepare-environment"
6
+ require "canzea/core/trace-runner"
7
+
8
+ class HelperRun
9
+ def initialize (_raw)
10
+ @basePath = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}"
11
+ @log = Logger.new(Canzea::config[:logging_root] + '/plans.log')
12
+ @raw = _raw
13
+ end
14
+
15
+ def runPlan (plans)
16
+ plans.each { | plan |
17
+ puts "Running #{plan[:action]}"
18
+ self.run plan[:solution], plan[:action], JSON.generate(plan[:parameters])
19
+ }
20
+ end
21
+
22
+ def enrich (params)
23
+ # If there is context information, then merge them into the parameters before calling the helper
24
+ if (ENV.has_key?('WORK_DIR') and File.exists?ENV['WORK_DIR'] + "/context.json")
25
+ context = JSON.parse(File.read(ENV['WORK_DIR'] + "/context.json"))
26
+ result = JSON.parse(params).merge(context)
27
+ return JSON.generate(result)
28
+ end
29
+ return params
30
+ end
31
+
32
+ def run (solution, action, parameters, status = false)
33
+
34
+ type = "ruby"
35
+
36
+ parameters = self.enrich(parameters)
37
+
38
+ envPush = PrepareEnvironment.new @raw
39
+
40
+ begin
41
+ root = "#{@basePath}/helpers/#{solution}"
42
+ if File.exist?("#{@basePath}/blocks/#{solution}/#{action}")
43
+ root = "#{@basePath}/blocks/#{solution}/#{action}"
44
+ end
45
+ envScript = "#{root}/environment.json"
46
+ if File.exist?(envScript)
47
+ @log.info("Adding environment variables...")
48
+ envPush.addToEnv "#{envScript}"
49
+ end
50
+
51
+ if File.exist?("#{root}/#{action}.sh")
52
+ type = "shell"
53
+ elsif File.exist?("#{root}/#{action}.py")
54
+ type = "python"
55
+ end
56
+
57
+ r = RunnerWorker.new @raw
58
+
59
+ ENV['CATALOG_LOCATION'] = "#{@basePath}";
60
+
61
+ ENV['ES_SOLUTION'] = solution;
62
+ ENV['ES_ACTION'] = action;
63
+
64
+ parameters = Template.new.processString(parameters, {})
65
+
66
+ if (type == "ruby")
67
+ cmd = "ruby #{root}/#{action}.rb '#{parameters}'"
68
+ elsif (type == "python")
69
+ cmd = "python #{root}/#{action}.py '#{parameters}'"
70
+ else
71
+ argList = []
72
+ args = JSON.parse(parameters)
73
+ args.each do | k |
74
+ argList.push('--' + k[0])
75
+ argList.push('"' + k[1] + '"')
76
+ end
77
+
78
+ cmd = "#{root}/#{action}.sh #{argList.join(' ')}"
79
+ end
80
+ r.run cmd, 1, 1, status
81
+
82
+ rescue => exception
83
+ @log.error(cmd)
84
+ @log.error(exception.to_s)
85
+ @log.error(exception.backtrace)
86
+ abort()
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,210 @@
1
+ require 'json'
2
+ require 'logger'
3
+ require 'pathname'
4
+ require 'canzea/helper-run-class'
5
+ require 'canzea/core/prepare-environment'
6
+ require 'canzea/core/trace-component'
7
+ require 'canzea/commands/push-config'
8
+
9
+ class PlanStep
10
+ def initialize ()
11
+ @basePath = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}"
12
+ @log = Logger.new(Canzea::config[:logging_root] + '/plans.log')
13
+ end
14
+
15
+ def runPhaseInstall (role, solution, test, task)
16
+
17
+ plan = JSON.parse("{ \"plan\": [ { \"role\": \"#{role}\", \"solution\": \"#{solution}\" } ] }")
18
+
19
+ ENV['ES_ROLE'] = role;
20
+ ENV['ES_SOLUTION'] = solution;
21
+
22
+ n = Worker.new
23
+ n.test ( test )
24
+
25
+ start = Integer(task)
26
+ lines = 1
27
+
28
+ cmd = "undefined"
29
+
30
+ begin
31
+
32
+ plan['plan'].each do |item|
33
+ @log.info(item['solution'])
34
+
35
+ root = "#{@basePath}/roles/#{item['role']}/#{item['solution']}"
36
+ if File.exist?(root) == false
37
+ root = "#{@basePath}/blocks/#{item['solution']}"
38
+ if File.exist?(root) == false
39
+ puts "-- ERROR #{root} does not exist!"
40
+ raise "#{root} does not exist!"
41
+ end
42
+ end
43
+
44
+ cmd = "#{root}/install.sh"
45
+ if File.exist?(cmd)
46
+ lines = n.run cmd, start, lines - 1
47
+
48
+ @log.info "#{ lines } lines read"
49
+ end
50
+ end
51
+ rescue => exception
52
+ @log.error(cmd)
53
+ @log.error(exception.to_s)
54
+ @log.error(exception.backtrace)
55
+ abort()
56
+ end
57
+ end
58
+
59
+ def runPhaseConfigure (role, solution, test, task, ref="")
60
+
61
+ plan = JSON.parse("{ \"plan\": [ { \"role\": \"#{role}\", \"solution\": \"#{solution}\" } ] }")
62
+
63
+ ENV['ES_REF'] = ref;
64
+ ENV['ES_ROLE'] = role;
65
+ ENV['ES_SOLUTION'] = solution;
66
+
67
+ n = Worker.new
68
+ n.test ( test )
69
+
70
+ start = Integer(task)
71
+ lines = 1
72
+
73
+ cmd = "undefined"
74
+
75
+ begin
76
+
77
+ plan['plan'].each do |item|
78
+
79
+ root = "#{@basePath}/roles/#{item['role']}/#{item['solution']}"
80
+ if File.exist?(root) == false
81
+ root = "#{@basePath}/blocks/#{item['solution']}"
82
+ if File.exist?(root) == false
83
+ log "-- ERROR #{root} does not exist!"
84
+ raise "#{root} does not exist!"
85
+ end
86
+ end
87
+
88
+ if (test == false)
89
+ # Register the service with Consul, if consul is ready
90
+ # If metadata.json exists, then use the information to register
91
+ cmd = "#{root}/metadata.json"
92
+ if File.exist?(cmd)
93
+ md = File.read(cmd)
94
+ md = JSON.parse(md)
95
+ if (md['services'].size() > 0)
96
+ svc = md['services'][0]
97
+
98
+ adef = {
99
+ "listener"=>svc['listener'],
100
+ "name" => "#{svc['name']}",
101
+ "id" => "#{ENV['HOSTNAME']}-#{svc['name']}",
102
+ "tags"=>[ item['role'] ],
103
+ "port"=>svc['port']
104
+ }
105
+ log "-- Registering #{svc['name']}"
106
+ h = HelperRun.new false
107
+ h.run "consul", "register_service", JSON.generate(adef)
108
+ end
109
+ end
110
+
111
+ envScript = "#{root}/environment.json"
112
+ if File.exist?(envScript)
113
+ envPush = PrepareEnvironment.new false
114
+ envPush.addToEnv "#{envScript}"
115
+ end
116
+
117
+ end
118
+
119
+ cmd = "#{root}/configure.sh"
120
+ if File.exist?(cmd)
121
+ lines = n.run cmd, start, lines - 1, false, ref
122
+ end
123
+
124
+ cmd = "#{root}/enable.sh"
125
+ if File.exist?(cmd)
126
+ lines = n.run cmd, start, lines - 1, false, ref
127
+ end
128
+
129
+ cmd = "#{root}/status.sh"
130
+ if File.exist?(cmd)
131
+ lines = n.run cmd, start, lines - 1, true, ref
132
+ end
133
+
134
+ if ENV.has_key? "ECOSYSTEM_CONFIG_GIT"
135
+ log "-- Writing data to ecosystem git"
136
+ adef = {
137
+ "ES_ROLE" => role,
138
+ "ES_SOLUTION" => solution
139
+ }
140
+ h = HelperRun.new false
141
+ h.run "ecosystem", "analyze-solution", JSON.generate(adef)
142
+ end
143
+ end
144
+ rescue => exception
145
+ @log.error(cmd)
146
+ @log.error(exception.to_s)
147
+ @log.error(exception.backtrace)
148
+ abort()
149
+ end
150
+ end
151
+
152
+
153
+ def runPhasePatch (commit, solution, test, task, ref="")
154
+
155
+ plan = JSON.parse("{ \"plan\": [ { \"commit\": \"#{commit}\", \"solution\": \"#{solution}\" } ] }")
156
+
157
+ ENV['ES_REF'] = ref;
158
+ ENV['ES_ROLE'] = 'patch';
159
+ ENV['ES_SOLUTION'] = solution;
160
+
161
+ n = Worker.new
162
+ n.test ( test )
163
+
164
+ start = Integer(task)
165
+ lines = 1
166
+
167
+ cmd = "undefined"
168
+
169
+ # patches/<commit>/<solution>
170
+ begin
171
+
172
+ plan['plan'].each do |item|
173
+
174
+ root = "#{@basePath}/patches/#{item['commit']}/#{item['solution']}"
175
+ if File.exist?(root) == false
176
+ log "-- WARNING #{root} does not exist"
177
+ else
178
+
179
+ if (test == false)
180
+
181
+ envScript = "#{root}/environment.json"
182
+ if File.exist?(envScript)
183
+ envPush = PrepareEnvironment.new false
184
+ envPush.addToEnv "#{envScript}"
185
+ end
186
+
187
+ end
188
+
189
+ ENV.store('SCRIPT_PATH', root)
190
+
191
+ cmd = "#{root}/patch.sh"
192
+ if File.exist?(cmd)
193
+ lines = n.run cmd, start, lines - 1, false, ref
194
+ end
195
+ end
196
+ end
197
+ rescue => exception
198
+ @log.error(cmd)
199
+ @log.error(exception.to_s)
200
+ @log.error(exception.backtrace)
201
+ abort()
202
+ end
203
+ end
204
+
205
+ def log (msg)
206
+ puts msg
207
+ @log.info(msg)
208
+ end
209
+
210
+ end
@@ -0,0 +1,12 @@
1
+ require 'json'
2
+ require_relative 'config'
3
+ require_relative 'canzea/core/registry'
4
+
5
+ module Canzea
6
+
7
+ extraConfig = Canzea::config[:config_location] + "/config.json"
8
+ if File.exists?(extraConfig)
9
+ file = File.read(extraConfig)
10
+ Canzea::configure JSON.parse(file)
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Canzea
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,201 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: escli
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Canzea Technologies
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-ssh
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 4.1.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 4.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-sftp
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mustache
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: cri
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.4.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.4.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: git
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.3'
125
+ description: Orchestrate the building of images based on defined ecosystem blueprints.
126
+ email:
127
+ - ikethecoder@canzea.com
128
+ executables:
129
+ - escli
130
+ - setup
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".gitignore"
135
+ - ".idea/compiler.xml"
136
+ - ".idea/copyright/profiles_settings.xml"
137
+ - ".idea/misc.xml"
138
+ - ".idea/modules.xml"
139
+ - ".idea/vcs.xml"
140
+ - ".travis.yml"
141
+ - Gemfile
142
+ - LICENSE.txt
143
+ - README.md
144
+ - Rakefile
145
+ - bin/escli
146
+ - bin/setup
147
+ - escli.gemspec
148
+ - lib/canzea/cli/canzea.rb
149
+ - lib/canzea/cli/escli.rb
150
+ - lib/canzea/commands/add-env.rb
151
+ - lib/canzea/commands/apply-config.rb
152
+ - lib/canzea/commands/config-git-commit.rb
153
+ - lib/canzea/commands/ecosystem/ecosystem.rb
154
+ - lib/canzea/commands/ecosystem/resources.rb
155
+ - lib/canzea/commands/gen-user.rb
156
+ - lib/canzea/commands/get-catalog.rb
157
+ - lib/canzea/commands/login.rb
158
+ - lib/canzea/commands/prepare-plan.rb
159
+ - lib/canzea/commands/push-config.rb
160
+ - lib/canzea/commands/register-metadata.rb
161
+ - lib/canzea/commands/remote-bootstrap.rb
162
+ - lib/canzea/commands/remote-run.rb
163
+ - lib/canzea/commands/update-config.rb
164
+ - lib/canzea/config.rb
165
+ - lib/canzea/core/audit.rb
166
+ - lib/canzea/core/prepare-environment.rb
167
+ - lib/canzea/core/registry.rb
168
+ - lib/canzea/core/ssh-base-cmd-class.rb
169
+ - lib/canzea/core/template-runner.rb
170
+ - lib/canzea/core/trace-component.rb
171
+ - lib/canzea/core/trace-runner.rb
172
+ - lib/canzea/environment.rb
173
+ - lib/canzea/helper-run-class.rb
174
+ - lib/canzea/plan-step-class.rb
175
+ - lib/canzea/registry.rb
176
+ - lib/canzea/version.rb
177
+ homepage: http://www.canzea.com
178
+ licenses:
179
+ - MIT
180
+ metadata: {}
181
+ post_install_message:
182
+ rdoc_options: []
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ required_rubygems_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ requirements: []
196
+ rubyforge_project:
197
+ rubygems_version: 2.5.2.3
198
+ signing_key:
199
+ specification_version: 4
200
+ summary: Canzea command line interface for orchestrating builds.
201
+ test_files: []