Hitcher 0.1.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.
@@ -0,0 +1,74 @@
1
+
2
+ require 'toolrack'
3
+
4
+ require 'erb'
5
+ require_relative 'command_builder'
6
+
7
+ module Hitcher
8
+ module Docker
9
+ class TemplateEngine
10
+ include Hitcher::Docker::CommandBuilder
11
+
12
+ def build_template(temp, val)
13
+ dest_root = Dir.getwd if val[:dest_root].nil? or val[:dest_root].empty?
14
+
15
+ case temp
16
+ when :dockerfile
17
+ path = File.join(File.dirname(__FILE__),"templates","Dockerfile.erb")
18
+ bind_template(path, File.join(dest_root,"Dockerfile"), val)
19
+ else
20
+ if Antrapol::ToolRack::RuntimeUtils.on_windows?
21
+ raise Hitcher::Error, "Not ready yet"
22
+ else
23
+ case temp
24
+ when :build_container, :build
25
+ path = File.join(File.dirname(__FILE__),"templates","linux_mac","1.build.sh.erb")
26
+ opts = {}
27
+ opts.merge!(val)
28
+ cmd = build_image(opts[:image_name], opts)
29
+ bind_template(path,File.join(dest_root,"1.build.sh"), { command: cmd })
30
+
31
+
32
+ when :run_container, :run
33
+ path = File.join(File.dirname(__FILE__),"templates","linux_mac","2.run_container.sh.erb")
34
+ opts = {}
35
+ opts.merge!(val)
36
+ cmd = run_container_from_image(opts[:image], opts)
37
+ bind_template(path,File.join(dest_root,"2.run_container.sh"), { command: cmd })
38
+
39
+ when :start_container, :start
40
+ path = File.join(File.dirname(__FILE__),"templates","linux_mac","3.start_container.sh.erb")
41
+ opts = {}
42
+ opts.merge!(val)
43
+ cmd = start_container(opts[:container_name], opts)
44
+ bind_template(path,File.join(dest_root,"3.start_container.sh"), { command: cmd })
45
+
46
+ when :container_prompt, :prompt
47
+ path = File.join(File.dirname(__FILE__),"templates","linux_mac","4.container_prompt.sh.erb")
48
+ opts = {}
49
+ opts.merge!(val)
50
+ cmd = container_prompt(opts[:container_name], opts)
51
+ bind_template(path,File.join(dest_root,"4.container_prompt.sh"), { command: cmd })
52
+
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def bind_template(source,dest, val)
59
+ File.open(source,"r") do |f|
60
+ cont = f.read
61
+ b = binding
62
+ val.each do |k,v|
63
+ b.local_variable_set(k,v)
64
+ end
65
+
66
+ File.open(dest,"w") do |ff|
67
+ ff.write ERB.new(cont).result(b)
68
+ end
69
+ end
70
+ end
71
+
72
+ end # TemplateEngine
73
+ end # Docker
74
+ end # Hitcher
@@ -0,0 +1,6 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ <% dockerfile.each do |d| %>
3
+ <%= d.strip if not d.strip.empty? %>
4
+ <% end %>
5
+
6
+
@@ -0,0 +1,5 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ #!/bin/sh
3
+
4
+ # read Dockerfile and build
5
+ <%= command %>
@@ -0,0 +1,6 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ #!/bin/sh
3
+
4
+ # run container
5
+ <%= command %>
6
+
@@ -0,0 +1,6 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ #!/bin/sh
3
+
4
+ # read start container
5
+ <%= command %>
6
+
@@ -0,0 +1,6 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ #!/bin/sh
3
+
4
+ # drop to prompt of running container
5
+ <%= command %>
6
+
@@ -0,0 +1,6 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ #!/bin/sh
3
+
4
+ # read link to existing running console
5
+ docker
6
+
@@ -0,0 +1,6 @@
1
+ <%#-*- coding: utf-8 -*-%>
2
+ #!/bin/sh
3
+
4
+ # start new instance of docker
5
+ docker run -it --name <%= name %> <%= mount %> <%= port %> <%= image_name %>
6
+
@@ -0,0 +1,129 @@
1
+
2
+ require 'toolrack'
3
+ require_relative "user_prompt"
4
+
5
+ module Hitcher
6
+ module CliOps
7
+ module RunOps
8
+ include Hitcher::UserPrompt
9
+ include Antrapol::ToolRack::ConditionUtils
10
+
11
+ class RunCommandException < StandardError; end
12
+
13
+ #### HERE IS THE FINAL METHOD SIGNATURE
14
+ def run(inst, opts = { })
15
+ raise Exception, "Parameter must be a Hash object" if not opts.is_a?(Hash)
16
+
17
+ opts[:interactive] = inst.interactive_mode || true
18
+ opts[:tty] = inst.tty_mode || true
19
+
20
+ run_container(inst, opts)
21
+ end # run
22
+
23
+ def run_prompt(inst, opts = { })
24
+
25
+ raise Exception, "Parameter must be a Hash object" if not opts.is_a?(Hash)
26
+
27
+ op = { }
28
+ op.merge!(opts)
29
+
30
+ command = opts[:command] || "/bin/bash --login"
31
+ if command == "/bin/bash --login"
32
+ op[:interactive] = true
33
+ op[:tty] = true
34
+ else
35
+ op[:interactive] = inst.interactive_mode
36
+ op[:tty] = inst.tty_mode
37
+ end
38
+
39
+ run_container(inst, op)
40
+
41
+ end # run_prompt
42
+
43
+ def run_new_prompt(inst, opts = { })
44
+ raise Exception, "Parameter must be a Hash object" if not opts.is_a?(Hash)
45
+ #nname = "#{inst.cName}_#{Time.zone.local.strftime("%Y%m%d_%H%M%S_%L%N")}"
46
+ opt = { }
47
+ opt.merge!(opts)
48
+ opt[:new_instance] = true
49
+
50
+ command = opts[:command] || "/bin/bash --login"
51
+ if command == "/bin/bash --login"
52
+ opt[:interactive] = true
53
+ opt[:tty] = true
54
+ else
55
+ opt[:interactive] = inst.interactive_mode
56
+ opt[:tty] = inst.tty_mode
57
+ end
58
+
59
+ run_container(inst, opt)
60
+ end # run_new_prompt
61
+
62
+ #######
63
+ def run_container(inst, opts = { })
64
+
65
+ loop do
66
+
67
+ res, st, id = inst.command_executor.container_exist?(opts)
68
+
69
+ if res
70
+ case st
71
+ when :stopped
72
+ STDOUT.puts "Container '#{inst.cName}' has stopped! Reviving the container..."
73
+ if not_empty?(opts[:command])
74
+ rmech, rval = inst.command_executor.run_command_in_container(opts[:command], opts)
75
+ break
76
+ else
77
+ # assuming the container is launching up something via the CMD or ENTRYPOINT or else the
78
+ # container will die back after startup...
79
+ rcst, rcout, rcerr = inst.command_executor.start_container(opts)
80
+ if not rcst
81
+ raise RunCommandException, "Failed to run container '#{name}'. Error was : #{rcerr.join("\n")}"
82
+ end
83
+ end
84
+ when :running
85
+ STDOUT.puts "Container '#{inst.cName}' is running!"
86
+ # break the loop
87
+ rmech, rval = inst.command_executor.run_command_in_container(opts[:command], opts)
88
+ case rmech
89
+ when :file, :term
90
+ break
91
+ else
92
+ raise RunCommandException, "Run command in container failed with mechanism '#{rmech}'"
93
+ end
94
+ else
95
+ raise RunCommandException, "Container found but neither in running or stopped status"
96
+ end
97
+ else
98
+ # container not exist!
99
+ iest, ieout, ieerr = inst.command_executor.image_exist?(opts)
100
+ if not_empty?(ieout)
101
+ STDOUT.puts "Image '#{inst.image}' exist! Creating container..."
102
+ mech, v = inst.command_executor.create_container(opts)
103
+ case mech
104
+ when :file
105
+ break
106
+ when :term
107
+ break
108
+ else
109
+ raise RunCommandException, "Create container command failed with mechanism '#{mech}'"
110
+ end
111
+ else
112
+ STDOUT.puts "Image '#{inst.image}' does not exist! Proceed to build image..."
113
+ bist, biout, bierr = inst.command_executor.build_image(opts)
114
+ if is_empty?(bierr)
115
+ STDOUT.puts "Image '#{inst.image}' built!"
116
+ # should loop back to run the container
117
+ else
118
+ raise RunCommandException, "Build image command failed. Error was : #{bierr.join("\n")}"
119
+ end
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ end # run_container
126
+
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,22 @@
1
+
2
+ require 'ptools'
3
+
4
+ module Hitcher
5
+ module TerminalUtils
6
+ attr_reader :found
7
+ # since integration is with docker CLI, terminal become essential part of the workflow
8
+ KNOWN = ["gnome-terminal","konsole","cmd.exe","tilix","terminator"]
9
+
10
+ def detect_known_terminal
11
+ found = {}
12
+ KNOWN.each do |t|
13
+ ft = File.which(t)
14
+ if not ft.nil?
15
+ found[t] = ft
16
+ end
17
+ end
18
+ found
19
+ end # detect_known
20
+
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+
2
+ require 'tty/prompt'
3
+ require 'colorize'
4
+
5
+ module Hitcher
6
+ module UserPrompt
7
+
8
+ def tty
9
+ if @tty.nil?
10
+ @tty = TTY::Prompt.new
11
+ end
12
+ @tty
13
+ end
14
+
15
+ def question(str)
16
+ STDOUT.print(str)
17
+ end
18
+
19
+ def notice(str)
20
+ STDOUT.print(str.light_blue)
21
+ end
22
+
23
+ def yes(str)
24
+ STDOUT.puts(str.green)
25
+ end
26
+
27
+ def no(str)
28
+ STDOUT.puts(str.yellow)
29
+ end
30
+
31
+ def fatal(str)
32
+ STDERR.puts(str.red)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Hitcher
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Hitcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Liaw
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-01-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: toolrack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: tlogger
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.25'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.25'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tty-prompt
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tty-command
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: colorize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ptools
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: devops_helper
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: " "
126
+ email:
127
+ - chrisliaw@antrapol.com
128
+ executables:
129
+ - hitcher
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".travis.yml"
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - bin/console
140
+ - bin/setup
141
+ - cspec
142
+ - exe/hitcher
143
+ - hitcher.gemspec
144
+ - lib/hitcher.rb
145
+ - lib/hitcher/command_runner.rb
146
+ - lib/hitcher/config.rb
147
+ - lib/hitcher/dsl.rb
148
+ - lib/hitcher/global.rb
149
+ - lib/hitcher/providers/docker/command_builder.rb
150
+ - lib/hitcher/providers/docker/command_runner.rb
151
+ - lib/hitcher/providers/docker/dsl.rb
152
+ - lib/hitcher/providers/docker/template.rb
153
+ - lib/hitcher/providers/docker/templates/Dockerfile.erb
154
+ - lib/hitcher/providers/docker/templates/linux_mac/1.build.sh.erb
155
+ - lib/hitcher/providers/docker/templates/linux_mac/2.run_container.sh.erb
156
+ - lib/hitcher/providers/docker/templates/linux_mac/3.start_container.sh.erb
157
+ - lib/hitcher/providers/docker/templates/linux_mac/4.container_prompt.sh.erb
158
+ - lib/hitcher/providers/docker/templates/linux_mac/console.sh.erb
159
+ - lib/hitcher/providers/docker/templates/linux_mac/start_new.sh.erb
160
+ - lib/hitcher/run_ops.rb
161
+ - lib/hitcher/terminal_utils.rb
162
+ - lib/hitcher/user_prompt.rb
163
+ - lib/hitcher/version.rb
164
+ homepage: ''
165
+ licenses:
166
+ - MIT
167
+ metadata: {}
168
+ post_install_message:
169
+ rdoc_options: []
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: 2.3.0
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ requirements: []
183
+ rubygems_version: 3.1.2
184
+ signing_key:
185
+ specification_version: 4
186
+ summary: ''
187
+ test_files: []