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,122 @@
1
+
2
+ require 'tty/prompt'
3
+ require_relative 'cli/run'
4
+ require_relative 'cli/delete_container'
5
+ require_relative 'cli/delete_image'
6
+
7
+ module Dockerun
8
+ class CliEngine
9
+ include TR::ArgUtils
10
+
11
+ arg_spec do
12
+ opt "i", "Initialize sample dockerspec at given directory as next argument" do |v|
13
+ init(v)
14
+ end
15
+ opt_alias "i", "init"
16
+
17
+ opt "r", "Run the dockerspec at given directory as next argument" do |v|
18
+ run(v)
19
+ end
20
+ opt_alias "r","run"
21
+
22
+ opt "dc", "Delete container at given directory as next argument" do |v|
23
+ delete_container(v)
24
+ end
25
+
26
+ opt "di", "Delete image and its associated container(s) at given directory as next argument" do |v|
27
+ delete_image(v)
28
+ end
29
+
30
+ opt 'clean', "Clean generated Dockerfile and temporary files at given directory as next argument" do |v|
31
+ clean_env(v)
32
+ end
33
+
34
+ opt 'help', "Command help" do
35
+ print_help
36
+ end
37
+
38
+ end
39
+
40
+ def print_help
41
+ pmt = self.class.pmt
42
+ pmt.puts ""
43
+ pmt.puts " Dockerun version #{Dockerun::VERSION}".magenta
44
+ pmt.puts ""
45
+ pmt.puts " Supported options : "
46
+ self.class.arg_options.each do |key, val|
47
+ pmt.puts " #{key}\t\t#{val[:desc]}"
48
+ end
49
+ pmt.puts ""
50
+ end
51
+
52
+ def self.select_spec(root)
53
+ raise InsufficientParameter, "Given path cannot be empty or nil" if is_empty?(root)
54
+
55
+ #sel = Dir.entries(Dir.getwd).sort
56
+ sel = Dir.entries(root).sort
57
+ default = sel.select { |e| (e =~ /^dockerspec/) != nil }
58
+ selSpec = pmt.select(" Please select the dockerspec to proceed : ", filter: true, default: default.first) do |m|
59
+ sel.each do |s|
60
+ next if sel == "." or sel == ".." or File.directory?(s)
61
+ m.choice s, File.expand_path(s)
62
+ end
63
+ end
64
+
65
+ selSpec
66
+ end
67
+
68
+
69
+ def init(root)
70
+ raise InsufficientParameter, "Given path cannot be empty or nil" if is_empty?(root)
71
+
72
+ root = File.expand_path(root)
73
+ template = File.join(File.dirname(__FILE__),"..","..","dockerspec.sample")
74
+ if File.exist?(template)
75
+ #FileUtils.cp template, File.join(Dir.getwd, "dockerspec.sample")
76
+ FileUtils.cp template, File.join(root, "dockerspec.sample")
77
+ end
78
+ end
79
+
80
+ def run(root)
81
+ raise InsufficientParameter, "Given path cannot be empty or nil" if is_empty?(root)
82
+
83
+ root = File.expand_path(root)
84
+ r = Dockerun::Cli::Run.new
85
+ r.start(root)
86
+ end
87
+
88
+ def delete_container(root)
89
+ raise InsufficientParameter, "Given path cannot be empty or nil" if is_empty?(root)
90
+ root = File.expand_path(root)
91
+ d = Dockerun::Cli::DeleteContainer.new
92
+ d.start(root)
93
+ end
94
+
95
+ def delete_image(root)
96
+ raise InsufficientParameter, "Given path cannot be empty or nil" if is_empty?(root)
97
+ root = File.expand_path(root)
98
+ d = Dockerun::Cli::DeleteImage.new
99
+ d.start(root)
100
+ end
101
+
102
+ def clean_env(root)
103
+ raise InsufficientParameter, "Given path cannot be empty or nil" if is_empty?(root)
104
+ root = File.expand_path(root)
105
+
106
+ Dir.glob(File.join(root,"Dockerfile-*")).each do |f|
107
+ FileUtils.rm(f)
108
+ end
109
+ pa = File.join(root,"script_for_gem.sh")
110
+ FileUtils.rm(pa) if File.exist?(pa)
111
+ self.class.pmt.puts " Generated Dockerfile-* and script_for_gem.sh is deleted at '#{root}'".green
112
+ end
113
+
114
+ def self.pmt
115
+ if @_pmt.nil?
116
+ @_pmt = TTY::Prompt.new
117
+ end
118
+ @_pmt
119
+ end
120
+
121
+ end
122
+ end
@@ -1,115 +1,80 @@
1
1
 
2
- require 'yaml'
2
+ require_relative 'context/rubygems'
3
3
 
4
4
  module Dockerun
5
5
  class Config
6
6
  include TR::CondUtils
7
7
 
8
- FILENAME = ".dockerun".freeze
9
-
10
- def self.from_storage
11
- path = File.join(Dir.getwd, FILENAME)
12
- if File.exist?(path)
13
- #cont = nil
14
- #File.open(path,"r") do |f|
15
- # cont = f.read
16
- #end
17
-
18
- #Config.new(YAML.load(cont), true)
19
- Config.new(YAML.unsafe_load_file(path), true)
20
- else
21
- Config.new({}, false)
22
- end
8
+ def set_workdir(path)
9
+ @workdir = path
23
10
  end
24
-
25
- def self.remove
26
- path = File.join(Dir.getwd, FILENAME)
27
- FileUtils.rm(path) if File.exist?(path)
28
- end
29
-
30
- def initialize(configHash = { }, configFileAvail = false)
31
- @config = configHash
32
- @images = @config[:images] || { }
33
- @confFileAvail = configFileAvail
34
- #@images = { } if @images.nil?
11
+ def workdir
12
+ if @workdir.nil?
13
+ @workdir = File.join("/opt",File.basename(Dir.getwd))
14
+ end
15
+ @workdir
35
16
  end
36
-
37
- def isConfigFileAvail?
38
- @confFileAvail
17
+ def is_workdir_given?
18
+ not_empty?(@workdir)
39
19
  end
40
20
 
41
- def image_names
42
- @images.keys
43
- end
44
21
 
45
- def add_image(name)
46
- @images[name] = { } if not_empty?(name) and not @images.keys.include?(name)
22
+ def set_platform(val)
23
+ @platform = val
47
24
  end
48
-
49
- def remove_image(name)
50
- @images.delete(name)
25
+ def platform
26
+ if is_empty?(@platform)
27
+ # wild guess
28
+ @platform = :debian
29
+ end
30
+ @platform
51
31
  end
52
32
 
53
- def container_names(imageName)
54
- @images[imageName].keys
55
- end
56
33
 
57
- def container_configs(imageName, name)
58
- @images[imageName].nil? ? {} : @images[imageName][name].nil? ? {} : @images[imageName][name]
34
+ def set_current_user(bool = true)
35
+ @set_current_user = bool
59
36
  end
60
-
61
- def add_container(imageName, name)
62
- @images[imageName] = { } if @images[imageName].nil?
63
- @images[imageName][name] = {} if @images[imageName][name].nil?
37
+ def set_current_user?
38
+ @set_current_user.nil? ? true : @set_current_user
64
39
  end
65
40
 
66
- def remove_container(imageName, name)
67
- if not @images[imageName].nil?
68
- @images[imageName].delete(name)
69
- end
70
- end
71
41
 
72
- def add_mount_to_container(imageName, container, mount)
73
- add_container(imageName, container)
74
- @images[imageName][container][:mount] = [] if @images[imageName][container][:mount].nil?
75
- case mount.class
76
- when Array
77
- @images[imageName][container][:mount]concat(mount)
42
+ def activate_context(ctx, &block)
43
+ case ctx
44
+ when :rubygems
45
+ @active_context = Context::Rubygems.new(self)
78
46
  else
79
- @images[imageName][container][:mount] << mount
47
+ raise Error, "Unknown context '#{ctx}'"
80
48
  end
49
+ @active_context.instance_eval(&block)
81
50
  end
82
-
83
- def container_mount_points(imageName, container)
84
- res = @images[imageName][container]
85
- if is_empty?(res) or is_empty?(res[:mount])
86
- []
87
- else
88
- res[:mount]
89
- end
51
+ def active_context
52
+ @active_context
90
53
  end
91
54
 
92
- def add_port_mapping_to_container(imageName, container, port_mapping)
93
- add_container(imageName, container)
94
- @images[imageName][container][:port_mapping] = [] if @images[imageName][container][:port_mapping].nil?
95
- case mount.class
96
- when Array
97
- @images[imageName][container][:port_mapping]concat(port_mapping)
98
- else
99
- @images[imageName][container][:port_mapping] << port_mapping
100
- end
55
+
56
+ def gen_docker_runscript(bool = true, overwrite = false)
57
+ @_gen_docker_runscript = bool
58
+ @_overwrite_docker_runscript = overwrite
101
59
  end
60
+ def is_gen_docker_runscript?
61
+ @_gen_docker_runscript.nil? ? false : @_gen_docker_runscript
62
+ end
63
+ def is_overwrite_docker_runscript?
64
+ @_overwrite_docker_runscript.nil? ? false : @_overwrite_docker_runscript
65
+ end
66
+
102
67
 
103
-
104
- def to_storage
105
- res = { images: @images }
106
-
107
- path = File.join(Dir.getwd, FILENAME)
108
- File.open(path,"w") do |f|
109
- f.write YAML.dump(res)
110
- end
68
+ def dry_run(bool = true, prompt = true)
69
+ @dry_run = bool
70
+ @dry_run_prompt = prompt
71
+ end
72
+ def is_dry_run?
73
+ @dry_run.nil? ? false : @dry_run
74
+ end
75
+ def is_dry_run_prompt?
76
+ @dry_run_prompt.nil? ? false : @dry_run_prompt
111
77
  end
112
- alias_method :save, :to_storage
113
78
 
114
79
  end
115
80
  end
@@ -0,0 +1,142 @@
1
+
2
+ require 'bundler'
3
+
4
+ require_relative '../cli/command_factory'
5
+
6
+ module Dockerun
7
+ module Context
8
+
9
+ class Rubygems
10
+ include TR::CondUtils
11
+
12
+ def self.is_rubygems?(path)
13
+ fs = Dir.entries(path)
14
+ gs = fs.select { |s| s =~ /.gemspec/ }
15
+ fs.include?("Gemfile") and fs.include?("Gemfile.lock") and not_empty?(gs)
16
+ end
17
+
18
+ def initialize(conf)
19
+ @_config = conf
20
+ end
21
+
22
+ def call(ops, *val)
23
+ case ops
24
+ when :dsl_before_go
25
+ check_integrity
26
+
27
+ when :dsl_image_built
28
+ FileUtils.rm(gen_file_name) if not is_keep_gen_file?
29
+
30
+ when :dockerfile_before_workdir
31
+ init_script_in_dockerfile
32
+
33
+ when :docker_cli_construct_command
34
+ para = val.first
35
+ if not_empty?(dev_gems_mounts)
36
+ para[:mounts] = {} if para[:mounts].nil?
37
+ para[:mounts].merge!(dev_gems_mounts)
38
+ end
39
+ para
40
+
41
+ end
42
+ end
43
+
44
+ def check_integrity
45
+ puts `cd #{Dir.getwd} && bundle`
46
+ end
47
+
48
+ def keep_gen_file(bool = true)
49
+ @_keep_gen_file = bool
50
+ end
51
+ def is_keep_gen_file?
52
+ @_keep_gen_file.nil? ? true : @_keep_gen_file
53
+ end
54
+
55
+ def gen_file_name
56
+ "script_for_gem.sh"
57
+ end
58
+
59
+ # shell script to set the env
60
+ def init_script_in_dockerfile
61
+ cmd = ["#!/usr/bin/env ruby"]
62
+ if is_duplicate_dev_env?
63
+ if has_dev_gems?
64
+ find_local_dev_gems.each do |name, path|
65
+ if @_config.is_workdir_given?
66
+ root = File.dirname(@_config.workdir)
67
+ else
68
+ root = "/opt"
69
+ end
70
+
71
+ dockerPath = File.join(root, name)
72
+ cmd << "`bundle config --global local.#{name} #{dockerPath}`"
73
+ dev_gems_mounts[path] = dockerPath
74
+ end
75
+ end
76
+ end
77
+
78
+ cmd << "`echo 'alias be=\"bundle exec\"' >> ~/.bashrc`"
79
+
80
+ initScript = cmd.join("\n")
81
+ File.open(gen_file_name,"w") do |f|
82
+ f.write initScript
83
+ end
84
+ `chmod +x script_for_gem.sh`
85
+
86
+ cont = []
87
+ cont << "COPY script_for_gem.sh /tmp"
88
+ cont << "RUN /tmp/script_for_gem.sh"
89
+ cont.join("\n")
90
+ end
91
+
92
+ def duplicate_dev_env(bool = true)
93
+ @dup_dev_env = bool
94
+ end
95
+ def is_duplicate_dev_env?
96
+ @dup_dev_env.nil? ? true : @dup_dev_env
97
+ end
98
+
99
+
100
+ def dev_gems_mounts
101
+ if @_dev_gems_mounts.nil?
102
+ @_dev_gems_mounts = {}
103
+ end
104
+ @_dev_gems_mounts
105
+ end
106
+
107
+
108
+ def has_dev_gems?
109
+ not find_local_dev_gems.empty?
110
+ end
111
+
112
+ def find_local_dev_gems
113
+
114
+ if @_dev_gems.nil?
115
+
116
+ @_dev_gems = {}
117
+ Bundler.load.dependencies.each do |d|
118
+ if not d.source.nil?
119
+ src = d.source
120
+ if src.path.to_s != "."
121
+ @_dev_gems[d.name] = src.path.expand_path.to_s
122
+ end
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ @_dev_gems
129
+
130
+ end # find_local_dev_gem
131
+
132
+ def docker_cli
133
+ if @_docker_cli.nil?
134
+ @_docker_cli = Dockerun::Cli::CommandFactory.new
135
+ end
136
+ @_docker_cli
137
+ end
138
+
139
+ end # class RubygemsEngine
140
+
141
+ end
142
+ end
@@ -0,0 +1,204 @@
1
+
2
+ require_relative 'cli/user_info'
3
+
4
+ module Dockerun
5
+
6
+ # Generate Dockerfile
7
+ class Dfile
8
+ include TR::CondUtils
9
+
10
+ def initialize(config)
11
+ @_config = config
12
+ end
13
+
14
+ # DSL
15
+ def set_image_name(val)
16
+ @image_name = val
17
+ end
18
+ def image_name
19
+ @image_name
20
+ end
21
+ def is_image_name_given?
22
+ not_empty?(@image_name)
23
+ end
24
+ def generated_image_name
25
+ if @_genImgName.nil?
26
+ @_genImgName = "#{File.basename(Dir.getwd.gsub(" ","-"))}_docker_image"
27
+ end
28
+ @_genImgName
29
+ end
30
+
31
+ # DSL
32
+ def output=(val)
33
+ @output = val
34
+ end
35
+ def output_filename
36
+ @output
37
+ end
38
+
39
+ def install(*app)
40
+ @installApp = app
41
+ end
42
+ def required_app
43
+ @installApp.nil? ? [] : @installApp
44
+ end
45
+
46
+ def set_command(*val)
47
+ @cmd = val
48
+ end
49
+ def command
50
+ @cmd
51
+ end
52
+ def default_command
53
+ ["/bin/bash"]
54
+ end
55
+ def is_command_given?
56
+ not_empty?(command)
57
+ end
58
+
59
+ def base_image=(img)
60
+ @base_image = img
61
+ end
62
+ def base_image
63
+ @base_image
64
+ end
65
+
66
+ def set_workdir(bool = true)
67
+ @set_workdir = bool
68
+ end
69
+ def is_set_workdir?
70
+ @set_workdir.nil? ? true : @set_workdir
71
+ end
72
+
73
+ def skip_update(bool = false)
74
+ @skip_update = bool
75
+ end
76
+ def skip_update?
77
+ @skip_update.nil? ? false : @skip_update
78
+ end
79
+
80
+ def skip_upgrade(bool = false)
81
+ @skip_upgrade = bool
82
+ end
83
+ def skip_upgrade?
84
+ @skip_upgrade.nil? ? false : @skip_upgrade
85
+ end
86
+
87
+ def keep_dockerfile(bool = true)
88
+ @keep_dockerfile = bool
89
+ end
90
+ def keep_dockerfile?
91
+ @keep_dockerfile.nil? ? true : @keep_dockerfile
92
+ end
93
+
94
+
95
+ # for context to install listener
96
+ def listener(&block)
97
+ @listener = block
98
+ end
99
+
100
+ def generate(opts = {})
101
+
102
+ opts = {} if opts.nil?
103
+
104
+ config = @_config
105
+ raise Error, "Config is required" if config.nil?
106
+
107
+ cont = []
108
+ cont << "FROM #{base_image}"
109
+ cont << ""
110
+
111
+ pkgMgr = pkg_mgr(config)
112
+
113
+ if not skip_update? or not skip_upgrade?
114
+ st = []
115
+ st << "#{pkgMgr} update" if not skip_update?
116
+ st << "#{pkgMgr} -y upgrade" if not skip_upgrade?
117
+ cont << "RUN #{st.join(" && ")}" if not_empty?(st)
118
+ cont << ""
119
+ end
120
+
121
+ cb = trigger_listener(:dockerfile_before_install_app)
122
+ cont << cb if not_empty?(cb)
123
+ cont << "RUN #{pkgMgr} -y install #{required_app.join(" ")}"
124
+ cont << ""
125
+
126
+ cb = trigger_listener(:dockerfile_after_install_app)
127
+ cont << cb if not_empty?(cb)
128
+
129
+ if config.set_current_user?
130
+ #RUN groupadd -f -g <%= @user_group_id %> <%= @user_group_name %> && useradd -u <%= @user_id %> -g <%= @user_group_id %> -m <%= @user_login %> && usermod -aG sudo <%= @user_login %> && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
131
+ #USER <%= @user_login %>
132
+
133
+ uInfo = Dockerun::Cli::UserInfo.user_info
134
+ gInfo = Dockerun::Cli::UserInfo.group_info
135
+
136
+ uCmd = []
137
+ uCmd << "groupadd -f -g"
138
+ uCmd << gInfo[:gid]
139
+ uCmd << gInfo[:group_name]
140
+ uCmd << "&& useradd"
141
+ uCmd << "-u"
142
+ uCmd << uInfo[:uid]
143
+ uCmd << "-g"
144
+ uCmd << gInfo[:gid]
145
+ uCmd << "-m"
146
+ uCmd << uInfo[:login]
147
+ uCmd << "&& usermod -aG sudo"
148
+ uCmd << uInfo[:login]
149
+ uCmd << "&& echo '#{uInfo[:login]} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers"
150
+
151
+ cb = trigger_listener(:dockerfile_before_add_user)
152
+ cont << cb if not_empty?(cb)
153
+
154
+ cont << "RUN #{pkgMgr} -y install sudo && #{uCmd.join(" ")}"
155
+ cont << "USER #{uInfo[:login]}"
156
+ cont << ""
157
+
158
+ cb = trigger_listener(:dockerfile_after_add_user)
159
+ cont << cb if not_empty?(cb)
160
+
161
+ end
162
+
163
+ cb = trigger_listener(:dockerfile_before_workdir)
164
+ cont << cb if not_empty?(cb)
165
+
166
+ if config.is_workdir_given? and is_set_workdir?
167
+ cont << "WORKDIR #{config.workdir}"
168
+ cont << ""
169
+ end
170
+
171
+ cb = trigger_listener(:dockerfile_after_workdir)
172
+ cont << cb if not_empty?(cb)
173
+
174
+
175
+ cb = trigger_listener(:dockerfile_before_command)
176
+ cont << cb if not_empty?(cb)
177
+
178
+ cont << "CMD [\"#{command.join(",")}\"]" if is_command_given?
179
+
180
+ cont.join("\n")
181
+
182
+ end
183
+
184
+ private
185
+ def pkg_mgr(config)
186
+ case config.platform
187
+ when :debian
188
+ "apt-get"
189
+ when :fedora
190
+ "dnf"
191
+ else
192
+ raise Error, "Unknown package manager for platform '#{config.platform}'"
193
+ end
194
+ end
195
+
196
+ def trigger_listener(evt, *argv)
197
+ if not @listener.nil?
198
+ argv << { dfile: self }
199
+ @listener.call(evt, *argv)
200
+ end
201
+ end
202
+
203
+ end
204
+ end