dockerun 0.3.5 → 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 +40 -70
  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 -221
  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 -204
  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,98 +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
23
- end
24
-
25
- def self.remove
26
- path = File.join(Dir.getwd, FILENAME)
27
- FileUtils.rm(path) if File.exist?(path)
8
+ def set_workdir(path)
9
+ @workdir = path
28
10
  end
29
-
30
- def initialize(configHash = { }, configFileAvail = false)
31
- @config = configHash
32
- @images = @config[:images] || { }
33
- @confFileAvail = configFileAvail
34
- #@images = { } if @images.nil?
35
- end
36
-
37
- def isConfigFileAvail?
38
- @confFileAvail
11
+ def workdir
12
+ if @workdir.nil?
13
+ @workdir = File.join("/opt",File.basename(Dir.getwd))
14
+ end
15
+ @workdir
39
16
  end
40
-
41
- def image_names
42
- @images.keys
17
+ def is_workdir_given?
18
+ not_empty?(@workdir)
43
19
  end
44
20
 
45
- def add_image(name)
46
- @images[name] = { } if not_empty?(name) and not @images.keys.include?(name)
47
- end
48
21
 
49
- def remove_image(name)
50
- @images.delete(name)
22
+ def set_platform(val)
23
+ @platform = val
51
24
  end
52
-
53
- def container_names(imageName)
54
- @images[imageName].keys
25
+ def platform
26
+ if is_empty?(@platform)
27
+ # wild guess
28
+ @platform = :debian
29
+ end
30
+ @platform
55
31
  end
56
32
 
57
- def container_configs(imageName, name)
58
- @images[imageName].nil? ? {} : @images[imageName][name].nil? ? {} : @images[imageName][name]
59
- end
60
33
 
61
- def add_container(imageName, name)
62
- @images[imageName] = { } if @images[imageName].nil?
63
- @images[imageName][name] = {} if @images[imageName][name].nil?
34
+ def set_current_user(bool = true)
35
+ @set_current_user = bool
64
36
  end
65
-
66
- def remove_container(imageName, name)
67
- if not @images[imageName].nil?
68
- @images[imageName].delete(name)
69
- end
37
+ def set_current_user?
38
+ @set_current_user.nil? ? true : @set_current_user
70
39
  end
71
40
 
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
- @images[imageName][container][:mount] << mount
76
- end
77
41
 
78
- def container_mount_points(imageName, container)
79
- res = @images[imageName][container]
80
- if is_empty?(res) or is_empty?(res[:mount])
81
- []
42
+ def activate_context(ctx, &block)
43
+ case ctx
44
+ when :rubygems
45
+ @active_context = Context::Rubygems.new(self)
82
46
  else
83
- res[:mount]
47
+ raise Error, "Unknown context '#{ctx}'"
84
48
  end
49
+ @active_context.instance_eval(&block)
50
+ end
51
+ def active_context
52
+ @active_context
85
53
  end
86
54
 
87
- def to_storage
88
- res = { images: @images }
89
55
 
90
- path = File.join(Dir.getwd, FILENAME)
91
- File.open(path,"w") do |f|
92
- f.write YAML.dump(res)
93
- 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
94
65
  end
95
- alias_method :save, :to_storage
96
66
 
97
67
  end
98
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