57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/cide/cli.rb', line 57
def build
containers = []
setup_docker
banner 'Config'
build = Build::Config.load(Dir.pwd)
exit 1 if build.nil?
ssh_key = File.expand_path(options.ssh_key)
build.run = ['sh', '-e', '-c', options.run] unless options.run.empty?
name = CIDE::Docker.id options.name
tag = "cide/#{name}"
say_status :config, build.inspect
banner 'Build'
if build.use_ssh
unless File.exist?(ssh_key)
fail ArgumentError, "SSH key #{ssh_key} not found"
end
create_tmp_file TEMP_SSH_KEY, File.read(ssh_key)
end
create_tmp_file DOCKERFILE, build.to_dockerfile
build_options = ['--force-rm']
build_options << '--pull' if options.pull
build_options.push '-f', DOCKERFILE
build_options.push '-t', tag
build_options << '.'
docker :build, *build_options
banner 'Run'
build.links.each do |link|
args = ['--detach']
link.env.each_pair do |key, value|
args.push('--env', [key, value].join('='))
end
args << link.image
args << link.run if link.run
link.id = docker(:run, *args, capture: true).strip
containers << link.id
end
run_options = ['--detach']
build.env.each_pair do |key, value|
run_options.push '--env', [key, value].join('=')
end
build.links.each do |link|
run_options.push '--link', [link.id, link.name].join(':')
end
id = SecureRandom.hex
run_options.push '--name', id
run_options.push tag
run_options.push(*build.run)
containers << id
docker(:run, *run_options, capture: true).strip
docker(:attach, id)
say_status :status, 'SUCCESS', :green
return unless options.export
banner 'Export'
source_export_dir = options.guest_export_dir || build.export_dir
fail 'export flag set but no export_dir given' if source_export_dir.nil?
target_export_dir = options.export_dir || source_export_dir
target_export_dir = File.dirname(target_export_dir)
guest_export_dir = File.expand_path(source_export_dir, CIDE_SRC_DIR)
host_export_dir = File.expand_path(target_export_dir, Dir.pwd)
docker :cp, [id, guest_export_dir].join(':'), host_export_dir
rescue Docker::Error => ex
say_status :status, 'ERROR', :red
exit ex.exitstatus
ensure
linked_containers = containers - [id]
unless linked_containers.empty?
infos = docker(
:inspect,
*linked_containers,
capture: true,
verbose: false,
)
JSON.parse(infos).each do |info|
config = info['Config']
state = info['State']
next unless state['Dead'] || state['ExitCode'] > 0
$stderr.puts "=== Failed linked container #{info['Id']} ==="
$stderr.puts "Image: #{config['Image']}"
$stderr.puts "State: #{state.inspect}"
docker(:logs, '--tail', 20, info['Id'])
end
end
unless containers.empty?
docker :rm, '--force', '--volumes', *containers.reverse,
verbose: false,
capture: true
end
end
|