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
Direct Known Subclasses
Scala
Instance Method Summary
collapse
Methods included from Base
#base_dir, #config, #config_path, #read_config
Constructor Details
#initialize ⇒ Frame
Returns a new instance of Frame.
12
13
14
15
16
17
18
|
# File 'lib/picsolve_docker_builder/frame.rb', line 12
def initialize
Docker.options[:read_timeout] = 3600
Excon.defaults[:read_timeout] = 3600
config
end
|
Instance Method Details
#asset_image ⇒ Object
284
285
286
|
# File 'lib/picsolve_docker_builder/frame.rb', line 284
def asset_image
@asset_image ||= fetch_asset_image
end
|
#build ⇒ Object
141
142
143
|
# File 'lib/picsolve_docker_builder/frame.rb', line 141
def build
docker_build
end
|
#build_dir ⇒ Object
224
225
226
|
# File 'lib/picsolve_docker_builder/frame.rb', line 224
def build_dir
'/_build'
end
|
#build_mode ⇒ Object
44
45
46
47
48
49
50
|
# File 'lib/picsolve_docker_builder/frame.rb', line 44
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
220
221
222
|
# File 'lib/picsolve_docker_builder/frame.rb', line 220
def build_user
'build'
end
|
#build_user_home ⇒ Object
216
217
218
|
# File 'lib/picsolve_docker_builder/frame.rb', line 216
def build_user_home
'/home/build'
end
|
#build_user_uid ⇒ Object
212
213
214
|
# File 'lib/picsolve_docker_builder/frame.rb', line 212
def build_user_uid
Process.uid.to_s
end
|
#container ⇒ Object
228
229
230
|
# File 'lib/picsolve_docker_builder/frame.rb', line 228
def container
@container ||= create_container
end
|
#create_container ⇒ Object
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'lib/picsolve_docker_builder/frame.rb', line 232
def create_container
command = ['/bin/sleep', '3600']
c = Docker::Container.create(
'Image' => asset_image.id,
'Cmd' => command,
'OpenStdin' => false,
'WorkingDir' => '/_build'
)
at_exit do
stop
end
log.debug "created a new container image=#{image_name} " \
"id=#{c.id} cmd=#{command}"
c
end
|
#create_logger ⇒ Object
288
289
290
291
292
|
# File 'lib/picsolve_docker_builder/frame.rb', line 288
def create_logger
log = Logger.new(STDOUT)
log.level = Logger::DEBUG
log
end
|
#default_config ⇒ Object
20
21
22
|
# File 'lib/picsolve_docker_builder/frame.rb', line 20
def default_config
{ 'docker' => {} }
end
|
#dest_image_name ⇒ Object
248
249
250
|
# File 'lib/picsolve_docker_builder/frame.rb', line 248
def dest_image_name
config['docker']['image_name']
end
|
#docker_build ⇒ Object
133
134
135
136
137
138
139
|
# File 'lib/picsolve_docker_builder/frame.rb', line 133
def docker_build
dockerfile
log.info "start docker image building with path #{base_dir}"
@docker_build = docker_build_build
end
|
#docker_build_build ⇒ Object
123
124
125
126
127
128
129
130
131
|
# File 'lib/picsolve_docker_builder/frame.rb', line 123
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
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/picsolve_docker_builder/frame.rb', line 149
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
160
161
162
|
# File 'lib/picsolve_docker_builder/frame.rb', line 160
def dockerfile_exists?
File.exist? dockerfile_path
end
|
#dockerfile_hooks_asset_build_early ⇒ Object
64
65
66
67
68
|
# File 'lib/picsolve_docker_builder/frame.rb', line 64
def dockerfile_hooks_asset_build_early
config['docker']['dockerfile_hooks']['asset_build']['early']
rescue NoMethodError
''
end
|
#dockerfile_hooks_asset_build_late ⇒ Object
70
71
72
73
74
|
# File 'lib/picsolve_docker_builder/frame.rb', line 70
def dockerfile_hooks_asset_build_late
config['docker']['dockerfile_hooks']['asset_build']['late']
rescue NoMethodError
''
end
|
#dockerfile_hooks_docker_build_early ⇒ Object
52
53
54
55
56
|
# File 'lib/picsolve_docker_builder/frame.rb', line 52
def dockerfile_hooks_docker_build_early
config['docker']['dockerfile_hooks']['docker_build']['early']
rescue NoMethodError
''
end
|
#dockerfile_hooks_docker_build_late ⇒ Object
58
59
60
61
62
|
# File 'lib/picsolve_docker_builder/frame.rb', line 58
def dockerfile_hooks_docker_build_late
config['docker']['dockerfile_hooks']['docker_build']['late']
rescue NoMethodError
''
end
|
#dockerfile_path ⇒ Object
145
146
147
|
# File 'lib/picsolve_docker_builder/frame.rb', line 145
def dockerfile_path
File.join(base_dir, 'Dockerfile')
end
|
#dockerfile_template ⇒ Object
164
165
166
|
# File 'lib/picsolve_docker_builder/frame.rb', line 164
def dockerfile_template
fail NotImplementedError
end
|
#dockerignore_template ⇒ Object
168
169
170
|
# File 'lib/picsolve_docker_builder/frame.rb', line 168
def dockerignore_template
fail NotImplementedError
end
|
#execute(cmd) ⇒ Object
24
25
26
27
28
29
|
# File 'lib/picsolve_docker_builder/frame.rb', line 24
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
31
32
33
34
35
36
37
38
39
40
41
42
|
# File 'lib/picsolve_docker_builder/frame.rb', line 31
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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
# File 'lib/picsolve_docker_builder/frame.rb', line 264
def fetch_asset_image
log.debug "pulling image '#{image_name}' from registry"
dockerfile_asset = <<EOS
FROM #{image_name}
MAINTAINER Picsolve Onlineops <[email protected]>
#{dockerfile_hooks_asset_build_early}
RUN useradd -d #{build_user_home} -u #{build_user_uid} #{build_user}
#{dockerfile_hooks_asset_build_late}
EOS
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
252
253
254
255
256
257
258
259
260
261
262
|
# File 'lib/picsolve_docker_builder/frame.rb', line 252
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
76
77
78
79
80
|
# File 'lib/picsolve_docker_builder/frame.rb', line 76
def jenkins_build_number
n = ENV['BUILD_NUMBER']
return nil if n.nil?
n.to_i
end
|
#log ⇒ Object
294
295
296
|
# File 'lib/picsolve_docker_builder/frame.rb', line 294
def log
@logger ||= create_logger
end
|
#push ⇒ Object
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/picsolve_docker_builder/frame.rb', line 100
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
|
#start ⇒ Object
180
181
182
183
184
|
# File 'lib/picsolve_docker_builder/frame.rb', line 180
def start
container.start('Binds' => volumes)
log.debug "started container id=#{container.id} volumes=#{volumes}"
end
|
#stop ⇒ Object
186
187
188
189
190
191
192
193
|
# File 'lib/picsolve_docker_builder/frame.rb', line 186
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
88
89
90
91
92
93
94
95
96
97
98
|
# File 'lib/picsolve_docker_builder/frame.rb', line 88
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
|
82
83
84
85
86
|
# File 'lib/picsolve_docker_builder/frame.rb', line 82
def tags
t = ['latest']
t << "jenkins-#{jenkins_build_number}" unless jenkins_build_number.nil?
t
end
|
#validate_config(c) ⇒ Object
172
173
174
|
# File 'lib/picsolve_docker_builder/frame.rb', line 172
def validate_config(c)
validate_config_docker(c)
end
|
#validate_config_docker(c) ⇒ Object
176
177
178
|
# File 'lib/picsolve_docker_builder/frame.rb', line 176
def validate_config_docker(c)
c
end
|
#volume_workspace ⇒ Object
195
196
197
198
199
200
|
# File 'lib/picsolve_docker_builder/frame.rb', line 195
def volume_workspace
[
base_dir,
build_dir
]
end
|
#volumes ⇒ Object
206
207
208
209
210
|
# File 'lib/picsolve_docker_builder/frame.rb', line 206
def volumes
volumes_array.map do |volume|
volume.join ':'
end
end
|
#volumes_array ⇒ Object
202
203
204
|
# File 'lib/picsolve_docker_builder/frame.rb', line 202
def volumes_array
[volume_workspace]
end
|