docker-cli 0.3.0 → 0.5.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.
- 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
|