Class: PicsolveDockerBuilder::Frame
- Inherits:
-
Object
- Object
- PicsolveDockerBuilder::Frame
show all
- Includes:
- Base
- Defined in:
- lib/picsolve_docker_builder/frame.rb
Overview
Docker image building template rubocop:disable Metrics/ClassLength
Instance Method Summary
collapse
Methods included from Base
#base_dir, #config, #config_file, #config_path, #read_config
Constructor Details
#initialize ⇒ Frame
Returns a new instance of Frame.
13
14
15
16
17
18
19
|
# File 'lib/picsolve_docker_builder/frame.rb', line 13
def initialize
Docker.options[:read_timeout] = 3600
Excon.defaults[:read_timeout] = 3600
config
end
|
Instance Method Details
#asset_build ⇒ Object
142
143
|
# File 'lib/picsolve_docker_builder/frame.rb', line 142
def asset_build
end
|
#asset_image ⇒ Object
327
328
329
|
# File 'lib/picsolve_docker_builder/frame.rb', line 327
def asset_image
@asset_image ||= fetch_asset_image
end
|
#build ⇒ Object
145
146
147
148
149
150
151
152
|
# File 'lib/picsolve_docker_builder/frame.rb', line 145
def build
asset_build
if dest_image_name.nil?
log.info 'Skip building docker image as no dest_image is set'
return
end
docker_build
end
|
#build_dir ⇒ Object
233
234
235
|
# File 'lib/picsolve_docker_builder/frame.rb', line 233
def build_dir
'/_build'
end
|
#build_mode ⇒ Object
45
46
47
48
49
50
51
|
# File 'lib/picsolve_docker_builder/frame.rb', line 45
def build_mode
return :template unless image_name.nil?
return :dockerfile if dockerfile_exists?
log.fatal 'No image_name configured and no Dockerfile present'
end
|
#build_user ⇒ Object
229
230
231
|
# File 'lib/picsolve_docker_builder/frame.rb', line 229
def build_user
'build'
end
|
#build_user_home ⇒ Object
225
226
227
|
# File 'lib/picsolve_docker_builder/frame.rb', line 225
def build_user_home
'/home/build'
end
|
#build_user_uid ⇒ Object
221
222
223
|
# File 'lib/picsolve_docker_builder/frame.rb', line 221
def build_user_uid
Process.uid.to_s
end
|
#container ⇒ Object
237
238
239
|
# File 'lib/picsolve_docker_builder/frame.rb', line 237
def container
@container ||= create_container
end
|
#create_container ⇒ Object
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
# File 'lib/picsolve_docker_builder/frame.rb', line 260
def create_container
command = ['/bin/sleep', '3600']
c = Docker::Container.create(
'Image' => asset_image.id,
'Cmd' => command,
'OpenStdin' => false,
'WorkingDir' => '/_build',
'Env' => environment
)
at_exit do
stop
end
log.debug "created a new container image=#{image_name} " \
"id=#{c.id} cmd=#{command}"
c
end
|
#create_logger ⇒ Object
331
332
333
334
335
|
# File 'lib/picsolve_docker_builder/frame.rb', line 331
def create_logger
log = Logger.new(STDOUT)
log.level = Logger::DEBUG
log
end
|
#default_config ⇒ Object
21
22
23
|
# File 'lib/picsolve_docker_builder/frame.rb', line 21
def default_config
{ 'docker' => {} }
end
|
#dest_image_name ⇒ Object
277
278
279
|
# File 'lib/picsolve_docker_builder/frame.rb', line 277
def dest_image_name
config['docker']['image_name']
end
|
#docker_build ⇒ Object
134
135
136
137
138
139
140
|
# File 'lib/picsolve_docker_builder/frame.rb', line 134
def docker_build
dockerfile
log.info "start docker image building with path #{base_dir}"
@docker_build = docker_build_build
end
|
#docker_build_build ⇒ Object
124
125
126
127
128
129
130
131
132
|
# File 'lib/picsolve_docker_builder/frame.rb', line 124
def docker_build_build
Docker::Image.build_from_dir(base_dir) do |stream|
s = JSON.parse(stream)['stream']
log.debug s.strip unless s.nil?
end
rescue StandardError => e
log.fatal "docker building failed: #{e}"
exit 1
end
|
#dockerfile ⇒ Object
158
159
160
161
162
163
164
165
166
167
|
# File 'lib/picsolve_docker_builder/frame.rb', line 158
def dockerfile
return unless build_mode == :template
File.open('Dockerfile', 'w') do |file|
dockerfile_template.each_line do |line|
log.debug "Dockerfile: #{line.strip}"
end
file.write(dockerfile_template)
end
end
|
#dockerfile_exists? ⇒ Boolean
169
170
171
|
# File 'lib/picsolve_docker_builder/frame.rb', line 169
def dockerfile_exists?
File.exist? dockerfile_path
end
|
#dockerfile_hooks_asset_build_early ⇒ Object
65
66
67
68
69
|
# File 'lib/picsolve_docker_builder/frame.rb', line 65
def dockerfile_hooks_asset_build_early
config['docker']['dockerfile_hooks']['asset_build']['early']
rescue NoMethodError
''
end
|
#dockerfile_hooks_asset_build_late ⇒ Object
71
72
73
74
75
|
# File 'lib/picsolve_docker_builder/frame.rb', line 71
def dockerfile_hooks_asset_build_late
config['docker']['dockerfile_hooks']['asset_build']['late']
rescue NoMethodError
''
end
|
#dockerfile_hooks_docker_build_early ⇒ Object
53
54
55
56
57
|
# File 'lib/picsolve_docker_builder/frame.rb', line 53
def dockerfile_hooks_docker_build_early
config['docker']['dockerfile_hooks']['docker_build']['early']
rescue NoMethodError
''
end
|
#dockerfile_hooks_docker_build_late ⇒ Object
59
60
61
62
63
|
# File 'lib/picsolve_docker_builder/frame.rb', line 59
def dockerfile_hooks_docker_build_late
config['docker']['dockerfile_hooks']['docker_build']['late']
rescue NoMethodError
''
end
|
#dockerfile_path ⇒ Object
154
155
156
|
# File 'lib/picsolve_docker_builder/frame.rb', line 154
def dockerfile_path
File.join(base_dir, 'Dockerfile')
end
|
#dockerfile_template ⇒ Object
173
174
175
|
# File 'lib/picsolve_docker_builder/frame.rb', line 173
def dockerfile_template
fail NotImplementedError
end
|
#dockerignore_template ⇒ Object
177
178
179
|
# File 'lib/picsolve_docker_builder/frame.rb', line 177
def dockerignore_template
fail NotImplementedError
end
|
#environment ⇒ Object
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
# File 'lib/picsolve_docker_builder/frame.rb', line 241
def environment
blacklist = %w(
SSH_CLIENT
SSH_CONNECTION
LD_LIBRARY_PATH
PATH
NVM_DIR
NVM_NODEJS_ORG_MIRROR)
keys = ENV.keys
keys = keys.reject do |key|
blacklist.include? key
end
keys.map do |key|
"#{key}=#{ENV[key]}"
end
end
|
#execute(cmd) ⇒ Object
25
26
27
28
29
30
|
# File 'lib/picsolve_docker_builder/frame.rb', line 25
def execute(cmd)
r = container.exec(cmd)
fail "Execution of cmd=#{cmd} failed" unless r[2] == 0
log.debug "executed container id=#{container.id} cmd=#{cmd} result=#{r}"
r
end
|
#execute_attach(cmd) ⇒ Object
32
33
34
35
36
37
38
39
40
41
42
43
|
# File 'lib/picsolve_docker_builder/frame.rb', line 32
def execute_attach(cmd)
log.debug "execute and attach container id=#{container.id} cmd=#{cmd}"
r = container.exec(
cmd
) do |_stream, chunk|
$stdout.write chunk
$stdout.flush
end
fail "Execution of cmd=#{cmd} failed" unless r[2] == 0
log.debug 'executed and attached container ' \
"id=#{container.id} cmd=#{cmd} exitcode=#{r[2]}"
end
|
#fetch_asset_image ⇒ Object
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
# File 'lib/picsolve_docker_builder/frame.rb', line 305
def fetch_asset_image
log.debug "pulling image '#{image_name}' from registry"
Docker::Image.create({'fromImage' => image_name}, Composer::Registry.creds)
log.debug "building asset image from '#{image_name}'"
dockerfile_asset = "FROM \#{image_name}\nMAINTAINER Picsolve Onlineops <[email protected]>\n\#{dockerfile_hooks_asset_build_early}\nRUN useradd -m -d \#{build_user_home} -u \#{build_user_uid} \#{build_user}\n\#{dockerfile_hooks_asset_build_late}\n"
begin
Docker::Image.build(dockerfile_asset) do |stream|
s = JSON.parse(stream)['stream']
log.debug s.strip unless s.nil?
end
rescue StandardError => e
log.fatal "asset building failed: #{e}"
exit 1
end
end
|
#image_name ⇒ Object
293
294
295
296
297
298
299
300
301
302
303
|
# File 'lib/picsolve_docker_builder/frame.rb', line 293
def image_name
name = config['docker']['base_image']
if name.match(/:[a-z0-9\-_]+$/)
name
else
"#{name}:latest"
end
rescue NoMethodError
nil
end
|
#jenkins_build_number ⇒ Object
77
78
79
80
81
|
# File 'lib/picsolve_docker_builder/frame.rb', line 77
def jenkins_build_number
n = ENV['BUILD_NUMBER']
return nil if n.nil?
n.to_i
end
|
#log ⇒ Object
337
338
339
|
# File 'lib/picsolve_docker_builder/frame.rb', line 337
def log
@logger ||= create_logger
end
|
#push ⇒ Object
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/picsolve_docker_builder/frame.rb', line 101
def push
fail 'No image found to be pushed' if @docker_build.nil?
tags.each do |tag|
repotag = "#{dest_image_name}:#{tag}"
log.info "pushing image with #{repotag}"
@docker_build.push(
Composer::Registry.creds,
tag: tag
) do |resp|
resp = JSON.parse resp
if resp.key? 'errorDetail'
message = "pushing image #{repotag} failed: #{resp['errorDetail']}"
log.fatal message
fail message
end
log.info "status pushing image #{repotag}: #{resp['status']}" \
if resp.key? 'status'
end
end
end
|
#runtime_image_name ⇒ Object
281
282
283
284
285
286
287
288
289
290
291
|
# File 'lib/picsolve_docker_builder/frame.rb', line 281
def runtime_image_name
name = config['docker']['runtime_image'] || image_name
if name.match(/:[a-z0-9\-_]+$/)
name
else
"#{name}:latest"
end
rescue NoMethodError
nil
end
|
#start ⇒ Object
189
190
191
192
193
|
# File 'lib/picsolve_docker_builder/frame.rb', line 189
def start
container.start('Binds' => volumes)
log.debug "started container id=#{container.id} volumes=#{volumes}"
end
|
#stop ⇒ Object
195
196
197
198
199
200
201
202
|
# File 'lib/picsolve_docker_builder/frame.rb', line 195
def stop
return if @container.nil?
container.stop
log.debug "stopped container id=#{container.id}"
container.remove
log.debug "removed container id=#{container.id}"
@container = nil
end
|
#tag ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/picsolve_docker_builder/frame.rb', line 89
def tag
fail 'No image found to tag' if @docker_build.nil?
tags.each do |tag|
log.info "tagging image with #{dest_image_name}:#{tag}"
@docker_build.tag(
repo: dest_image_name,
tag: tag,
force: true
)
end
end
|
83
84
85
86
87
|
# File 'lib/picsolve_docker_builder/frame.rb', line 83
def tags
t = ['latest']
t << "jenkins-#{jenkins_build_number}" unless jenkins_build_number.nil?
t
end
|
#validate_config(c) ⇒ Object
181
182
183
|
# File 'lib/picsolve_docker_builder/frame.rb', line 181
def validate_config(c)
validate_config_docker(c)
end
|
#validate_config_docker(c) ⇒ Object
185
186
187
|
# File 'lib/picsolve_docker_builder/frame.rb', line 185
def validate_config_docker(c)
c
end
|
#volume_workspace ⇒ Object
204
205
206
207
208
209
|
# File 'lib/picsolve_docker_builder/frame.rb', line 204
def volume_workspace
[
base_dir,
build_dir
]
end
|
#volumes ⇒ Object
215
216
217
218
219
|
# File 'lib/picsolve_docker_builder/frame.rb', line 215
def volumes
volumes_array.map do |volume|
volume.join ':'
end
end
|
#volumes_array ⇒ Object
211
212
213
|
# File 'lib/picsolve_docker_builder/frame.rb', line 211
def volumes_array
[volume_workspace]
end
|