docker-cli 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.release_history.yml +4 -0
- data/.rubocop.yml +2 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +24 -27
- data/Rakefile +2 -1
- data/docker-cli.gemspec +5 -2
- data/exe/_gemdocker +225 -0
- data/exe/dc-update +24 -0
- data/exe/gemdocker +52 -0
- data/exe/gemdocker_test +40 -0
- data/lib/docker/cli/command.rb +37 -31
- data/lib/docker/cli/command_factory.rb +50 -26
- data/lib/docker/cli/command_result.rb +16 -0
- data/lib/docker/cli/docker_composer.rb +113 -0
- data/lib/docker/cli/docker_container.rb +216 -0
- data/lib/docker/cli/docker_image.rb +205 -0
- data/lib/docker/cli/docker_run_log.rb +169 -0
- data/lib/docker/cli/dockerfile.rb +62 -0
- data/lib/docker/cli/dockerfile_template/dup_gem_bundler_env.rb +73 -0
- data/lib/docker/cli/dockerfile_template/match_user.rb +38 -0
- data/lib/docker/cli/dockerfile_template.rb +69 -0
- data/lib/docker/cli/gem/bundler_helper.rb +25 -0
- data/lib/docker/cli/image_helper.rb +43 -0
- data/lib/docker/cli/operations/args_parser.rb +53 -0
- data/lib/docker/cli/operations/run.rb +203 -0
- data/lib/docker/cli/operations/run_del.rb +67 -0
- data/lib/docker/cli/operations/run_keep.rb +118 -0
- data/lib/docker/cli/user_info.rb +39 -0
- data/lib/docker/cli/version.rb +1 -1
- data/lib/docker/cli.rb +64 -0
- data/scripts/create_user.sh.erb +10 -0
- metadata +51 -12
@@ -0,0 +1,205 @@
|
|
1
|
+
|
2
|
+
require_relative 'command_factory'
|
3
|
+
|
4
|
+
module Docker
|
5
|
+
module Cli
|
6
|
+
class DockerImage
|
7
|
+
include TR::CondUtils
|
8
|
+
|
9
|
+
def self.set_master_format(format)
|
10
|
+
@_doc_mformat = format
|
11
|
+
end
|
12
|
+
def self.master_format
|
13
|
+
if @_doc_mformat.nil?
|
14
|
+
@_doc_mformat = "{{.Repository}}#{self.separator}{{.ID}}#{self.separator}{{.Tag}}"
|
15
|
+
end
|
16
|
+
@_doc_mformat.freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.set_inspect_format(format)
|
20
|
+
@_dec_iformat = format
|
21
|
+
end
|
22
|
+
def self.inspect_format
|
23
|
+
if @_doc_iformat.nil?
|
24
|
+
@_doc_iformat = "{{.Created}}#{self.separator}{{.Size}}"
|
25
|
+
end
|
26
|
+
@_doc_iformat.freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.set_separator(sep)
|
30
|
+
@_doc_sep = sep
|
31
|
+
end
|
32
|
+
def self.separator
|
33
|
+
if @_doc_sep.nil?
|
34
|
+
@_doc_sep = ";"
|
35
|
+
end
|
36
|
+
@_doc_sep.freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.images
|
40
|
+
logger.warn "loading images from system is an expensive operation. Please implement some cache at aplication level to increase its efficiency"
|
41
|
+
cmd = []
|
42
|
+
cmd << Cli.docker_exe
|
43
|
+
cmd << "images"
|
44
|
+
cmd << "--format"
|
45
|
+
cmd << "\"#{self.master_format}\""
|
46
|
+
|
47
|
+
rres = []
|
48
|
+
res = Command.new(cmd).run
|
49
|
+
if res.successful?
|
50
|
+
res.each_line do |l|
|
51
|
+
sp = l.strip.split(self.separator)
|
52
|
+
rres << { name: sp[0], id: sp[1], tag: sp[2] }
|
53
|
+
end
|
54
|
+
else
|
55
|
+
logger.warn "Command '#{cmd.join(" ")}' failed.\n Error was : #{res.err_stream}"
|
56
|
+
end
|
57
|
+
|
58
|
+
fres = []
|
59
|
+
rres.each do |r|
|
60
|
+
ccmd = []
|
61
|
+
ccmd << cmd[0]
|
62
|
+
ccmd << "inspect"
|
63
|
+
ccmd << "-f"
|
64
|
+
ccmd << "'{{.ID}}#{self.separator}{{.Created}}#{self.separator}{{.Size}}'"
|
65
|
+
ccmd << r[:name]
|
66
|
+
|
67
|
+
rres = Command.new(ccmd).run
|
68
|
+
if rres.successful?
|
69
|
+
rres.each_line do |l|
|
70
|
+
sp = l.strip.split(self.separator)
|
71
|
+
rid = sp[0]
|
72
|
+
r[:image_id] = rid.split(":")[1]
|
73
|
+
r[:created] = sp[1]
|
74
|
+
r[:size] = sp[2]
|
75
|
+
r[:runtime] = true
|
76
|
+
fres << DockerImage.new(r[:name], r)
|
77
|
+
end
|
78
|
+
else
|
79
|
+
logger.warn "Command '#{ccmd.join(" ")}' failed.\n Error was : #{rres.err_stream}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
fres
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.image(image)
|
87
|
+
cmd = []
|
88
|
+
cmd << Cli.docker_exe
|
89
|
+
cmd << "images"
|
90
|
+
cmd << "--format"
|
91
|
+
cmd << "\"#{self.master_format}\""
|
92
|
+
# image and tag is in single unit
|
93
|
+
# e.g.:
|
94
|
+
# jruby:9.2-jdk11
|
95
|
+
# jruby:9
|
96
|
+
# jruby:9.3.0.0-jdk11
|
97
|
+
cmd << image
|
98
|
+
|
99
|
+
rres = []
|
100
|
+
res = Command.new(cmd).run
|
101
|
+
if res.successful?
|
102
|
+
# single image could have many lines because they have
|
103
|
+
# different tags!
|
104
|
+
res.each_line do |l|
|
105
|
+
sp = l.strip.split(self.separator)
|
106
|
+
rres << { name: sp[0], id: sp[1], tag: sp[2] }
|
107
|
+
end
|
108
|
+
else
|
109
|
+
logger.warn "Command '#{cmd.join(" ")}' failed.\n Error was : #{res.err_stream}"
|
110
|
+
end
|
111
|
+
|
112
|
+
fres = []
|
113
|
+
rres.each do |r|
|
114
|
+
ccmd = []
|
115
|
+
ccmd << cmd[0]
|
116
|
+
ccmd << "inspect"
|
117
|
+
ccmd << "-f"
|
118
|
+
ccmd << "'{{.ID}}#{self.separator}{{.Created}}#{self.separator}{{.Size}}'"
|
119
|
+
ccmd << r[:name]
|
120
|
+
|
121
|
+
rres = Command.new(ccmd).run
|
122
|
+
if rres.successful?
|
123
|
+
rres.each_line do |l|
|
124
|
+
sp = l.strip.split(self.separator)
|
125
|
+
rid = sp[0]
|
126
|
+
r[:image_id] = rid.split(":")[1]
|
127
|
+
r[:created] = sp[1]
|
128
|
+
r[:size] = sp[2]
|
129
|
+
r[:runtime] = true
|
130
|
+
fres << DockerImage.new(r[:name], r)
|
131
|
+
end
|
132
|
+
else
|
133
|
+
logger.warn "Command '#{ccmd.join(" ")}' failed.\n Error was : #{rres.err_stream}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
fres
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.build(imageName, dockerfile, context = ".")
|
141
|
+
command.build_image(imageName, dockerfile: dockerfile, context_root: context).run
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
attr_reader :name, :tag, :size, :created, :image_id, :sid
|
146
|
+
|
147
|
+
def initialize(name, opts = {})
|
148
|
+
@name = name
|
149
|
+
if not_empty?(opts)
|
150
|
+
@sid = opts[:sid]
|
151
|
+
@image_id = opts[:image_id]
|
152
|
+
@tag = opts[:tag]
|
153
|
+
@size = opts[:size]
|
154
|
+
@created = opts[:created]
|
155
|
+
@runtime = opts[:runtime]
|
156
|
+
end
|
157
|
+
|
158
|
+
@runtime = false if is_empty?(@runtime) or not_bool?(@runtime)
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
def is_runtime_image?
|
163
|
+
@runtime
|
164
|
+
end
|
165
|
+
|
166
|
+
def has_containers?
|
167
|
+
DockerRunLog.instance.image_has_containers?(@name)
|
168
|
+
end
|
169
|
+
|
170
|
+
def containers
|
171
|
+
if @_cont.nil?
|
172
|
+
# here assuming every run from system will be logged
|
173
|
+
# but what about the one not using the system?
|
174
|
+
@_cont = DockerRunLog.instance.image_containers(@name).collect { |e| DockerContainer.new(e[:container], e) }
|
175
|
+
end
|
176
|
+
@_cont
|
177
|
+
end
|
178
|
+
|
179
|
+
def delete!
|
180
|
+
if not_empty?(@tag)
|
181
|
+
command.delete_image(@name, @tag, opts)
|
182
|
+
else
|
183
|
+
raise IndefiniteOption, "Delete image cannot proceed because there might be more than single instance of the image. Please provide a tag for definite selection for deletion."
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
def self.command
|
189
|
+
if @_cmd.nil?
|
190
|
+
@_cmd = CommandFactory.new
|
191
|
+
end
|
192
|
+
@_cmd
|
193
|
+
end
|
194
|
+
|
195
|
+
def command
|
196
|
+
self.class.command
|
197
|
+
end
|
198
|
+
|
199
|
+
def self.logger
|
200
|
+
Cli.logger(:docker_image)
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
|
2
|
+
require 'singleton'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Docker
|
6
|
+
module Cli
|
7
|
+
|
8
|
+
class NonEmptyRecord < StandardError; end
|
9
|
+
|
10
|
+
class DockerRunLog
|
11
|
+
include TR::CondUtils
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
def log(image, container, opts = {})
|
15
|
+
if not_empty?(image) and not_empty?(container)
|
16
|
+
logfile[image] = [] if logfile[image].nil?
|
17
|
+
cont = { container: container, created_at: Time.now.to_i, last_run: Time.now.to_i }
|
18
|
+
cont = cont.merge(opts) if not_empty?(opts)
|
19
|
+
logfile[image] << cont
|
20
|
+
write
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#def log_dockerfile(df)
|
25
|
+
# if not_empty?(df) and File.exist?(df)
|
26
|
+
# logfile[:dockerfile_signature] = [] if logfile[:dockerfile_signature].nil?
|
27
|
+
# d = digest_file(df)
|
28
|
+
# if not logfile[:dockerfile_signature].include?(d)
|
29
|
+
# logfile[:dockerfile_signature] << digest.hexdigest(File.read(df))
|
30
|
+
# end
|
31
|
+
# write
|
32
|
+
# end
|
33
|
+
#end
|
34
|
+
|
35
|
+
def log_dockerfile_image(df, image)
|
36
|
+
if not_empty?(df) and File.exist?(df) and not_empty?(image)
|
37
|
+
logfile[:dockerfile_images] = { } if logfile[:dockerfile_images].nil?
|
38
|
+
d = digest_file(df)
|
39
|
+
logfile[:dockerfile_images][d] = [] if logfile[:dockerfile_images][d].nil?
|
40
|
+
logfile[:dockerfile_images][d] << image
|
41
|
+
write
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_dockerfile_built_to_image?(df)
|
46
|
+
if not_empty?(df)
|
47
|
+
if File.exist?(df)
|
48
|
+
d = digest_file(df)
|
49
|
+
else
|
50
|
+
d = df
|
51
|
+
end
|
52
|
+
|
53
|
+
not (logfile[:dockerfile_images].nil? or logfile[:dockerfile_images][d].nil?)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def dockerfile_images(df)
|
58
|
+
if File.exist?(df)
|
59
|
+
d = digest_file(df)
|
60
|
+
else
|
61
|
+
d = df
|
62
|
+
end
|
63
|
+
|
64
|
+
if (logfile[:dockerfile_images].nil? or logfile[:dockerfile_images][d].nil?)
|
65
|
+
[]
|
66
|
+
else
|
67
|
+
logfile[:dockerfile_images][d]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def has_dockerfile_seen_before?(df)
|
72
|
+
logger.debug "dockerfile_seen_before? #{df}"
|
73
|
+
if not_empty?(df) and File.exist?(df)
|
74
|
+
d = Cli.digest_bin(File.read(df))
|
75
|
+
logger.debug "Digest : #{d}"
|
76
|
+
logger.debug "Record : #{logfile[:dockerfile_images]}"
|
77
|
+
if not logfile[:dockerfile_images].nil?
|
78
|
+
logfile[:dockerfile_images].include?(d)
|
79
|
+
else
|
80
|
+
false
|
81
|
+
end
|
82
|
+
else
|
83
|
+
false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def digest_file(path)
|
88
|
+
if not_empty?(path) and File.exist?(path)
|
89
|
+
Cli.digest_bin(File.read(path))
|
90
|
+
else
|
91
|
+
""
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def image_has_containers?(image)
|
96
|
+
not logfile[image].nil? and logfile[image].length > 0
|
97
|
+
end
|
98
|
+
|
99
|
+
def delete_image(image, opts = {})
|
100
|
+
if logfile[image].nil? or is_empty?(logfile[image])
|
101
|
+
logfile.delete(image)
|
102
|
+
elsif not_empty?(opts) and opts[:force] == true
|
103
|
+
logfile.delete(image)
|
104
|
+
else
|
105
|
+
raise NonEmptyRecord, "Image #{image} has #{logfile[image].length} container(s). Remove image failed."
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def update_last_run(image, cont)
|
110
|
+
if not logfile[image].nil? and not logfile[image][cont].nil?
|
111
|
+
logfile[image][cont][:last_run] = Time.now.to_i
|
112
|
+
write
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def image_containers(image)
|
117
|
+
if not logfile[image].nil?
|
118
|
+
logfile[image]
|
119
|
+
else
|
120
|
+
[]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def all_logs
|
125
|
+
logfile.freeze
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
def logfile
|
130
|
+
if @_logfile.nil?
|
131
|
+
if File.exist?(log_path)
|
132
|
+
@_logfile = YAML.load(File.read(log_path))
|
133
|
+
else
|
134
|
+
@_logfile = {}
|
135
|
+
end
|
136
|
+
end
|
137
|
+
@_logfile
|
138
|
+
end
|
139
|
+
|
140
|
+
def write
|
141
|
+
File.open(log_path,"w") do |f|
|
142
|
+
f.write YAML.dump(logfile)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def log_path
|
147
|
+
if @_logPath.nil?
|
148
|
+
@_logPath = File.join(Dir.getwd, ".docker_run_log")
|
149
|
+
end
|
150
|
+
@_logPath
|
151
|
+
end
|
152
|
+
|
153
|
+
def digest
|
154
|
+
if @_digest.nil?
|
155
|
+
@_digest = Cli.digest
|
156
|
+
end
|
157
|
+
@_digest
|
158
|
+
end
|
159
|
+
|
160
|
+
def logger
|
161
|
+
if @_logger.nil?
|
162
|
+
@_logger = Cli.logger(:drLog)
|
163
|
+
end
|
164
|
+
@_logger
|
165
|
+
end
|
166
|
+
|
167
|
+
end # class DockerRunLog
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
module Docker
|
5
|
+
module Cli
|
6
|
+
class Dockerfile
|
7
|
+
|
8
|
+
class NoDockerfileFound < StandardError; end
|
9
|
+
|
10
|
+
def self.find_available(root = Dir.getwd)
|
11
|
+
Dir.glob("**/Dockerfile*")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run_before?(dockerfile_path)
|
15
|
+
DockerRunLog.instance.has_dockerfile_seen_before?(dockerfile_path)
|
16
|
+
end
|
17
|
+
|
18
|
+
# expect dockerfile is CONTENT, not file path
|
19
|
+
def self.images(dockerfile)
|
20
|
+
DockerRunLog.instance.dockerfile_images(dockerfile)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(file)
|
24
|
+
@dfile = file
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_dockerfile(vals = {}, &block)
|
28
|
+
if @_df.nil?
|
29
|
+
if @dfile.nil?
|
30
|
+
@_df = nil
|
31
|
+
else
|
32
|
+
if File.exist?(@dfile)
|
33
|
+
if is_erb_template?
|
34
|
+
@_df = process_dockerfile_template(@dfile, vals)
|
35
|
+
else
|
36
|
+
@_df = File.read(@dfile)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
@_df = nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@_df
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_erb_template?
|
47
|
+
if File.exist?(@dfile)
|
48
|
+
cont = File.read(@dfile)
|
49
|
+
(cont =~ /<%=/ and cont =~ /%>/) != nil
|
50
|
+
else
|
51
|
+
false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def process_dockerfile_template(file, values = {})
|
56
|
+
raise Error, "Given dockerfile to process as template not found" if not File.exist?(file)
|
57
|
+
DockerfileTemplate::TemplateEngine.new.process(File.read(file), values)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
module Docker
|
3
|
+
module Cli
|
4
|
+
module DockerfileTemplate
|
5
|
+
module DupGemBundlerEnv
|
6
|
+
|
7
|
+
# DSL entry by including into DockerfileTemplate module
|
8
|
+
def dup_gem_bundler_env(&block)
|
9
|
+
if has_dev_gems?
|
10
|
+
logger.debug "Detected development gems"
|
11
|
+
|
12
|
+
#add_mandatory_key(:docker_root)
|
13
|
+
#if not has_mandatory_keys? and block
|
14
|
+
# @docker_root = block.call(:docker_root)
|
15
|
+
#else
|
16
|
+
raise TemplateKeyRequired, "docker_root is required for dup_gem_bundler_env to function" if is_empty?(@docker_root)
|
17
|
+
#end
|
18
|
+
|
19
|
+
# gen shell script
|
20
|
+
res = gen_script
|
21
|
+
block.call(:script_output, res) if block
|
22
|
+
localPath = File.join(Dir.getwd,"dup_gem_bundler_env.rb")
|
23
|
+
File.open(localPath,"w") do |f|
|
24
|
+
f.write res
|
25
|
+
end
|
26
|
+
|
27
|
+
inst = []
|
28
|
+
# copy inside docker
|
29
|
+
inst << "COPY #{File.basename(localPath)} /tmp/dup_gem_bundler_env.rb"
|
30
|
+
# run the script
|
31
|
+
inst << "RUN ruby /tmp/dup_gem_bundler_env.rb"
|
32
|
+
# for the docker just this two lines
|
33
|
+
# but the localPath must be there first before this two
|
34
|
+
# lines can come into effect
|
35
|
+
inst.join("\n")
|
36
|
+
else
|
37
|
+
""
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def has_dev_gems?
|
43
|
+
not Cli.find_dev_gems.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
def gen_script
|
47
|
+
|
48
|
+
res = %Q(
|
49
|
+
#!/usr/bin/env ruby
|
50
|
+
|
51
|
+
## This file is auto-generated.
|
52
|
+
|
53
|
+
<% Docker::Cli.find_dev_gems.each do |name, pa| %>
|
54
|
+
`bundle config --global local.<%= name %> <%= File.join(@docker_root, File.basename(pa)) %>`
|
55
|
+
<% end %>
|
56
|
+
)
|
57
|
+
|
58
|
+
ERB.new(res).result(binding)
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def logger
|
63
|
+
if @_logger
|
64
|
+
@_logger = Cli.logger(:temp_dup_gem_bundler_env)
|
65
|
+
end
|
66
|
+
@_logger
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
require 'erb'
|
3
|
+
require_relative '../user_info'
|
4
|
+
|
5
|
+
module Docker
|
6
|
+
module Cli
|
7
|
+
module DockerfileTemplate
|
8
|
+
module MatchUser
|
9
|
+
|
10
|
+
# DSL entry
|
11
|
+
def match_user
|
12
|
+
|
13
|
+
logger.debug "match_user called"
|
14
|
+
ui = UserInfo.user_info
|
15
|
+
gi = UserInfo.group_info
|
16
|
+
|
17
|
+
ERB.new(user_template).result_with_hash({ user_group_id: gi[:gid], user_group_name: gi[:group_name], user_id: ui[:uid], user_login: ui[:login] })
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def user_template
|
23
|
+
if @_ut.nil?
|
24
|
+
@_ut = []
|
25
|
+
@_ut << "RUN apt-get install -y sudo && 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"
|
26
|
+
@_ut << "USER <%= user_login %>"
|
27
|
+
end
|
28
|
+
@_ut.join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def logger
|
32
|
+
Cli.logger(:temp_match_user)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
Dir.glob(File.join(File.dirname(__FILE__),"dockerfile_template","*.rb")).each do |f|
|
3
|
+
require_relative f
|
4
|
+
end
|
5
|
+
|
6
|
+
module Docker
|
7
|
+
module Cli
|
8
|
+
module DockerfileTemplate
|
9
|
+
class TemplateKeyRequired < StandardError; end
|
10
|
+
class TemplateEngine
|
11
|
+
include MatchUser
|
12
|
+
include DupGemBundlerEnv
|
13
|
+
|
14
|
+
def process(cont, values = {}, &block)
|
15
|
+
logger.debug "Got values : #{values}"
|
16
|
+
values.each do |k,v|
|
17
|
+
|
18
|
+
logger.debug "Creating field #{k}"
|
19
|
+
|
20
|
+
self.class.class_eval <<-END
|
21
|
+
if not (Class.instance_methods.include?(:#{k}) and Class.instace_methods.include?(:#{k}=))
|
22
|
+
attr_accessor :#{k}
|
23
|
+
elsif not Class.instance_methods.include?(:#{k})
|
24
|
+
attr_reader :#{k}
|
25
|
+
elsif not Class.instance_methods.include?(:#{k}=)
|
26
|
+
attr_writer :#{k}
|
27
|
+
end
|
28
|
+
END
|
29
|
+
|
30
|
+
self.send("#{k}=", v)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
ERB.new(cont).result(binding)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def logger
|
39
|
+
if @_logger.nil?
|
40
|
+
@_logger = Cli.logger(:df_template)
|
41
|
+
end
|
42
|
+
@_logger
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_mandatory_key(key)
|
46
|
+
if @_man.nil?
|
47
|
+
@_man = []
|
48
|
+
end
|
49
|
+
@_man << key if not_empty?(key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def mandatory_keys
|
53
|
+
@_man
|
54
|
+
end
|
55
|
+
|
56
|
+
def has_mandatory_keys?
|
57
|
+
given = true
|
58
|
+
mandatory_keys.each do |mk|
|
59
|
+
given = Class.instance_methods.include?(mk.to_sym) and Class.instance_methods.include?("#{mk}=".to_sym)
|
60
|
+
break if not given
|
61
|
+
end
|
62
|
+
|
63
|
+
given
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
module Docker
|
5
|
+
module Cli
|
6
|
+
module BundlerHelper
|
7
|
+
|
8
|
+
def find_local_dev_gems
|
9
|
+
|
10
|
+
res = {}
|
11
|
+
Bundler.load.dependencies.each do |d|
|
12
|
+
if not d.source.nil?
|
13
|
+
src = d.source
|
14
|
+
if src.path.to_s != "."
|
15
|
+
res[d.name] = src.path.expand_path.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
res
|
20
|
+
|
21
|
+
end # find_local_dev_gem
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Docker
|
4
|
+
module Cli
|
5
|
+
module ImageHelper
|
6
|
+
|
7
|
+
def build_image(pmt, cmdFact)
|
8
|
+
|
9
|
+
root = Dir.getwd
|
10
|
+
dockerfile = File.join(root, "Dockerfile")
|
11
|
+
|
12
|
+
again = true
|
13
|
+
while again
|
14
|
+
if not File.exist?(dockerfile)
|
15
|
+
dockerfile = pmt.ask(" #{dockerfile} does not exist. Please provide new location of Dockerfile: ", required: true)
|
16
|
+
else
|
17
|
+
again = false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
again = true
|
22
|
+
while again
|
23
|
+
dname = pmt.ask(" Please provide name of image at local : ", required: true)
|
24
|
+
if cmdFact.is_image_exist?(dname)
|
25
|
+
|
26
|
+
reuse = pmt.yes?(" Given local image name '#{dname}' already taken. Use back the same image? 'No' to retry with new name : ")
|
27
|
+
if reuse
|
28
|
+
again = false
|
29
|
+
end
|
30
|
+
else
|
31
|
+
rv = cmdFact.build_image(dname, dockerfile: dockerfile)
|
32
|
+
raise CommandFailed, "Build image command failed. Error was : #{rv.err_stream}"
|
33
|
+
again = false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
dname
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|