dockerun 0.3.6 → 0.4.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 (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 +104 -0
  6. data/{dockerun.gemspec → dockerun.gemspec.bak} +20 -22
  7. data/exe/dockerun +8 -115
  8. data/lib/dockerun/cli/command.rb +133 -0
  9. data/lib/dockerun/cli/command_factory.rb +313 -0
  10. data/lib/dockerun/cli/command_result.rb +67 -0
  11. data/lib/dockerun/cli/delete_container.rb +55 -0
  12. data/lib/dockerun/cli/delete_image.rb +99 -0
  13. data/lib/dockerun/cli/run.rb +39 -0
  14. data/lib/dockerun/cli/user_info.rb +39 -0
  15. data/lib/dockerun/cli_engine.rb +104 -0
  16. data/lib/dockerun/config.rb +39 -86
  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 +291 -0
  21. data/lib/dockerun/version.rb +1 -1
  22. data/lib/dockerun.rb +31 -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
@@ -1,115 +1,68 @@
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)
11
+ def workdir
12
+ if @workdir.nil?
13
+ @workdir = File.join("/opt",File.basename(Dir.getwd))
14
+ end
15
+ @workdir
28
16
  end
29
-
30
- def initialize(configHash = { }, configFileAvail = false)
31
- @config = configHash
32
- @images = @config[:images] || { }
33
- @confFileAvail = configFileAvail
34
- #@images = { } if @images.nil?
17
+ def is_workdir_given?
18
+ not_empty?(@workdir)
35
19
  end
36
20
 
37
- def isConfigFileAvail?
38
- @confFileAvail
39
- end
40
21
 
41
- def image_names
42
- @images.keys
22
+ def set_platform(val)
23
+ @platform = val
43
24
  end
44
-
45
- def add_image(name)
46
- @images[name] = { } if not_empty?(name) and not @images.keys.include?(name)
25
+ def platform
26
+ if is_empty?(@platform)
27
+ # wild guess
28
+ @platform = :debian
29
+ end
30
+ @platform
47
31
  end
48
32
 
49
- def remove_image(name)
50
- @images.delete(name)
51
- end
52
33
 
53
- def container_names(imageName)
54
- @images[imageName].keys
34
+ def set_current_user(bool = true)
35
+ @set_current_user = bool
55
36
  end
56
-
57
- def container_configs(imageName, name)
58
- @images[imageName].nil? ? {} : @images[imageName][name].nil? ? {} : @images[imageName][name]
37
+ def set_current_user?
38
+ @set_current_user.nil? ? true : @set_current_user
59
39
  end
60
40
 
61
- def add_container(imageName, name)
62
- @images[imageName] = { } if @images[imageName].nil?
63
- @images[imageName][name] = {} if @images[imageName][name].nil?
64
- end
65
41
 
66
- def remove_container(imageName, name)
67
- if not @images[imageName].nil?
68
- @images[imageName].delete(name)
69
- end
70
- end
71
-
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
101
- end
102
-
103
-
104
- def to_storage
105
- res = { images: @images }
106
55
 
107
- path = File.join(Dir.getwd, FILENAME)
108
- File.open(path,"w") do |f|
109
- f.write YAML.dump(res)
110
- end
56
+ def dry_run(bool = true, prompt = true)
57
+ @dry_run = bool
58
+ @dry_run_prompt = prompt
59
+ end
60
+ def is_dry_run?
61
+ @dry_run.nil? ? false : @dry_run
62
+ end
63
+ def is_dry_run_prompt?
64
+ @dry_run_prompt.nil? ? false : @dry_run_prompt
111
65
  end
112
- alias_method :save, :to_storage
113
66
 
114
67
  end
115
68
  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
@@ -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