dockerun 0.3.6 → 0.4.1

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -11
  3. data/Rakefile +0 -2
  4. data/Rakefile.bak +8 -0
  5. data/dockerspec.sample +107 -0
  6. data/{dockerun.gemspec → dockerun.gemspec.bak} +20 -22
  7. data/exe/dockerun +15 -115
  8. data/lib/dockerun/cli/command.rb +140 -0
  9. data/lib/dockerun/cli/command_factory.rb +316 -0
  10. data/lib/dockerun/cli/command_result.rb +67 -0
  11. data/lib/dockerun/cli/delete_container.rb +59 -0
  12. data/lib/dockerun/cli/delete_image.rb +103 -0
  13. data/lib/dockerun/cli/run.rb +40 -0
  14. data/lib/dockerun/cli/user_info.rb +39 -0
  15. data/lib/dockerun/cli_engine.rb +122 -0
  16. data/lib/dockerun/config.rb +50 -85
  17. data/lib/dockerun/context/rubygems.rb +142 -0
  18. data/lib/dockerun/dfile.rb +204 -0
  19. data/lib/dockerun/docker_cli.rb +124 -0
  20. data/lib/dockerun/dsl.rb +342 -0
  21. data/lib/dockerun/version.rb +1 -1
  22. data/lib/dockerun.rb +32 -24
  23. data/sig/dockerun.rbs +4 -0
  24. metadata +62 -73
  25. data/.release_history.yml +0 -56
  26. data/Dockerfile.dockerun +0 -38
  27. data/Gemfile +0 -15
  28. data/Gemfile.lock +0 -94
  29. data/bin/console +0 -15
  30. data/bin/setup +0 -8
  31. data/lib/dockerun/bundler_helper.rb +0 -25
  32. data/lib/dockerun/cli_prompt.rb +0 -18
  33. data/lib/dockerun/command/dockerun.rb +0 -30
  34. data/lib/dockerun/command/init.rb +0 -79
  35. data/lib/dockerun/command/remove_container.rb +0 -99
  36. data/lib/dockerun/command/reset_image.rb +0 -107
  37. data/lib/dockerun/command/run.rb +0 -226
  38. data/lib/dockerun/command/run_new_container.rb +0 -94
  39. data/lib/dockerun/command/run_new_image.rb +0 -89
  40. data/lib/dockerun/command/stop_container.rb +0 -90
  41. data/lib/dockerun/docker_command_factory_helper.rb +0 -19
  42. data/lib/dockerun/docker_container_helper.rb +0 -213
  43. data/lib/dockerun/docker_image_helper.rb +0 -381
  44. data/lib/dockerun/template/general_template_writer.rb +0 -14
  45. data/lib/dockerun/template/jruby_template_writer.rb +0 -24
  46. data/lib/dockerun/template/template_engine.rb +0 -27
  47. data/lib/dockerun/template/template_writer.rb +0 -102
  48. data/lib/dockerun/user_info.rb +0 -37
  49. data/template/Dockerfile_general.erb +0 -41
  50. data/template/setup_ruby_devenv.rb.erb +0 -22
@@ -0,0 +1,124 @@
1
+
2
+ require 'tty/which'
3
+
4
+ require_relative 'cli/command_factory'
5
+
6
+ module Dockerun
7
+
8
+ # Generate docker cli string
9
+ class DockerCli
10
+ include TR::CondUtils
11
+
12
+ def self.docker_exe
13
+ exe = TTY::Which.which("docker")
14
+ raise Error, "Docker executable cannot be found. Please make sure it is installed and in the PATH" if is_empty?(exe)
15
+ exe
16
+ end
17
+
18
+ def initialize(config, dfile)
19
+ @_config = config
20
+ @_dfile = dfile
21
+ end
22
+
23
+ def set_container_name(val)
24
+ @name = val
25
+ end
26
+ def container_name
27
+ @name.nil? ? "" : @name
28
+ end
29
+ def is_container_name_given?
30
+ not_empty?(container_name)
31
+ end
32
+ def generated_container_name
33
+ if @_gen_cont_name.nil?
34
+ @_gen_cont_name = "#{File.basename(Dir.getwd)}_cont_name"
35
+ end
36
+ @_gen_cont_name
37
+ end
38
+
39
+ def keep(bool = true)
40
+ @keep = bool
41
+ end
42
+ def keep_container?
43
+ @keep.nil? ? true : @keep
44
+ end
45
+
46
+ def interactive(bool = true)
47
+ @interactive = bool
48
+ end
49
+ def is_interactive?
50
+ @interactive.nil? ? false : true
51
+ end
52
+
53
+ def mount(*mnt)
54
+ mnt.each do |mm|
55
+ mm.each do |on_host, on_docker|
56
+ case on_host
57
+ when :current_dir
58
+ hostPath = Dir.getwd
59
+ else
60
+ hostPath = File.expand_path(on_host)
61
+ end
62
+
63
+ req_mounts[hostPath] = on_docker
64
+
65
+ end
66
+ end
67
+ end
68
+ def mounts
69
+ req_mounts
70
+ end
71
+
72
+ def port(*ports)
73
+ ports.each do |port|
74
+ raise Error, "Hash of hostPort => dockerPort is required" if not port.is_a?(Hash)
75
+ port.each do |hostPort, dockerPort|
76
+ expose_ports[hostPort] = dockerPort
77
+ end
78
+ end
79
+ end
80
+ def expose_ports
81
+ if @_ports.nil?
82
+ @_ports = {}
83
+ end
84
+ @_ports
85
+ end
86
+ def has_exposed_ports?
87
+ expose_ports.size > 0
88
+ end
89
+
90
+ def listener(&block)
91
+ @listener = block
92
+ end
93
+
94
+ def run_in_docker(cmd)
95
+ @cmdToBeRun = cmd
96
+ end
97
+ def command_to_be_run
98
+ @cmdToBeRun
99
+ end
100
+
101
+ def trigger_listener(evt, *args, &block)
102
+ if not @listener.nil?
103
+ args << { docker_cli: self }
104
+ @listener.call(evt, *args, &block)
105
+ end
106
+ end
107
+
108
+ private
109
+ def method_missing(mtd, *args, &block)
110
+ if @_config.respond_to?(mtd)
111
+ @_config.send(mtd, *args, &block)
112
+ end
113
+ end
114
+
115
+ def req_mounts
116
+ if @_req_mounts.nil?
117
+ @_req_mounts = {}
118
+ end
119
+ @_req_mounts
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,342 @@
1
+
2
+ require_relative 'config'
3
+ require_relative 'dfile'
4
+ require_relative 'docker_cli'
5
+
6
+ require_relative 'cli/command_factory'
7
+
8
+ module Dockerun
9
+ module DSL
10
+ include TR::CondUtils
11
+
12
+ def set_exec_root(root)
13
+ @_exec_root = root
14
+ end
15
+ def exec_root
16
+ @_exec_root
17
+ end
18
+
19
+ def config(&block)
20
+ _config.instance_eval(&block)
21
+ end
22
+
23
+ def set_dry_run_mode(bool = true, prompt = false)
24
+ _config.dry_run(bool, prompt)
25
+ end
26
+
27
+ # Main DSL for dockerfile related configurations
28
+ def from(base_image, &block)
29
+ _dfile.base_image = base_image
30
+ _dfile.instance_eval(&block)
31
+ end
32
+
33
+ # Additional dockerfile configurations for example
34
+ # if user did not specify the image name, better generate
35
+ # by system so that it can be traced for subsequent functions
36
+ # later such as delete image
37
+ def dockerfile_patch(&block)
38
+ _file.instance_eval(&block)
39
+ end
40
+
41
+ # Main DSL for docker cli
42
+ def up(&block)
43
+ _docker_cli.instance_eval(&block)
44
+ end
45
+
46
+ # Trigger point to start the ball rolling!
47
+ def go
48
+
49
+ # Link context with Dockerfile and docker cli
50
+ if not_empty?(_config.active_context)
51
+ self.listener do |ops, *val|
52
+ _config.active_context.call(ops, *val)
53
+ end
54
+
55
+ _dfile.listener do |ops, *val|
56
+ _config.active_context.call(ops, *val)
57
+ end
58
+
59
+ _docker_cli.listener do |ops, *val|
60
+ _config.active_context.call(ops, *val)
61
+ end
62
+ end
63
+
64
+ # give chance to context to verify the integrity of the
65
+ # workspace before proceed
66
+ trigger_listener(:dsl_before_go, self)
67
+
68
+ # check if image exist?
69
+ if not image_exist?
70
+ logger.debug "Image doesn't exist... proceed to build the image"
71
+ # if not exist, build the image giving the name
72
+ st, res = build_image
73
+ if st
74
+ trigger_listener(:dsl_image_built, self)
75
+ #puts " Image '#{image_name}' built successfully"
76
+ else
77
+ trigger_listener(:dsl_image_building_failed, self)
78
+ raise Error, " Image '#{image_name}' failed to be built. Error was : #{res.err_lines.join("\n")}"
79
+ end
80
+ else
81
+ logger.debug "Image exist... skipped image building..."
82
+ end
83
+
84
+ # check if container exist?
85
+ if container_exist?
86
+ trigger_listener(:dsl_before_start_container, self)
87
+ logger.debug "Container exist... Starting container..."
88
+ # container exist, start the container
89
+ start_container
90
+
91
+ trigger_listener(:dsl_before_attach_container, self)
92
+ logger.debug "Container started... attaching container..."
93
+ # attach to container
94
+ attach_container
95
+ trigger_listener(:dsl_after_attach_container, self)
96
+ else
97
+ trigger_listener(:dsl_before_run_container, self)
98
+ logger.debug "Container does not exist. Creating new container..."
99
+ # Container does not exist, run the container
100
+ run_container
101
+ end
102
+
103
+ end
104
+
105
+
106
+ def image_name
107
+ if _dfile.is_image_name_given?
108
+ _dfile.image_name
109
+ else
110
+ _dfile.generated_image_name
111
+ end
112
+ end
113
+
114
+ def container_name
115
+ if _docker_cli.is_container_name_given?
116
+ _docker_cli.container_name
117
+ else
118
+ _docker_cli.generated_container_name
119
+ end
120
+ end
121
+
122
+
123
+ def listener(&block)
124
+ @listener = block
125
+ end
126
+
127
+
128
+ private
129
+ def _config
130
+ if @_config.nil?
131
+ @_config = Config.new
132
+ end
133
+ @_config
134
+ end
135
+
136
+ def _dfile
137
+ if @_dfile.nil?
138
+ @_dfile = Dfile.new(_config)
139
+ end
140
+ @_dfile
141
+ end
142
+
143
+ def _docker_cli
144
+ if @_docker_cli.nil?
145
+ @_docker_cli = DockerCli.new(_config, _dfile)
146
+ end
147
+ @_docker_cli
148
+ end
149
+
150
+ def docker_cf
151
+ if @_docker_cf.nil?
152
+ @_docker_cf = Dockerun::Cli::CommandFactory.new
153
+ end
154
+ @_docker_cf
155
+ end
156
+
157
+ def trigger_listener(evt, *args, &block)
158
+ if not @listener.nil?
159
+ @listener.call(evt, *args, &block)
160
+ end
161
+ end
162
+
163
+ # flag to bridge between script and eval mode
164
+ def mark_go_done
165
+ @_go_done = true
166
+ end
167
+ def is_go_done?
168
+ @_go_done.nil? ? false : @_go_done
169
+ end
170
+ # end flag
171
+
172
+ def image_exist?
173
+ fact = docker_cf.find_image(image_name)
174
+ if _config.is_dry_run?
175
+ dry_run_puts "Find Image : #{fact.to_s}"
176
+ dry_run_puts "Find Image : Returning false to allow image build"
177
+ false
178
+ else
179
+ res = docker_cf.find_image(image_name).run
180
+ res.success? and not_empty?(res.output_lines)
181
+ end
182
+ end
183
+
184
+ def build_image
185
+ dfile = _dfile.generate
186
+ dfileName = File.join(exec_root,"Dockerfile-#{SecureRandom.hex(4)}")
187
+ File.open(dfileName,"w") do |f|
188
+ f.write dfile
189
+ end
190
+
191
+ fact = docker_cf.build_image(image_name, dockerfile: dfileName, working_dir: exec_root)
192
+
193
+ if _config.is_gen_docker_runscript?
194
+ out = File.join(exec_root,"1.build-image.sh")
195
+ if (not File.exist?(out)) or _config.is_overwrite_docker_runscript?
196
+ File.open(out, "w") do |f|
197
+ f.puts "#!/bin/sh"
198
+ f.puts fact.to_s
199
+ end
200
+ end
201
+ end
202
+
203
+ if _config.is_dry_run?
204
+ dry_run_puts "Build Image : #{fact.to_s}"
205
+ dry_run_puts "Build Image : Returning true to proceed to next phase."
206
+ dry_run_puts "Generated dockerfile '#{dfileName}' shall be remained in project directory."
207
+ [true, nil]
208
+ else
209
+ res = fact.run(true)
210
+ if res.success?
211
+ FileUtils.rm(dFileName) if not _dfile.keep_dockerfile?
212
+ [true, res]
213
+ else
214
+ [false, res]
215
+ end
216
+ end
217
+ end
218
+
219
+
220
+ def container_exist?
221
+ if _docker_cli.keep_container?
222
+ fact = docker_cf.find_from_all_container(container_name)
223
+ if _config.is_dry_run?
224
+ dry_run_puts "Is container exist? : #{fact.to_s}"
225
+ dry_run_puts "Returning false to allow container build"
226
+ false
227
+ else
228
+ res = fact.run
229
+ res.success? and not_empty?(res.output_lines)
230
+ end
231
+ else
232
+ remove_container
233
+ false
234
+ end
235
+ end
236
+
237
+ def remove_container
238
+ fact = docker_cf.find_from_all_container(container_name)
239
+ res = fact.run
240
+ if res.success?
241
+ res.output_lines.each do |ci|
242
+ docker_cf.stop_container(ci).run
243
+ r = docker_cf.delete_container(ci).run
244
+ logger.debug "Delete container : #{r.success?} / #{r.success? ? r.output_lines.join("\n") : r.err_lines.join("\n")}"
245
+ end
246
+ else
247
+ logger.debug "Failed to find all container by name '#{container_name}'"
248
+ end
249
+ end
250
+
251
+ def start_container
252
+ fact = docker_cf.find_running_container(container_name)
253
+ fact2 = docker_cf.start_container(container_name)
254
+
255
+ if _config.is_gen_docker_runscript?
256
+ out = File.join(exec_root,"3.start-container.sh")
257
+ if (not File.exist?(out)) or _config.is_overwrite_docker_runscript?
258
+ File.open(out, "w") do |f|
259
+ f.puts "#!/bin/sh"
260
+ f.puts fact.to_s
261
+ end
262
+ end
263
+ end
264
+
265
+ if _config.is_dry_run?
266
+ dry_run_puts "Find running container : #{fact.to_s}"
267
+ dry_run_puts "Start container : #{fact2.to_s}"
268
+ [true, nil]
269
+ else
270
+ res = fact.run
271
+ if res.success? and not_empty?(res.output_lines)
272
+ # already running so ignore
273
+ [true, res]
274
+ else
275
+ res2 = fact2.run
276
+ [res2.success?, res2]
277
+ end
278
+ end
279
+ end
280
+
281
+ def attach_container
282
+ fact = docker_cf.attach_container(container_name)
283
+
284
+ if _config.is_gen_docker_runscript?
285
+ out = File.join(exec_root,"4.attach-container.sh")
286
+ if (not File.exist?(out)) or _config.is_overwrite_docker_runscript?
287
+ File.open(out, "w") do |f|
288
+ f.puts "#!/bin/sh"
289
+ f.puts fact.to_s
290
+ end
291
+ end
292
+ end
293
+
294
+ if _config.is_dry_run?
295
+ dry_run_puts "Attach container : #{fact.to_s}"
296
+ else
297
+ fact.run
298
+ end
299
+
300
+ end
301
+
302
+ def run_container
303
+
304
+ params = { interactive: _docker_cli.is_interactive?, tty: _docker_cli.is_interactive?, del: !_docker_cli.keep_container?, container_name: container_name, match_user: _config.set_current_user?, command: _docker_cli.command_to_be_run, mounts: _docker_cli.mounts }
305
+
306
+ params[:ports] = {} if params[:ports].nil?
307
+ params[:ports].merge!(_docker_cli.expose_ports) if _docker_cli.has_exposed_ports?
308
+
309
+ rparams = _docker_cli.trigger_listener(:docker_cli_construct_command, params)
310
+ rparams = params if is_empty?(rparams)
311
+
312
+ fact = docker_cf.create_container_from_image(image_name, rparams)
313
+
314
+ if _config.is_gen_docker_runscript?
315
+ out = File.join(exec_root,"2.create-container.sh")
316
+ if (not File.exist?(out)) or _config.is_overwrite_docker_runscript?
317
+ File.open(out, "w") do |f|
318
+ f.puts "#!/bin/sh"
319
+ f.puts fact.to_s
320
+ end
321
+ end
322
+ end
323
+
324
+ if _config.is_dry_run?
325
+ dry_run_puts "Run container : #{fact.to_s}"
326
+ else
327
+ fact.run
328
+ end
329
+ end
330
+
331
+
332
+ def dry_run_puts(msg)
333
+ puts "[DryRun] #{msg}" if _config.is_dry_run_prompt?
334
+ end
335
+
336
+
337
+ def logger
338
+ Dockerun.logger(:dockerun_dsl)
339
+ end
340
+
341
+ end
342
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dockerun
4
- VERSION = "0.3.6"
4
+ VERSION = "0.4.1"
5
5
  end
data/lib/dockerun.rb CHANGED
@@ -3,41 +3,49 @@
3
3
  require 'toolrack'
4
4
  require 'teLogger'
5
5
 
6
- require 'colorize'
7
- require 'tty/prompt'
6
+ require 'tty/command'
7
+ require 'tty/which'
8
8
 
9
9
  require_relative "dockerun/version"
10
+ require_relative 'dockerun/dsl'
10
11
 
11
- require_relative 'dockerun/command/dockerun'
12
- require_relative 'dockerun/command/init'
13
- require_relative 'dockerun/command/run'
14
- require_relative 'dockerun/command/reset_image'
15
- require_relative 'dockerun/command/run_new_container'
16
- require_relative 'dockerun/command/remove_container'
17
- require_relative 'dockerun/command/run_new_image'
18
- require_relative 'dockerun/command/stop_container'
19
-
20
- require_relative 'dockerun/template/template_writer'
21
- require_relative 'dockerun/template/template_engine'
12
+ require_relative 'dockerun/cli_engine'
22
13
 
23
14
  module Dockerun
15
+ include TR::CondUtils
16
+
24
17
  class Error < StandardError; end
18
+ class InsufficientParameter < StandardError; end
25
19
  # Your code goes here...
26
20
 
27
- def self.udebug(msg)
28
- logger.tdebug(:dockerun, msg) if is_user_debug_on?
29
- end
30
-
31
- def self.logger
21
+ def self.logger(tag = nil, &block)
32
22
  if @_logger.nil?
33
- @_logger = TeLogger::Tlogger.new
23
+ drLogout = ENV["DR_LOGOUT"]
24
+ if is_empty?(drLogout)
25
+ @_logger = TeLogger::Tlogger.new('dockerun.log',5, 5*1024*1024)
26
+ else
27
+ @_logger = TeLogger::Tlogger.new(drLogout, 5, 5*1024*1024)
28
+ end
34
29
  end
35
- @_logger
36
- end
37
30
 
38
- def self.is_user_debug_on?
39
- val = ENV["DOCKERUN_DEBUG"]
40
- (not val.nil? and val == "true")
31
+ if block
32
+ if not_empty?(tag)
33
+ @_logger.with_tag(tag, &block)
34
+ else
35
+ @_logger.with_tag(@_logger.tag, &block)
36
+ end
37
+ else
38
+ if is_empty?(tag)
39
+ @_logger.tag = :dockerun
40
+ @_logger
41
+ else
42
+ # no block but tag is given? hmm
43
+ @_logger.tag = tag
44
+ @_logger
45
+ end
46
+ end
41
47
  end
42
48
 
49
+
50
+
43
51
  end
data/sig/dockerun.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Dockerun
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end