ood_packaging 0.0.1.r2.0

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.
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ood_packaging/utils'
4
+ require 'rake'
5
+ require 'rake/file_utils'
6
+
7
+ # Build the packaging build boxes
8
+ class OodPackaging::BuildBox
9
+ include OodPackaging::Utils
10
+ include FileUtils
11
+
12
+ BASE_IMAGES = {
13
+ 'el7' => 'centos:7',
14
+ 'el8' => 'rockylinux/rockylinux:8',
15
+ 'ubuntu-20.04' => 'ubuntu:20.04'
16
+ }.freeze
17
+
18
+ CODENAMES = {
19
+ 'ubuntu-20.04' => 'focal'
20
+ }.freeze
21
+
22
+ def initialize(config = {})
23
+ @config = config
24
+ raise ArgumentError, 'Must provide dist' if dist.nil?
25
+
26
+ # rubocop:disable Style/GuardClause
27
+ unless valid_dist?(dist)
28
+ raise ArgumentError, "Invalid dist selected: #{dist}. Valid choices are #{valid_dists.join(' ')}"
29
+ end
30
+ # rubocop:enable Style/GuardClause
31
+ end
32
+
33
+ def dist
34
+ @dist ||= ENV['OOD_PACKAGING_DIST'] || @config[:dist]
35
+ end
36
+
37
+ def rpm?
38
+ dist.start_with?('el')
39
+ end
40
+
41
+ def deb?
42
+ !rpm?
43
+ end
44
+
45
+ def dnf?
46
+ return false unless rpm?
47
+ return false if dist == 'el7'
48
+
49
+ true
50
+ end
51
+
52
+ def scl?
53
+ return true if dist == 'el7'
54
+
55
+ false
56
+ end
57
+
58
+ def package_manager
59
+ return 'apt' if deb?
60
+ return 'dnf' if dnf?
61
+
62
+ 'yum'
63
+ end
64
+
65
+ def valid_dist?(value)
66
+ BASE_IMAGES.key?(value)
67
+ end
68
+
69
+ def valid_dists
70
+ BASE_IMAGES.keys
71
+ end
72
+
73
+ def base_image
74
+ @base_image ||= BASE_IMAGES[dist]
75
+ end
76
+
77
+ def codename
78
+ @codename ||= CODENAMES[dist]
79
+ end
80
+
81
+ def build_dir
82
+ File.join(File.dirname(__FILE__), 'build_box/docker-image')
83
+ end
84
+
85
+ def image_registry
86
+ @config[:builx_box_registry] || ENV['OOD_PACKAGING_BUILD_BOX_REGISTRY'] || nil
87
+ end
88
+
89
+ def image_org
90
+ @config[:build_box_org] || ENV['OOD_PACKAGING_BUILX_BOX_ORG'] || 'ohiosupercomputer'
91
+ end
92
+
93
+ def image_name
94
+ @config[:builx_box_name] || ENV['OOD_PACKAGING_BUILD_BOX_NAME'] || 'ood-buildbox'
95
+ end
96
+
97
+ def image_version
98
+ (ENV['OOD_PACKAGING_BUILD_BOX_VERSION'] || OodPackaging::VERSION).gsub(/^v/, '')
99
+ end
100
+
101
+ def image_tag
102
+ [image_registry, image_org, "#{image_name}-#{dist}:#{image_version}"].compact.join('/')
103
+ end
104
+
105
+ def build_gem
106
+ gem = File.join(proj_root, 'pkg', "ood_packaging-#{OodPackaging::VERSION}.gem")
107
+ Rake::Task['build'].invoke
108
+ sh "rm -f #{build_dir}/*.gem"
109
+ sh "cp #{gem} #{build_dir}/"
110
+ end
111
+
112
+ def dockerfile
113
+ template_file('build_box/docker-image/Dockerfile.erb')
114
+ end
115
+
116
+ def scripts
117
+ template_file('build_box/docker-image/inituidgid.sh.erb')
118
+ template_file('build_box/docker-image/install.sh.erb')
119
+ end
120
+
121
+ def build!
122
+ scripts
123
+ cmd = [container_runtime, 'build']
124
+ cmd.concat ['--tag', image_tag]
125
+ cmd.concat [ENV['OOD_PACKAGING_BUILD_BOX_ARGS']] if ENV['OOD_PACKAGING_BUILD_BOX_ARGS']
126
+ cmd.concat ['-f', dockerfile]
127
+ cmd.concat [build_dir]
128
+ build_gem
129
+ sh cmd.join(' ')
130
+ end
131
+
132
+ def push!
133
+ sh [container_runtime, 'push', image_tag].join(' ')
134
+ end
135
+
136
+ def pull!
137
+ sh [container_runtime, 'pull', image_tag].join(' ')
138
+ end
139
+
140
+ def save!(path)
141
+ sh [container_runtime, 'save', image_tag, '| gzip >', path].join(' ')
142
+ end
143
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Handle options for OodPackaging
4
+ module OodPackaging
5
+ OPTIONS = [:package, :version, :dist, :work_dir, :clean_work_dir, :output_dir, :clean_output_dir, :tar,
6
+ :tar_only, :skip_download, :gpg_sign, :gpg_name, :gpg_pubkey, :gpg_private_key, :gpg_passphrase,
7
+ :debug, :attach].freeze
8
+ end
@@ -0,0 +1,326 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ood_packaging/build_box'
4
+ require 'ood_packaging/utils'
5
+ require 'ood_packaging/string_ext'
6
+ require 'English'
7
+ require 'pathname'
8
+ require 'ostruct'
9
+ require 'securerandom'
10
+ require 'rake'
11
+ require 'rake/file_utils'
12
+
13
+ # The interface to build packages using containers
14
+ class OodPackaging::Package
15
+ include OodPackaging::Utils
16
+ include FileUtils
17
+
18
+ attr_accessor :build_box
19
+
20
+ def initialize(config = {})
21
+ @config = config
22
+ @config[:dist] = 'el8' if tar_only?
23
+ @build_box = OodPackaging::BuildBox.new(config)
24
+ raise ArgumentError, 'Package is required' if package.nil?
25
+ raise ArgumentError, 'Version is required' if version.nil?
26
+ raise ArgumentError, "Package #{package} is not a directory" unless Dir.exist?(package)
27
+ raise ArgumentError, "Package #{package} is not an absolute path" unless (Pathname.new package).absolute?
28
+ end
29
+
30
+ def container_name
31
+ @container_name ||= SecureRandom.uuid
32
+ end
33
+
34
+ def debug?
35
+ return true if ENV['OOD_PACKAGING_DEBUG'] == 'true'
36
+
37
+ @config[:debug].nil? ? false : @config[:debug]
38
+ end
39
+
40
+ def cmd_suffix
41
+ return '' if debug?
42
+
43
+ ' 2>/dev/null 1>/dev/null'
44
+ end
45
+
46
+ def attach?
47
+ return true if ENV['OOD_PACKAGING_ATTACH'] == 'true'
48
+
49
+ @config[:attach].nil? ? false : @config[:attach]
50
+ end
51
+
52
+ def work_dir
53
+ @work_dir ||= File.expand_path(@config[:work_dir])
54
+ end
55
+
56
+ def clean_work_dir
57
+ return false if ENV['OOD_PACKAGING_CLEAN_WORK_DIR'] == 'false'
58
+
59
+ @config[:clean_work_dir].nil? ? true : @config[:clean_work_dir]
60
+ end
61
+
62
+ def output_dir
63
+ @output_dir ||= File.expand_path(@config[:output_dir])
64
+ end
65
+
66
+ def clean_output_dir
67
+ return false if ENV['OOD_PACKAGING_CLEAN_OUTPUT_DIR'] == 'false'
68
+
69
+ @config[:clean_output_dir].nil? ? true : @config[:clean_output_dir]
70
+ end
71
+
72
+ def package
73
+ @config[:package]
74
+ end
75
+
76
+ def version
77
+ @config[:version]
78
+ end
79
+
80
+ def tar_version
81
+ version.gsub(/^v/, '')
82
+ end
83
+
84
+ def tar?
85
+ @config[:tar].nil? ? build_box.deb? : @config[:tar]
86
+ end
87
+
88
+ def tar_only?
89
+ @config[:tar_only].nil? ? false : @config[:tar_only]
90
+ end
91
+
92
+ def package_name
93
+ name = File.basename(package)
94
+ case name
95
+ when /deb|rpm/
96
+ name = if File.basename(File.dirname(package)) == 'packages'
97
+ File.basename(File.dirname(File.dirname(package)))
98
+ else
99
+ File.basename(File.dirname(package))
100
+ end
101
+ when 'packaging'
102
+ name = File.basename(File.dirname(package))
103
+ end
104
+ name
105
+ end
106
+
107
+ def gpg_files
108
+ [
109
+ OpenStruct.new(private_key: @config[:gpg_private_key], passphrase: @config[:gpg_passphrase]),
110
+ OpenStruct.new(private_key: ENV['OOD_PACKAGING_GPG_PRIVATE_KEY'],
111
+ passphrase: ENV['OOD_PACKAGING_GPG_PASSPHRASE'])
112
+ ].each do |gpg|
113
+ next if gpg.private_key.nil? || gpg.passphrase.nil?
114
+ return gpg if File.exist?(gpg.private_key) && File.exist?(gpg.passphrase)
115
+ end
116
+ nil
117
+ end
118
+
119
+ def gpg_sign
120
+ return false if ENV['OOD_PACKAGING_GPG_SIGN'].to_s == 'false'
121
+ return false if @config[:gpg_sign] == false
122
+
123
+ !gpg_files.nil?
124
+ end
125
+
126
+ def default_gpg_name
127
+ 'OnDemand Release Signing Key'
128
+ end
129
+
130
+ def gpg_name
131
+ @config[:gpg_name].nil? ? default_gpg_name : @config[:gpg_name]
132
+ end
133
+
134
+ def container_init
135
+ '/sbin/init'
136
+ end
137
+
138
+ def tar_path
139
+ if build_box.deb?
140
+ path = File.join(package, 'deb')
141
+ return path if Dir.exist?(path)
142
+ end
143
+
144
+ package
145
+ end
146
+
147
+ def tar_name
148
+ version = if build_box.rpm?
149
+ rpm_version
150
+ else
151
+ deb_version
152
+ end
153
+ "#{package_name}-#{version}"
154
+ end
155
+
156
+ def rpm_tar_dest_dir
157
+ [
158
+ File.join(package, 'rpm'),
159
+ File.join(package, 'packaging/rpm'),
160
+ File.join(package, 'packaging')
161
+ ].each do |dir|
162
+ return dir if Dir.exist?(dir)
163
+ end
164
+ File.join(package, 'packaging/rpm')
165
+ end
166
+
167
+ def rpm_version
168
+ tar_version
169
+ end
170
+
171
+ def deb_tar_dest_dir
172
+ dir = File.join(package, 'deb')
173
+ return File.join(dir, 'build') if Dir.exist?(dir)
174
+
175
+ File.join(package, 'build')
176
+ end
177
+
178
+ def deb_version
179
+ tar_version.gsub('-', '.')
180
+ end
181
+
182
+ def exec_launchers
183
+ [
184
+ File.join(ctr_scripts_dir, 'inituidgid.sh'),
185
+ File.join(ctr_scripts_dir, 'setuser.rb'),
186
+ ctr_user
187
+ ]
188
+ end
189
+
190
+ def exec_rake
191
+ cmd = []
192
+ cmd.concat exec_launchers if docker_runtime?
193
+ cmd.concat ['scl', 'enable', scl_ruby, '--'] if podman_runtime? && build_box.scl?
194
+ cmd.concat [File.join(ctr_scripts_dir, 'rake')]
195
+ cmd.concat ['-q'] unless debug?
196
+ cmd.concat ['-f', File.join(ctr_scripts_dir, 'Rakefile'), 'ood_packaging:package:build']
197
+ cmd
198
+ end
199
+
200
+ def exec_attach
201
+ cmd = []
202
+ cmd.concat exec_launchers if docker_runtime?
203
+ cmd.concat ['/bin/bash']
204
+ cmd
205
+ end
206
+
207
+ def container_mounts
208
+ args = []
209
+ args.concat ['-v', "#{package}:/package:ro"]
210
+ args.concat ['-v', "#{@config[:gpg_pubkey]}:/gpg.pub:ro"] if @config[:gpg_pubkey]
211
+ args.concat ['-v', "#{work_dir}:/work"]
212
+ args.concat ['-v', "#{output_dir}:/output"]
213
+ if gpg_sign
214
+ args.concat ['-v', "#{gpg_files.private_key}:#{gpg_private_key}:ro"]
215
+ args.concat ['-v', "#{gpg_files.passphrase}:#{gpg_passphrase}:ro"]
216
+ end
217
+ args
218
+ end
219
+
220
+ def clean!
221
+ sh "rm -rf #{work_dir}", verbose: debug? if clean_work_dir
222
+ sh "rm -rf #{output_dir}", verbose: debug? if clean_output_dir
223
+ end
224
+
225
+ def bootstrap!
226
+ sh "mkdir -p #{work_dir}", verbose: debug?
227
+ sh "mkdir -p #{output_dir}", verbose: debug?
228
+ end
229
+
230
+ def tar!
231
+ cmd = ['git', 'ls-files', '.', '|', tar, '-c']
232
+ if build_box.rpm?
233
+ dir = rpm_tar_dest_dir
234
+ else
235
+ dir = deb_tar_dest_dir.tap { |p| sh "mkdir -p #{p}" }
236
+ cmd.concat ["--transform 'flags=r;s,packaging/deb,debian,'"]
237
+ end
238
+ tar_file = "#{dir}/#{tar_name}.tar.gz"
239
+ cmd.concat ["--transform 's,^,#{tar_name}/,'"]
240
+ cmd.concat ['-T', '-', '|', "gzip > #{tar_file}"]
241
+
242
+ sh "rm #{tar_file}" if File.exist?(tar_file)
243
+ puts "Create tar archive #{tar_file}".blue
244
+ Dir.chdir(tar_path) do
245
+ sh cmd.join(' '), verbose: debug?
246
+ end
247
+ end
248
+
249
+ def run!
250
+ if tar_only?
251
+ tar!
252
+ return
253
+ end
254
+ clean!
255
+ bootstrap!
256
+ tar! if tar?
257
+ container_start!
258
+ container_exec!(exec_rake)
259
+ puts "Build SUCCESS: package=#{package} dist=#{build_box.dist}".green
260
+ rescue RuntimeError
261
+ puts "Build FAILED package=#{package} dist=#{build_box.dist}".red
262
+ raise
263
+ ensure
264
+ container_exec!(exec_attach, ['-i', '-t']) if attach?
265
+ container_kill! if container_running? && !attach?
266
+ end
267
+
268
+ def container_running?
269
+ cmd = "#{container_runtime} inspect #{container_name} 2>/dev/null 1>/dev/null"
270
+ puts cmd if debug?
271
+ `#{cmd}`
272
+ $CHILD_STATUS.success?
273
+ end
274
+
275
+ def container_start!
276
+ cmd = [container_runtime, 'run', '--detach', '--rm']
277
+ cmd.concat ['--name', container_name]
278
+ cmd.concat rt_specific_flags
279
+ cmd.concat container_mounts
280
+ cmd.concat [build_box.image_tag]
281
+ cmd.concat [container_init]
282
+ cmd.concat ['1>/dev/null'] unless debug?
283
+ puts "Starting container #{container_name} using image #{build_box.image_tag}".blue
284
+ sh cmd.join(' '), verbose: debug?
285
+ end
286
+
287
+ def container_exec!(exec_cmd, extra_args = [])
288
+ cmd = [container_runtime, 'exec']
289
+ cmd.concat extra_args
290
+ container_env.each_pair do |k, v|
291
+ cmd.concat ['-e', "'#{k}=#{v}'"] unless v.nil?
292
+ end
293
+ cmd.concat [container_name]
294
+ cmd.concat exec_cmd
295
+ puts "Build STARTED: package=#{package} dist=#{build_box.dist} exec=#{exec_cmd[-1]}".blue
296
+ sh cmd.join(' '), verbose: debug?
297
+ true
298
+ rescue RuntimeError
299
+ container_kill! if container_running? && !attach?
300
+ raise
301
+ end
302
+
303
+ def container_kill!
304
+ puts "Killing container #{container_name}".blue
305
+ cmd = [container_runtime, 'kill', container_name]
306
+ cmd.concat [cmd_suffix] unless debug?
307
+ sh cmd.join(' '), verbose: debug?
308
+ end
309
+
310
+ def container_env
311
+ env = {
312
+ 'DIST' => build_box.dist,
313
+ 'PACKAGE' => package_name,
314
+ 'VERSION' => version,
315
+ 'TAR_NAME' => "#{tar_name}.tar.gz",
316
+ 'GPG_SIGN' => gpg_sign,
317
+ 'GPG_NAME' => gpg_name,
318
+ 'SKIP_DOWNLOAD' => @config[:skip_download],
319
+ 'OOD_UID' => Process.uid,
320
+ 'OOD_GID' => Process.gid,
321
+ 'DEBUG' => debug?
322
+ }
323
+ env['GPG_PUBKEY'] = '/gpg.pub' if @config[:gpg_pubkey]
324
+ env
325
+ end
326
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ood_packaging'
4
+ require 'rake'
5
+ require 'rake/tasklib'
6
+
7
+ # Define OodPackaging rake task library
8
+ class OodPackaging::RakeTask < ::Rake::TaskLib
9
+ include ::Rake::DSL if defined?(::Rake::DSL)
10
+ include OodPackaging::Utils
11
+
12
+ OodPackaging::OPTIONS.each do |o|
13
+ attr_accessor o.to_sym
14
+ end
15
+
16
+ def initialize(*args, &task_block)
17
+ super()
18
+ @name = args.shift || :package
19
+
20
+ define(args, &task_block)
21
+ end
22
+
23
+ def define(args, &task_block)
24
+ desc 'Build package' unless ::Rake.application.last_description
25
+
26
+ task @name, *args do |_, task_args|
27
+ task_block&.call(*[self, task_args].slice(0, task_block.arity))
28
+ config = {}
29
+ OodPackaging::OPTIONS.each do |o|
30
+ v = instance_variable_get("@#{o}")
31
+ config[o.to_sym] = v unless v.nil?
32
+ end
33
+ OodPackaging::Package.new(config).run!
34
+ end
35
+ end
36
+
37
+ def name
38
+ @name.to_s
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # https://stackoverflow.com/a/11482430
4
+ class String
5
+ def colorize(code)
6
+ "\e[#{code}m#{self}\e[0m"
7
+ end
8
+
9
+ def red
10
+ colorize(31)
11
+ end
12
+
13
+ def green
14
+ colorize(32)
15
+ end
16
+
17
+ def blue
18
+ colorize(34)
19
+ end
20
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ood_packaging'
4
+ require 'ood_packaging/rake_task'
5
+ require 'ood_packaging/utils'
6
+
7
+ namespace :ood_packaging do
8
+ include OodPackaging::Utils
9
+
10
+ desc 'Set version'
11
+ task :version, [:version] do |_task, args|
12
+ version_file = File.join(proj_root, 'lib/ood_packaging/version.rb')
13
+ version = args[:version].gsub(/^v/, '')
14
+ sh "#{sed} -i -r \"s| VERSION =.*| VERSION = '#{version}'|g\" #{version_file}"
15
+ sh 'bundle install'
16
+ end
17
+
18
+ namespace :buildbox do
19
+ desc 'Build buildbox image'
20
+ task :build, [:dist] do |_task, args|
21
+ @build_box = OodPackaging::BuildBox.new(args)
22
+ @build_box.build!
23
+ end
24
+
25
+ desc 'Push buildbox image'
26
+ task :push, [:dist] do |_task, args|
27
+ @build_box = OodPackaging::BuildBox.new(args)
28
+ @build_box.push!
29
+ end
30
+
31
+ desc 'Pull buildbox image'
32
+ task :pull, [:dist] do |_task, args|
33
+ @build_box = OodPackaging::BuildBox.new(args)
34
+ @build_box.pull!
35
+ end
36
+
37
+ desc 'Save buildbox image'
38
+ task :save, [:dist, :path] do |_task, args|
39
+ @build_box = OodPackaging::BuildBox.new(args)
40
+ @build_box.save!(args[:path])
41
+ end
42
+ end
43
+
44
+ namespace :package do
45
+ desc 'Build a package (INSIDE CONTAINER ONLY)'
46
+ task :build do
47
+ OodPackaging::Build.new.run!
48
+ end
49
+
50
+ OodPackaging::RakeTask.new(:internal, [:package, :dist]) do |t, args|
51
+ name = args[:package].split(':').last
52
+ t.package = File.join(proj_root, 'packages', name)
53
+ dist = args[:dist] || ENV['OOD_PACKAGING_DIST']
54
+ t.dist = dist
55
+ t.version = OodPackaging.package_version(name, dist)
56
+ t.work_dir = File.join(proj_root, 'tmp/work')
57
+ t.output_dir = File.join(proj_root, 'tmp/output')
58
+ end
59
+
60
+ desc 'Package ondemand-release'
61
+ task :'ondemand-release', [:dist] do |t, args|
62
+ ENV['OOD_PACKAGING_GPG_SIGN'] = 'false'
63
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
64
+ end
65
+
66
+ desc 'Package ondemand-release-latest'
67
+ task :'ondemand-release-latest', [:dist] do |t, args|
68
+ ENV['OOD_PACKAGING_GPG_SIGN'] = 'false'
69
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
70
+ end
71
+
72
+ desc 'Package ondemand-release'
73
+ task :'ondemand-runtime', [:dist] do |t, args|
74
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
75
+ end
76
+
77
+ desc 'Package passenger'
78
+ task :passenger, [:dist] do |t, args|
79
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
80
+ end
81
+
82
+ desc 'Package cjose'
83
+ task :cjose, [:dist] do |t, args|
84
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
85
+ end
86
+
87
+ desc 'Package mod_auth_openidc'
88
+ task :mod_auth_openidc, [:dist] do |t, args|
89
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
90
+ end
91
+
92
+ desc 'Package sqlite'
93
+ task :sqlite, [:dist] do |t, args|
94
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
95
+ end
96
+
97
+ desc 'Package ondemand_exporter'
98
+ task :ondemand_exporter, [:dist] do |t, args|
99
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
100
+ end
101
+
102
+ desc 'Package ondemand-compute'
103
+ task :'ondemand-compute', [:dist] do |t, args|
104
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
105
+ end
106
+
107
+ desc 'Package python-websockify'
108
+ task :'python-websockify', [:dist] do |t, args|
109
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
110
+ end
111
+
112
+ desc 'Package turbovnc'
113
+ task :turbovnc, [:dist] do |t, args|
114
+ Rake::Task['ood_packaging:package:internal'].invoke(t.name, args[:dist])
115
+ end
116
+ end
117
+ end