dockerun 0.3.6 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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