Class: OodPackaging::Package

Inherits:
Object
  • Object
show all
Includes:
FileUtils, Utils
Defined in:
lib/ood_packaging/package.rb

Overview

The interface to build packages using containers

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#container_runtime, #ctr_gems_dir, #ctr_gpg_dir, #ctr_home, #ctr_rpmmacros, #ctr_scripts_dir, #ctr_user, #docker_runtime?, #gpg_passphrase, #gpg_private_key, #nodejs_version, #ondemand_repo_version, #podman_runtime?, #proj_root, #rt_specific_flags, #ruby_version, #scl_ruby, #sed, #tar, #template_file

Constructor Details

#initialize(config = {}) ⇒ Package

Returns a new instance of Package.

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ood_packaging/package.rb', line 20

def initialize(config = {})
  @config = config
  @config[:dist] = 'el8' if tar_only?
  @build_box = OodPackaging::BuildBox.new(config)
  @clean_work_dir = config[:clean_work_dir].nil? ? true : config[:clean_work_dir]
  @clean_output_dir = config[:clean_output_dir].nil? ? true : config[:clean_output_dir]
  raise ArgumentError, 'Package is required' if package.nil?
  raise ArgumentError, 'Version is required' if version.nil?
  raise ArgumentError, "Package #{package} is not a directory" unless Dir.exist?(package)
  raise ArgumentError, "Package #{package} is not an absolute path" unless (Pathname.new package).absolute?
end

Instance Attribute Details

#build_boxObject

Returns the value of attribute build_box.



18
19
20
# File 'lib/ood_packaging/package.rb', line 18

def build_box
  @build_box
end

Instance Method Details

#attach?Boolean

Returns:

  • (Boolean)


42
43
44
45
46
# File 'lib/ood_packaging/package.rb', line 42

def attach?
  return true if ENV['OOD_PACKAGING_ATTACH'] == 'true'

  @config[:attach].nil? ? false : @config[:attach]
end

#bootstrap!Object



207
208
209
210
# File 'lib/ood_packaging/package.rb', line 207

def bootstrap!
  sh "mkdir -p #{work_dir}", verbose: debug
  sh "mkdir -p #{output_dir}", verbose: debug
end

#clean!Object



202
203
204
205
# File 'lib/ood_packaging/package.rb', line 202

def clean!
  sh "rm -rf #{work_dir}", verbose: debug if @clean_work_dir
  sh "rm -rf #{output_dir}", verbose: debug if @clean_output_dir
end

#container_envObject



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/ood_packaging/package.rb', line 288

def container_env
  env = {
    'DIST'          => build_box.dist,
    'PACKAGE'       => package_name,
    'VERSION'       => version,
    'TAR_NAME'      => "#{tar_name}.tar.gz",
    'GPG_SIGN'      => gpg_sign,
    'GPG_NAME'      => gpg_name,
    'SKIP_DOWNLOAD' => @config[:skip_download],
    'OOD_UID'       => Process.uid,
    'OOD_GID'       => Process.gid,
    'DEBUG'         => debug
  }
  env['GPG_PUBKEY'] = '/gpg.pub' if @config[:gpg_pubkey]
  env
end

#container_exec!(exec_cmd, extra_args = []) ⇒ Object



269
270
271
272
273
274
275
276
277
278
279
# File 'lib/ood_packaging/package.rb', line 269

def container_exec!(exec_cmd, extra_args = [])
  cmd = [container_runtime, 'exec']
  cmd.concat extra_args
  container_env.each_pair do |k, v|
    cmd.concat ['-e', "'#{k}=#{v}'"] unless v.nil?
  end
  cmd.concat [container_name]
  cmd.concat exec_cmd
  puts "Build STARTED: package=#{package} dist=#{build_box.dist} exec=#{exec_cmd[-1]}".blue
  sh cmd.join(' '), verbose: debug
end

#container_initObject



116
117
118
# File 'lib/ood_packaging/package.rb', line 116

def container_init
  '/sbin/init'
end

#container_kill!Object



281
282
283
284
285
286
# File 'lib/ood_packaging/package.rb', line 281

def container_kill!
  puts "Killing container #{container_name}".blue
  cmd = [container_runtime, 'kill', container_name]
  cmd.concat ['1>/dev/null', '2>/dev/null'] unless debug
  sh cmd.join(' '), verbose: debug
end

#container_mountsObject



189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/ood_packaging/package.rb', line 189

def container_mounts
  args = []
  args.concat ['-v', "#{package}:/package:ro"]
  args.concat ['-v', "#{@config[:gpg_pubkey]}:/gpg.pub:ro"] if @config[:gpg_pubkey]
  args.concat ['-v', "#{work_dir}:/work"]
  args.concat ['-v', "#{output_dir}:/output"]
  if gpg_sign
    args.concat ['-v', "#{gpg_files.private_key}:#{gpg_private_key}:ro"]
    args.concat ['-v', "#{gpg_files.passphrase}:#{gpg_passphrase}:ro"]
  end
  args
end

#container_nameObject



32
33
34
# File 'lib/ood_packaging/package.rb', line 32

def container_name
  @container_name ||= SecureRandom.uuid
end

#container_running?Boolean

Returns:

  • (Boolean)


252
253
254
255
# File 'lib/ood_packaging/package.rb', line 252

def container_running?
  `#{container_runtime} inspect #{container_name} 2>/dev/null 1>/dev/null`
  $CHILD_STATUS.success?
end

#container_start!Object



257
258
259
260
261
262
263
264
265
266
267
# File 'lib/ood_packaging/package.rb', line 257

def container_start!
  cmd = [container_runtime, 'run', '--detach', '--rm']
  cmd.concat ['--name', container_name]
  cmd.concat rt_specific_flags
  cmd.concat container_mounts
  cmd.concat [build_box.image_tag]
  cmd.concat [container_init]
  cmd.concat ['1>/dev/null'] unless debug
  puts "Starting container #{container_name} using image #{build_box.image_tag}".blue
  sh cmd.join(' '), verbose: debug
end

#deb_tar_dest_dirObject



153
154
155
156
157
158
# File 'lib/ood_packaging/package.rb', line 153

def deb_tar_dest_dir
  dir = File.join(package, 'deb')
  return File.join(dir, 'build') if Dir.exist?(dir)

  File.join(package, 'build')
end

#deb_versionObject



160
161
162
# File 'lib/ood_packaging/package.rb', line 160

def deb_version
  tar_version.gsub('-', '.')
end

#debugObject



36
37
38
39
40
# File 'lib/ood_packaging/package.rb', line 36

def debug
  return true if ENV['OOD_PACKAGING_DEBUG'] == 'true'

  @config[:debug].nil? ? false : @config[:debug]
end

#exec_attachObject



182
183
184
185
186
187
# File 'lib/ood_packaging/package.rb', line 182

def exec_attach
  cmd = []
  cmd.concat exec_launchers if docker_runtime?
  cmd.concat ['/bin/bash']
  cmd
end

#exec_launchersObject



164
165
166
167
168
169
170
# File 'lib/ood_packaging/package.rb', line 164

def exec_launchers
  [
    File.join(ctr_scripts_dir, 'inituidgid.sh'),
    File.join(ctr_scripts_dir, 'setuser.rb'),
    ctr_user
  ]
end

#exec_rakeObject



172
173
174
175
176
177
178
179
180
# File 'lib/ood_packaging/package.rb', line 172

def exec_rake
  cmd = []
  cmd.concat exec_launchers if docker_runtime?
  cmd.concat ['scl', 'enable', scl_ruby, '--'] if podman_runtime? && build_box.scl?
  cmd.concat [File.join(ctr_scripts_dir, 'rake')]
  cmd.concat ['-q'] unless debug
  cmd.concat ['-f', File.join(ctr_scripts_dir, 'Rakefile'), 'ood_packaging:package:build']
  cmd
end

#gpg_filesObject



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ood_packaging/package.rb', line 91

def gpg_files
  [
    OpenStruct.new(private_key: File.join(proj_root, 'ondemand.sec'), passphrase: File.join(proj_root, '.gpgpass')),
    OpenStruct.new(private_key: File.join(package, 'ondemand.sec'), passphrase: File.join(package, '.gpgpass')),
    OpenStruct.new(private_key: @config[:gpg_private_key], passphrase: @config[:gpg_passphrase]),
    OpenStruct.new(private_key: ENV['OOD_PACKAGING_GPG_PRIVATE_KEY'],
                   passphrase:  ENV['OOD_PACKAGING_GPG_PASSPHRASE'])
  ].each do |gpg|
    next if gpg.private_key.nil? || gpg.passphrase.nil?
    return gpg if File.exist?(gpg.private_key) && File.exist?(gpg.passphrase)
  end
  nil
end

#gpg_nameObject



112
113
114
# File 'lib/ood_packaging/package.rb', line 112

def gpg_name
  @config[:gpg_name].nil? ? 'OnDemand Release Signing Key' : @config[:gpg_name]
end

#gpg_signObject



105
106
107
108
109
110
# File 'lib/ood_packaging/package.rb', line 105

def gpg_sign
  return false if ENV['OOD_PACKAGING_GPG_SIGN'].to_s == 'false'
  return false if @config[:gpg_sign] == false

  !gpg_files.nil?
end

#output_dirObject



52
53
54
# File 'lib/ood_packaging/package.rb', line 52

def output_dir
  @output_dir ||= File.expand_path(@config[:output_dir])
end

#packageObject



56
57
58
# File 'lib/ood_packaging/package.rb', line 56

def package
  @config[:package]
end

#package_nameObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ood_packaging/package.rb', line 76

def package_name
  name = File.basename(package)
  case name
  when /deb|rpm/
    name = if File.basename(File.dirname(package)) == 'packages'
             File.basename(File.dirname(File.dirname(package)))
           else
             File.basename(File.dirname(package))
           end
  when 'packaging'
    name = File.basename(File.dirname(package))
  end
  name
end

#rpm_tar_dest_dirObject



138
139
140
141
142
143
144
145
146
147
# File 'lib/ood_packaging/package.rb', line 138

def rpm_tar_dest_dir
  [
    File.join(package, 'rpm'),
    File.join(package, 'packaging/rpm'),
    File.join(package, 'packaging')
  ].each do |dir|
    return dir if Dir.exist?(dir)
  end
  File.join(package, 'packaging/rpm')
end

#rpm_versionObject



149
150
151
# File 'lib/ood_packaging/package.rb', line 149

def rpm_version
  tar_version
end

#run!Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/ood_packaging/package.rb', line 231

def run!
  if tar_only?
    tar!
    return
  end
  clean!
  bootstrap!
  tar! if tar?
  container_start!
  container_exec!(exec_rake)
rescue RuntimeError
  # ret = 1
  puts "Build FAILED package=#{package} dist=#{build_box.dist}".red
  raise
else
  puts "Build SUCCESS: package=#{package} dist=#{build_box.dist}".green
ensure
  container_exec!(exec_attach, ['-i', '-t']) if attach?
  container_kill! if container_running?
end

#tar!Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/ood_packaging/package.rb', line 212

def tar!
  cmd = ['git', 'ls-files', '.', '|', tar, '-c']
  if build_box.rpm?
    dir = rpm_tar_dest_dir
  else
    dir = deb_tar_dest_dir.tap { |p| sh "mkdir -p #{p}" }
    cmd.concat ["--transform 'flags=r;s,packaging/deb,debian,'"]
  end
  tar_file = "#{dir}/#{tar_name}.tar.gz"
  cmd.concat ["--transform 's,^,#{tar_name}/,'"]
  cmd.concat ['-T', '-', '|', "gzip > #{tar_file}"]

  sh "rm #{tar_file}" if File.exist?(tar_file)
  puts "Create tar archive #{tar_file}".blue
  Dir.chdir(tar_path) do
    sh cmd.join(' '), verbose: debug
  end
end

#tar?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/ood_packaging/package.rb', line 68

def tar?
  @config[:tar].nil? ? build_box.deb? : @config[:tar]
end

#tar_nameObject



129
130
131
132
133
134
135
136
# File 'lib/ood_packaging/package.rb', line 129

def tar_name
  version = if build_box.rpm?
              rpm_version
            else
              deb_version
            end
  "#{package_name}-#{version}"
end

#tar_only?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/ood_packaging/package.rb', line 72

def tar_only?
  @config[:tar_only].nil? ? false : @config[:tar_only]
end

#tar_pathObject



120
121
122
123
124
125
126
127
# File 'lib/ood_packaging/package.rb', line 120

def tar_path
  if build_box.deb?
    path = File.join(package, 'deb')
    return path if Dir.exist?(path)
  end

  package
end

#tar_versionObject



64
65
66
# File 'lib/ood_packaging/package.rb', line 64

def tar_version
  version.gsub(/^v/, '')
end

#versionObject



60
61
62
# File 'lib/ood_packaging/package.rb', line 60

def version
  @config[:version]
end

#work_dirObject



48
49
50
# File 'lib/ood_packaging/package.rb', line 48

def work_dir
  @work_dir ||= File.expand_path(@config[:work_dir])
end