docker-cli 0.3.1 → 0.5.1
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 +2 -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 +62 -27
- 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,53 @@
|
|
1
|
+
|
2
|
+
require 'toolrack'
|
3
|
+
require_relative 'run_keep'
|
4
|
+
require_relative 'run_del'
|
5
|
+
require_relative 'run'
|
6
|
+
|
7
|
+
module Docker
|
8
|
+
module Cli
|
9
|
+
class ArgsParser
|
10
|
+
include TR::ArgUtils
|
11
|
+
|
12
|
+
class ArgsParserException < StandardError; end
|
13
|
+
|
14
|
+
OpsOption = [
|
15
|
+
"run-keep", "rk",
|
16
|
+
"run-del","rd",
|
17
|
+
"run","r"
|
18
|
+
]
|
19
|
+
|
20
|
+
arg_spec do
|
21
|
+
|
22
|
+
callback :pre_processing do |argv|
|
23
|
+
select_runner(argv)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def select_runner(argv)
|
29
|
+
ops = argv.first
|
30
|
+
if is_empty?(ops)
|
31
|
+
raise ArgsParserException, "\n Operation is empty. First parameter is operation. Supported operations including : #{OpsOption.join(", ")}\n\n"
|
32
|
+
else
|
33
|
+
case ops
|
34
|
+
when "run-keep", "rk"
|
35
|
+
Docker::Cli::Operations::RunKeep.new.parse_argv(argv[1..-1])
|
36
|
+
|
37
|
+
when "run-del", "rd"
|
38
|
+
Docker::Cli::Operations::RunDel.new.parse_argv(argv[1..-1])
|
39
|
+
|
40
|
+
when "run", "r"
|
41
|
+
Docker::Cli::Operations::Run.new.run
|
42
|
+
|
43
|
+
else
|
44
|
+
raise ArgsParserException, " Unknown operation '#{ops}'. First parameter is operation. Supported operations including : #{OpsOption.join(", ")}\n"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
[true, argv[1..-1]]
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
|
2
|
+
require 'securerandom'
|
3
|
+
require 'tty/prompt'
|
4
|
+
require_relative '../dockerfile'
|
5
|
+
|
6
|
+
module Docker
|
7
|
+
module Cli
|
8
|
+
module Operations
|
9
|
+
|
10
|
+
# Normal run by finding Dockerfile
|
11
|
+
# By default is interactive
|
12
|
+
class Run
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@pmt = TTY::Prompt.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
|
20
|
+
# find dockerfile to build an image
|
21
|
+
df = Dockerfile.find_available
|
22
|
+
raise NoDockerfileFound, "No Dockerfile found. Please create one and re-run this operation" if df.length == 0
|
23
|
+
|
24
|
+
if df.length > 1
|
25
|
+
@selDf = @pmt.select(" Please select one of the Dockerfile to execute : ") do |m|
|
26
|
+
df.each do |f|
|
27
|
+
m.choice f, f
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
@selDf = df.first
|
32
|
+
end
|
33
|
+
|
34
|
+
@mount_root = @pmt.ask(" Please provide a root for folder mount into Docker env : ", default: "/opt", required: true)
|
35
|
+
|
36
|
+
df = Dockerfile.new(@selDf)
|
37
|
+
# parameter pass in is to build the template
|
38
|
+
# e.g. docker_root is to build the dup_gem_bundler_env directive
|
39
|
+
ndf = df.render_dockerfile(docker_root: @mount_root)
|
40
|
+
|
41
|
+
@dev_gems = {}
|
42
|
+
devGems = Cli.find_dev_gems
|
43
|
+
if devGems.length > 0
|
44
|
+
devGems.each do |k,v|
|
45
|
+
@dev_gems[v] = File.join(@mount_root, File.basename(v))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
dfName = @pmt.ask(" Please provide the new name for the generated Dockerfile : ", required: true, default: "Dockerfile.docli")
|
50
|
+
dfPath = File.join(Dir.getwd, dfName)
|
51
|
+
File.open(dfPath,"w") do |f|
|
52
|
+
f.write ndf
|
53
|
+
end
|
54
|
+
|
55
|
+
if Dockerfile.run_before?(dfPath)
|
56
|
+
proceed = @pmt.yes?(" Given dockerfile '#{@selDf}' seems already run before. Do you want to use existing image instead? ")
|
57
|
+
if proceed
|
58
|
+
img = Dockerfile.images(dfPath)
|
59
|
+
if img.length > 1
|
60
|
+
@selImg = @pmt.select(" There are multiple images being run from the same Dockerfile. Please select one of them : ") do |m|
|
61
|
+
img.each do |i|
|
62
|
+
m.choice i, i
|
63
|
+
end
|
64
|
+
end
|
65
|
+
elsif img.length > 0
|
66
|
+
@selImg = img.first
|
67
|
+
end
|
68
|
+
|
69
|
+
else
|
70
|
+
# not using existing image.. built one
|
71
|
+
#@df, @selImg = build_image_from_dockerfile_bin(ndf)
|
72
|
+
@selImg = build_image_from_dockerfile(dfPath, dfName)
|
73
|
+
end
|
74
|
+
|
75
|
+
else
|
76
|
+
#logger.debug "Dockerfile not being run before"
|
77
|
+
#@df, @selImg = build_image_from_dockerfile_bin(ndf) # =>
|
78
|
+
@selImg = build_image_from_dockerfile(dfPath, dfName)
|
79
|
+
end
|
80
|
+
|
81
|
+
logger.debug "selected image : #{@selImg}"
|
82
|
+
|
83
|
+
di = DockerImage.new(@selImg)
|
84
|
+
if di.has_containers?
|
85
|
+
if di.containers.length > 1
|
86
|
+
@selCont = @pmt.select(" Please select one of the container to run : ") do |m|
|
87
|
+
|
88
|
+
di.containers.each do |c|
|
89
|
+
m.choice c.name_for_display, c
|
90
|
+
end
|
91
|
+
|
92
|
+
m.choice "New container", :new
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
else
|
97
|
+
@selCont = di.containers.first
|
98
|
+
end
|
99
|
+
|
100
|
+
end # has_containers?
|
101
|
+
|
102
|
+
|
103
|
+
case @selCont
|
104
|
+
when :new, nil
|
105
|
+
@selCont = @pmt.ask(" Please provide a new container name : ", required: true, default: "#{File.basename(Dir.getwd)}_#{SecureRandom.hex(4)}")
|
106
|
+
|
107
|
+
cp = ContainerProfile.new
|
108
|
+
if devGems.length > 0
|
109
|
+
devGems.each do |name, path|
|
110
|
+
cp.add_mount_point(path, File.join(@mount_root, name))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# add current dir as mount point
|
115
|
+
cp.add_mount_point(Dir.getwd, File.join(@mount_root, File.basename(Dir.getwd)))
|
116
|
+
|
117
|
+
while true
|
118
|
+
STDOUT.puts "\n\n Mount points : \n"
|
119
|
+
ctn = 1
|
120
|
+
cp.mount_points.each do |local, docker|
|
121
|
+
STDOUT.puts " #{ctn}. #{local} ==> #{docker}"
|
122
|
+
end
|
123
|
+
apath = @pmt.ask("\n Please provide full path to mount in the docker (just enter if done) : ")
|
124
|
+
break if is_empty?(apath)
|
125
|
+
|
126
|
+
if File.exist?(apath)
|
127
|
+
mpath = @pmt.ask(" Please provide mount point inside the docker : ", default: File.dirname(apath))
|
128
|
+
cp.add_mount_point(mpath, File.join(@mount_root, File.basename(mpath)))
|
129
|
+
else
|
130
|
+
STDERR.puts "Given path '#{apath}' doesn't exist. Please try again."
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
cmd = @pmt.ask(" What command should be inside the docker? : ", required: true, default: "/bin/bash" )
|
135
|
+
cp.run_command = cmd
|
136
|
+
cp.image_name = @selImg
|
137
|
+
|
138
|
+
dc = DockerContainer.new(@selCont)
|
139
|
+
dc.create(cp)
|
140
|
+
DockerRunLog.instance.log(@selImg, @selCont)
|
141
|
+
|
142
|
+
else
|
143
|
+
|
144
|
+
#cmd = @pmt.ask(" What command should be inside the docker? : ", required: true, default: "/bin/bash" )
|
145
|
+
dc = DockerContainer.new(@selCont.name)
|
146
|
+
dc.start
|
147
|
+
dc.attach
|
148
|
+
#dc.run(cmd)
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
def build_image_from_dockerfile(df, dfName)
|
156
|
+
|
157
|
+
iName = File.basename(Dir.getwd)
|
158
|
+
name = @pmt.ask(" Please provide an image name for Dockerfile '#{dfName}' : ", required: true, default: "#{iName}_image")
|
159
|
+
ctx = @pmt.ask(" Context to run to the dockerfile? ", required: true, default: ".")
|
160
|
+
|
161
|
+
DockerImage.build(name, dfName ,ctx)
|
162
|
+
DockerRunLog.instance.log_dockerfile_image(df, name)
|
163
|
+
|
164
|
+
name
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
#def build_image_from_dockerfile_bin(df)
|
169
|
+
# #raise NoDockerfileFound, "Given Dockerfile to build image '#{df}' does not exist" if not File.exist?(df)
|
170
|
+
|
171
|
+
# dfName = @pmt.ask(" Please provide the new name for the generated Dockerfile : ", required: true, default: "Dockerfile.docli")
|
172
|
+
# path = File.join(Dir.getwd, dfName)
|
173
|
+
# dfName = File.basename(path)
|
174
|
+
# if not_empty?(df)
|
175
|
+
# File.open(path,"w") do |f|
|
176
|
+
# f.write df
|
177
|
+
# end
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# iName = File.basename(Dir.getwd)
|
181
|
+
# name = @pmt.ask(" Please provide an image name for Dockerfile '#{dfName}' : ", required: true, default: "#{iName}_image")
|
182
|
+
# ctx = @pmt.ask(" Context to run to the dockerfile? ", required: true, default: ".")
|
183
|
+
|
184
|
+
# DockerImage.build(name, dfName ,ctx)
|
185
|
+
# DockerRunLog.instance.log_dockerfile_image(df, name)
|
186
|
+
|
187
|
+
# [dfName, name]
|
188
|
+
#end
|
189
|
+
|
190
|
+
|
191
|
+
private
|
192
|
+
def logger
|
193
|
+
if @_logger.nil?
|
194
|
+
@_logger = Cli.logger(:run_ops)
|
195
|
+
end
|
196
|
+
@_logger
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
module Docker
|
3
|
+
module Cli
|
4
|
+
module Operations
|
5
|
+
class RunDel
|
6
|
+
include TR::ArgUtils
|
7
|
+
|
8
|
+
arg_spec do
|
9
|
+
|
10
|
+
callback :pre_processing do |a|
|
11
|
+
capture_image(a)
|
12
|
+
end
|
13
|
+
|
14
|
+
opt "-c", "Command to be executed inside the Docker" do |a|
|
15
|
+
capture_command(a)
|
16
|
+
end
|
17
|
+
|
18
|
+
opt "-u", "Run as current user for Docker" do
|
19
|
+
set_use_same_user(true)
|
20
|
+
end
|
21
|
+
|
22
|
+
callback :post_processing do |a|
|
23
|
+
run
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@match_user = false
|
30
|
+
# leave this blank as the image may have already
|
31
|
+
# set an entry program
|
32
|
+
@cmd = ""
|
33
|
+
end
|
34
|
+
|
35
|
+
def capture_image(a)
|
36
|
+
@dimage = a.first
|
37
|
+
[true, a[1..-1]]
|
38
|
+
end
|
39
|
+
|
40
|
+
def capture_command(a)
|
41
|
+
@cmd = a
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_use_same_user(bol)
|
45
|
+
@match_user = bol
|
46
|
+
end
|
47
|
+
|
48
|
+
# Just run with image name on command line
|
49
|
+
def run
|
50
|
+
|
51
|
+
mountLocal = Dir.getwd
|
52
|
+
mountDocker = "/opt/#{File.basename(Dir.getwd)}"
|
53
|
+
if TR::RTUtils.on_linux? and @match_user
|
54
|
+
# This approach has user match with local user but no name on the docker
|
55
|
+
# workable not nice only
|
56
|
+
Docker::Cli::DockerContainer.create_container(@dimage, interactive: true, tty: true, command: @cmd, mount: { mountLocal => mountDocker }, match_user: @match_user, del: true)
|
57
|
+
else
|
58
|
+
# Apparently on Mac and Windows, the user issue is not an issue
|
59
|
+
Docker::Cli::DockerContainer.create_container(@dimage, interactive: true, tty: true, command: @cmd, mount: { mountLocal => mountDocker }, del: true)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
require 'tty/prompt'
|
3
|
+
require_relative '../docker_run_log'
|
4
|
+
|
5
|
+
module Docker
|
6
|
+
module Cli
|
7
|
+
module Operations
|
8
|
+
class RunKeep
|
9
|
+
include TR::ArgUtils
|
10
|
+
|
11
|
+
arg_spec do
|
12
|
+
|
13
|
+
callback :pre_processing do |a|
|
14
|
+
capture_image(a)
|
15
|
+
end
|
16
|
+
|
17
|
+
opt "-c", "Command to be executed inside the Docker" do |a|
|
18
|
+
capture_command(a)
|
19
|
+
end
|
20
|
+
|
21
|
+
opt "-u", "Run as current user for Docker" do
|
22
|
+
set_use_same_user(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
opt "-n", "Name of the container" do |a|
|
26
|
+
capture_container_name(a)
|
27
|
+
end
|
28
|
+
|
29
|
+
callback :post_processing do |a|
|
30
|
+
run
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@match_user = false #TR::RTUtils.on_linux?
|
37
|
+
# leave this blank as the image may have already
|
38
|
+
# set an entry program
|
39
|
+
@cmd = ""
|
40
|
+
end
|
41
|
+
|
42
|
+
def capture_image(a)
|
43
|
+
@fullArgv = a
|
44
|
+
@dimage = a.first
|
45
|
+
[true, a[1..-1]]
|
46
|
+
end
|
47
|
+
|
48
|
+
def capture_command(a)
|
49
|
+
logger.debug "Capturing command : #{a}"
|
50
|
+
@cmd = a
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture_container_name(a)
|
54
|
+
@contName = a
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_use_same_user(bol)
|
58
|
+
@match_user = bol
|
59
|
+
end
|
60
|
+
|
61
|
+
# Just run with image name on command line
|
62
|
+
def run
|
63
|
+
|
64
|
+
if Docker::Cli::DockerRunLog.instance.has_existing_container?(@dimage)
|
65
|
+
pmt = TTY::Prompt.new
|
66
|
+
begin
|
67
|
+
eCont = pmt.select(" System found there were some container already exist on this image.\n Do you want to reuse the existing container? ") do |m|
|
68
|
+
DockerContainer.containers_of_image_from_history(@dimage).each do |c, name|
|
69
|
+
m.choice name, c
|
70
|
+
end
|
71
|
+
m.choice "Run new container", :new_cont
|
72
|
+
m.choice "Quit", :quit
|
73
|
+
end
|
74
|
+
|
75
|
+
case eCont
|
76
|
+
when :new_cont
|
77
|
+
run_new
|
78
|
+
when :quit
|
79
|
+
STDOUT.puts " Have a nice day "
|
80
|
+
else
|
81
|
+
cont = DockerContainer.new(eCont)
|
82
|
+
cont.start if not cont.is_running?
|
83
|
+
cont.attach
|
84
|
+
end
|
85
|
+
rescue TTY::Reader::InputInterrupt
|
86
|
+
end
|
87
|
+
else
|
88
|
+
run_new
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def run_new
|
95
|
+
mountLocal = Dir.getwd
|
96
|
+
mountDocker = "/opt/#{File.basename(Dir.getwd)}"
|
97
|
+
contName = @contName || SecureRandom.hex(18)
|
98
|
+
if TR::RTUtils.on_linux? and @match_user
|
99
|
+
# This approach has user match with local user but no name on the docker
|
100
|
+
# workable not nice only
|
101
|
+
Docker::Cli::DockerContainer.create_container(@dimage, interactive: true, tty: true, command: @cmd, mount: { mountLocal => mountDocker }, match_user: @match_user, container_name: contName)
|
102
|
+
else
|
103
|
+
# Apparently on Mac and Windows, the user issue is not an issue
|
104
|
+
Docker::Cli::DockerContainer.create_container(@dimage, interactive: true, tty: true, command: @cmd, mount: { mountLocal => mountDocker }, container_name: contName)
|
105
|
+
end
|
106
|
+
|
107
|
+
Docker::Cli::DockerRunLog.instance.log(@dimage, contName, argv: @fullArgv)
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
def logger
|
112
|
+
Cli.logger(:rk)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
require 'etc'
|
3
|
+
|
4
|
+
module Docker
|
5
|
+
module Cli
|
6
|
+
|
7
|
+
module UserInfo
|
8
|
+
include TR::CondUtils
|
9
|
+
|
10
|
+
def self.user_info(login = nil)
|
11
|
+
login = Etc.getlogin if is_empty?(login)
|
12
|
+
res = { login: login }
|
13
|
+
begin
|
14
|
+
res[:uid] = Etc.getpwnam(login).uid
|
15
|
+
rescue Exception => ex
|
16
|
+
res[:uid] = nil
|
17
|
+
end
|
18
|
+
res
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.group_info(login = nil)
|
22
|
+
login = Etc.getlogin if is_empty?(login)
|
23
|
+
res = { }
|
24
|
+
begin
|
25
|
+
gnm = Etc.getgrnam(login)
|
26
|
+
res[:group_name] = gnm.name
|
27
|
+
res[:gid] = gnm.gid
|
28
|
+
rescue Exception => ex
|
29
|
+
p ex
|
30
|
+
res[:group_name] = ""
|
31
|
+
res[:gid] = nil
|
32
|
+
end
|
33
|
+
res
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/docker/cli/version.rb
CHANGED
data/lib/docker/cli.rb
CHANGED
@@ -9,9 +9,21 @@ require_relative "cli/version"
|
|
9
9
|
require_relative 'cli/command'
|
10
10
|
require_relative 'cli/command_factory'
|
11
11
|
|
12
|
+
require_relative 'cli/docker_image'
|
13
|
+
require_relative 'cli/docker_container'
|
14
|
+
require_relative 'cli/docker_composer'
|
15
|
+
|
16
|
+
require_relative 'cli/dockerfile_template'
|
17
|
+
|
12
18
|
module Docker
|
13
19
|
module Cli
|
20
|
+
include TR::CondUtils
|
21
|
+
|
14
22
|
class Error < StandardError; end
|
23
|
+
class RuntimeException < StandardError; end
|
24
|
+
class CommandFailed < StandardError; end
|
25
|
+
class IndefiniteOption < StandardError; end
|
26
|
+
class NoDockerfileFound < StandardError; end
|
15
27
|
# Your code goes here...
|
16
28
|
|
17
29
|
def Cli.docker_exe
|
@@ -25,5 +37,57 @@ module Docker
|
|
25
37
|
|
26
38
|
end
|
27
39
|
|
40
|
+
def self.find_dev_gems
|
41
|
+
if @_devGems.nil?
|
42
|
+
@_devGems = {}
|
43
|
+
Bundler.load.dependencies.each do |d|
|
44
|
+
if not d.source.nil?
|
45
|
+
src = d.source
|
46
|
+
if src.path.to_s != "."
|
47
|
+
@_devGems[d.name] = src.path.expand_path.to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@_devGems
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.digest_bin(bin)
|
56
|
+
OpenSSL::Digest.new("SHA3-256").hexdigest(bin)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.command_output(out)
|
60
|
+
if out.is_a?(Array)
|
61
|
+
out.each do |e|
|
62
|
+
STDOUT.puts " ## #{e}"
|
63
|
+
end
|
64
|
+
else
|
65
|
+
STDOUT.puts " ## #{out}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.logger(tag = nil, &block)
|
70
|
+
if @_logger.nil?
|
71
|
+
@_logger = TeLogger::Tlogger.new(STDOUT)
|
72
|
+
end
|
73
|
+
|
74
|
+
if block
|
75
|
+
if not_empty?(tag)
|
76
|
+
@_logger.with_tag(tag, &block)
|
77
|
+
else
|
78
|
+
@_logger.with_tag(@_logger.tag, &block)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
if is_empty?(tag)
|
82
|
+
@_logger.tag = :docker_cli
|
83
|
+
@_logger
|
84
|
+
else
|
85
|
+
# no block but tag is given? hmm
|
86
|
+
@_logger.tag = tag
|
87
|
+
@_logger
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
28
92
|
end
|
29
93
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# This is mostly a test. May not work across different variant of linux
|
4
|
+
|
5
|
+
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
|
6
|
+
|
7
|
+
tail -f /dev/null
|
8
|
+
#while true; do sleep 1000; done
|
9
|
+
#exec /bin/bash
|
10
|
+
|