cicd-builder 0.9.23 → 0.9.25
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +136 -0
- data/cicd-builder.gemspec +14 -12
- data/lib/cicd/builder.rb +23 -20
- data/lib/cicd/builder/mixlib/build.rb +144 -69
- data/lib/cicd/builder/mixlib/environment.rb +51 -17
- data/lib/cicd/builder/mixlib/errors.rb +35 -0
- data/lib/cicd/builder/mixlib/options.rb +14 -8
- data/lib/cicd/builder/mixlib/repo.rb +42 -383
- data/lib/cicd/builder/mixlib/repo/S3.rb +355 -0
- data/lib/cicd/builder/mixlib/repo/artifactory.rb +237 -0
- data/lib/cicd/builder/mixlib/repo/base.rb +102 -0
- data/lib/cicd/builder/mixlib/utils.rb +11 -1
- data/lib/cicd/builder/version.rb +1 -1
- metadata +132 -16
@@ -6,8 +6,8 @@ module CiCd
|
|
6
6
|
def checkEnvironment()
|
7
7
|
# [2013-12-30 Christo] Detect CI ...
|
8
8
|
unless ENV.has_key?('JENKINS_HOME')
|
9
|
-
|
10
|
-
|
9
|
+
@logger.error "Sorry, your CI environment is not supported at this time (2013-12-30) ... Christo De Lange\n"+
|
10
|
+
'This script is developed for Jenkins so either you are not using Jenkins or you ran me outside of the CI ecosystem ...'
|
11
11
|
return 99
|
12
12
|
end
|
13
13
|
|
@@ -15,13 +15,15 @@ module CiCd
|
|
15
15
|
map_keys = {}
|
16
16
|
|
17
17
|
@options[:env_keys].each { |k|
|
18
|
-
map_keys[k]= (not ENV.has_key?(k))
|
18
|
+
map_keys[k]= (not ENV.has_key?(k) or ENV[k].empty?)
|
19
19
|
}
|
20
20
|
missing = map_keys.keys.select{ |k| map_keys[k] }
|
21
21
|
|
22
22
|
if missing.count() > 0
|
23
|
-
ap missing
|
24
|
-
raise Exception.new("Need environment variables: #{missing}")
|
23
|
+
# ap missing
|
24
|
+
#raise Exception.new("Need these environment variables: #{missing}")
|
25
|
+
puts("Need these environment variables: #{missing.ai}")
|
26
|
+
return 1
|
25
27
|
end
|
26
28
|
0
|
27
29
|
end
|
@@ -61,7 +63,7 @@ module CiCd
|
|
61
63
|
|
62
64
|
if ENV.has_key?('VARIANT')
|
63
65
|
@vars[:variant] = "#{ENV['VARIANT']}"
|
64
|
-
|
66
|
+
end
|
65
67
|
|
66
68
|
if ENV.has_key?('BUILD_NUMBER')
|
67
69
|
@vars[:build_num] = "#{ENV['BUILD_NUMBER']}"
|
@@ -70,6 +72,7 @@ module CiCd
|
|
70
72
|
@vars[:return_code] = getLatest()
|
71
73
|
end
|
72
74
|
|
75
|
+
# ---------------------------------------------------------------------------------------------------------------
|
73
76
|
def getLatest
|
74
77
|
ret = 0
|
75
78
|
@vars[:vars_fil] = "#{@vars[:build_store]}/#{ENV['JOB_NAME']}-#{@vars[:variant]}.env"
|
@@ -87,27 +90,46 @@ module CiCd
|
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
93
|
+
ret = loadLatestVarsFile
|
94
|
+
ret
|
95
|
+
end
|
96
|
+
|
97
|
+
# ---------------------------------------------------------------------------------------------------------------
|
98
|
+
def loadLatestVarsFile
|
99
|
+
ret = 0
|
90
100
|
if File.exists?(@vars[:latest_fil])
|
91
101
|
@vars[:latest_ver] = IO.readlines(@vars[:latest_fil])
|
92
102
|
unless @vars[:latest_ver].is_a?(Array)
|
93
103
|
@logger.error "Unable to parse latest version from #{@vars[:latest_fil]}"
|
94
|
-
ret =
|
104
|
+
ret = Errors::PARSING_LATEST_VERSION
|
95
105
|
end
|
96
106
|
@vars[:latest_sha] = @vars[:latest_ver][1].chomp() if (@vars[:latest_ver].length > 1)
|
97
107
|
@vars[:latest_ver] = @vars[:latest_ver][0].chomp()
|
108
|
+
if @vars[:latest_ver] =~ %r'-\d+$'
|
109
|
+
@vars[:latest_ver], @vars[:latest_rel] = @vars[:latest_ver].split(/-/)
|
110
|
+
end
|
98
111
|
end
|
99
112
|
ret
|
100
113
|
end
|
101
114
|
|
115
|
+
# ---------------------------------------------------------------------------------------------------------------
|
116
|
+
def saveLatestVarsFile
|
117
|
+
@logger.info "Save latest build info to #{@vars[:latest_fil]}"
|
118
|
+
wrote = IO.write(@vars[:latest_fil], "#{@vars[:build_ver]}-#{@vars[:build_rel]}\n#{@vars[:build_sha]}")
|
119
|
+
ret = (wrote > 0) ? 0 : Errors::SAVE_LATEST_VARS
|
120
|
+
end
|
121
|
+
|
102
122
|
# ---------------------------------------------------------------------------------------------------------------
|
103
123
|
def saveEnvironment(ignored=ENV_IGNORED)
|
124
|
+
@logger.step __method__.to_s
|
104
125
|
@logger.info "Save environment to #{@vars[:vars_fil]}"
|
105
126
|
vstr = ['[global]']
|
106
127
|
ENV.to_hash.sort.each{|k,v|
|
107
128
|
vstr << %(#{k}="#{v}") unless ignored.include?(k)
|
108
129
|
}
|
109
130
|
|
110
|
-
|
131
|
+
@vars[:return_code] = (IO.write(@vars[:vars_fil], vstr.join("\n")) > 0) ? 0 : Errors::SAVE_ENVIRONMENT_VARS
|
132
|
+
return @vars[:return_code]
|
111
133
|
end
|
112
134
|
|
113
135
|
# ---------------------------------------------------------------------------------------------------------------
|
@@ -122,7 +144,11 @@ module CiCd
|
|
122
144
|
end
|
123
145
|
if @vars[:latest_ver] != @vars[:build_ver]
|
124
146
|
change = true
|
125
|
-
@logger.info "CHANGE:
|
147
|
+
@logger.info "CHANGE: Version [#{@vars[:latest_ver]}] => [#{@vars[:build_ver]}]"
|
148
|
+
end
|
149
|
+
if @vars[:latest_rel] != @vars[:build_rel]
|
150
|
+
change = true
|
151
|
+
@logger.info "CHANGE: Release [#{@vars[:latest_rel]}] => [#{@vars[:build_rel]}]"
|
126
152
|
end
|
127
153
|
unless File.file?(@vars[:build_pkg])
|
128
154
|
change = true
|
@@ -134,7 +160,7 @@ module CiCd
|
|
134
160
|
end
|
135
161
|
|
136
162
|
if change
|
137
|
-
if @vars[:latest_pkg] != @vars[:build_pkg]
|
163
|
+
if @vars[:latest_pkg] != @vars[:build_pkg] and File.file?(@vars[:build_pkg])
|
138
164
|
@logger.info "Link #{@vars[:latest_pkg]} to #{@vars[:build_pkg]}"
|
139
165
|
begin
|
140
166
|
File.unlink(@vars[:latest_pkg])
|
@@ -142,16 +168,24 @@ module CiCd
|
|
142
168
|
# noop
|
143
169
|
end
|
144
170
|
File.symlink(@vars[:build_pkg], @vars[:latest_pkg])
|
171
|
+
else
|
172
|
+
@logger.warn "Skipping link #{@vars[:latest_pkg]} to missing '#{@vars[:build_pkg]}'"
|
173
|
+
end
|
174
|
+
@vars[:return_code] = saveLatestVarsFile()
|
175
|
+
unless 0 == @vars[:return_code]
|
176
|
+
@logger.error "Failed to save latest vars file: #{@vars[:latest_fil]}"
|
177
|
+
return @vars[:return_code]
|
178
|
+
end
|
179
|
+
@vars[:return_code] = saveEnvironment(ENV_IGNORED)
|
180
|
+
unless 0 == @vars[:return_code]
|
181
|
+
@logger.error "Failed to save environment vars file: #{@vars[:vars_fil]}"
|
182
|
+
return @vars[:return_code]
|
145
183
|
end
|
146
|
-
@logger.info "Save latest build info to #{@vars[:latest_fil]}"
|
147
|
-
IO.write(@vars[:latest_fil], "#{@vars[:build_ver]}\n#{@vars[:build_sha]}")
|
148
|
-
saveEnvironment(ENV_IGNORED)
|
149
184
|
# NOTE the '.note'!
|
150
|
-
@logger.note "CHANGE: #{ENV['JOB_NAME']} (#{@vars[:build_ver]}[#{@vars[:build_sha]}])"
|
151
|
-
|
185
|
+
@logger.note "CHANGE: #{ENV['JOB_NAME']} (#{@vars[:build_ver]}-#{@vars[:build_rel]}[#{@vars[:build_sha]}])"
|
152
186
|
else
|
153
|
-
@logger.info "Artifact #{@vars[:latest_pkg]} unchanged (#{@vars[:latest_ver]} [#{@vars[:latest_sha]}])"
|
154
|
-
@logger.
|
187
|
+
@logger.info "Artifact #{@vars[:latest_pkg]} unchanged (#{@vars[:latest_ver]}-#{@vars[:latest_rel]} [#{@vars[:latest_sha]}])"
|
188
|
+
@logger.note "NO_CHANGE: #{ENV['JOB_NAME']} #{@vars[:latest_ver]}"
|
155
189
|
end
|
156
190
|
@vars[:return_code] = 0
|
157
191
|
rescue => e
|
@@ -7,6 +7,41 @@ module CiCd
|
|
7
7
|
class InvalidVersion < Unknown ; end
|
8
8
|
class InvalidVersionConstraint < Unknown ; end
|
9
9
|
|
10
|
+
i = 10
|
11
|
+
ARTIFACT_UPLOAD_EXCEPTION = i+=1
|
12
|
+
MAKEBUILD_EXCEPTION = i+=1
|
13
|
+
MAKEBUILD_PREPARATION = i+=1
|
14
|
+
MISSING_ENV_VAR = i+=1
|
15
|
+
PREPAREBUILD_EXCEPTION = i+=1
|
16
|
+
PARSING_LATEST_VERSION = i+=1
|
17
|
+
PARSING_BUILD_CHECKSUM = i+=1
|
18
|
+
STORING_BUILD_CHECKSUM = i+=1
|
19
|
+
INVALID_WORKSPACE = i+=1
|
20
|
+
CLEANUPBUILD_EXCEPTION = i+=1
|
21
|
+
REPO_DIR = i+=1
|
22
|
+
WORKSPACE_DIR = i+=1
|
23
|
+
NO_COMPONENTS = i+=1
|
24
|
+
MANIFEST_EMPTY = i+=1
|
25
|
+
MANIFEST_WRITE = i+=1
|
26
|
+
MANIFEST_DELETE = i+=1
|
27
|
+
INVENTORY_UPLOAD_EXCEPTION = i+=1
|
28
|
+
STORING_BUILD_METADATA = i+=1
|
29
|
+
BUILDER_REPO_TYPE = i+=1
|
30
|
+
BUILD_DIR = i+=1
|
31
|
+
BUCKET = i+=1
|
32
|
+
BAD_ARTIFACTS = i+=1
|
33
|
+
ARTIFACT_NOT_FOUND = i+=1
|
34
|
+
SAVE_LATEST_VARS = i+=1
|
35
|
+
SAVE_ENVIRONMENT_VARS = i+=1
|
36
|
+
NO_ARTIFACTS = i+=1
|
37
|
+
|
38
|
+
require 'awesome_print'
|
39
|
+
|
40
|
+
MAP = {}
|
41
|
+
constants.each do |c|
|
42
|
+
MAP[const_get(c)] = c.to_s
|
43
|
+
end
|
44
|
+
|
10
45
|
end
|
11
46
|
end
|
12
47
|
end
|
@@ -7,34 +7,40 @@ module CiCd
|
|
7
7
|
@options = {
|
8
8
|
log_level: :warn,
|
9
9
|
#dry_run: false,
|
10
|
-
|
10
|
+
trace: false,
|
11
11
|
gen: '3.0.0',
|
12
12
|
}.merge @default_options
|
13
13
|
|
14
14
|
opt_parser = OptionParser.new do |opts|
|
15
15
|
opts.banner = "Usage: #{MYNAME} [@options]"
|
16
16
|
|
17
|
-
opts.on('-l', '--log_level LEVEL', '--log-level LEVEL', [:trace, :debug, :info, :note, :warn, :error, :fatal, :todo],
|
17
|
+
opts.on('-l', '--log_level LEVEL', '--log-level LEVEL', [:trace, :debug, :info, :note, :warn, :error, :fatal, :todo], 'Log level ([:trace, :debug, :info, :step, :warn, :error, :fatal, :todo])') do |v|
|
18
18
|
@options[:log_level] = v
|
19
19
|
end
|
20
|
-
opts.on(
|
20
|
+
opts.on('-f', '--inifile FILE', 'INI file with settings') do |v|
|
21
21
|
@options[:inifile] = v
|
22
22
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
opts.on('-t', '--[no-]trace', 'Print backtrace in log, Default --no-trace') do |v|
|
24
|
+
@options[:trace] = v
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
opt_parser.parse!
|
29
29
|
|
30
30
|
# Set up logger
|
31
|
-
Logging.init :trace, :debug, :info, :note, :warn, :error, :fatal, :todo
|
31
|
+
Logging.init :trace, :debug, :info, :note, :step, :warn, :error, :fatal, :todo
|
32
32
|
@logger = Logging.logger(STDOUT,
|
33
33
|
:pattern => "%#{::Logging::MAX_LEVEL_LENGTH}l: %m\n",
|
34
34
|
:date_pattern => '%Y-%m-%d %H:%M:%S')
|
35
35
|
@logger.level = @options[:log_level]
|
36
36
|
|
37
|
-
|
37
|
+
unless @options[:inifile]
|
38
|
+
if ENV.has_key?('INIFILE')
|
39
|
+
@vars[:inifile] = ENV['INIFILE']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if @options.key?(:inifile)
|
38
44
|
@options[:inifile] = File.expand_path(@options[:inifile])
|
39
45
|
unless File.exist?(@options[:inifile])
|
40
46
|
raise StandardError.new("#{@options[:inifile]} not found!")
|
@@ -1,400 +1,49 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'semverse'
|
2
3
|
|
3
4
|
module CiCd
|
4
5
|
module Builder
|
6
|
+
require 'cicd/builder/mixlib/repo/base'
|
7
|
+
require 'cicd/builder/mixlib/repo/S3'
|
8
|
+
# noinspection RubyResolve
|
9
|
+
if ENV.has_key?('REPO_TYPE') and (not ENV['REPO_TYPE'].capitalize.equal?('S3'))
|
10
|
+
require "cicd/builder/mixlib/repo/#{ENV['REPO_TYPE'].downcase}"
|
11
|
+
end
|
5
12
|
|
6
|
-
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
unless @s3_bucket
|
14
|
-
@s3_bucket = @s3.buckets[ENV['AWS_S3_BUCKET']]
|
15
|
-
end
|
16
|
-
@s3_bucket
|
17
|
-
end
|
18
|
-
|
19
|
-
# ---------------------------------------------------------------------------------------------------------------
|
20
|
-
def uploadToS3(artifacts)
|
21
|
-
bucket = getS3Bucket()
|
22
|
-
artifacts.each{|art|
|
23
|
-
# makes no request, returns an AWS::S3::S3Object
|
24
|
-
s3_obj = bucket.objects[art[:key]]
|
25
|
-
upload = true
|
26
|
-
if art[:data].has_key?(:file)
|
27
|
-
md5 = Digest::MD5.file(art[:data][:file]).hexdigest
|
28
|
-
else
|
29
|
-
#noinspection RubyArgCount
|
30
|
-
md5 = Digest::MD5.hexdigest(art[:data][:data])
|
31
|
-
end
|
32
|
-
if s3_obj.exists?
|
33
|
-
@logger.info "s3://#{ENV['AWS_S3_BUCKET']}/#{art[:key]} exists"
|
34
|
-
etag = s3_obj.etag.gsub(/"/,'')
|
35
|
-
unless etag == md5
|
36
|
-
checksum = s3_obj.metadata[:checksum]
|
37
|
-
unless checksum and checksum == md5
|
38
|
-
@logger.warn "s3://#{ENV['AWS_S3_BUCKET']}/#{art[:key]} is different from our #{art[:key]}(#{s3_obj.etag} <=> #{md5})"
|
39
|
-
upload = true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
if upload
|
45
|
-
@logger.info "Upload new s3://#{ENV['AWS_S3_BUCKET']}/#{art[:key]}"
|
46
|
-
# Get size before upload changes our object
|
47
|
-
if art[:data].has_key?(:file)
|
48
|
-
size = File.size(art[:data][:file])
|
49
|
-
else
|
50
|
-
size = art[:data][:data].length
|
51
|
-
end
|
52
|
-
art[:data][:metadata] = {checksum: md5, digest: "md5=#{md5}"}
|
53
|
-
# art[:data][:'x-amz-meta-digest'] = "md5=#{md5}"
|
54
|
-
s3_obj.write(art[:data])
|
55
|
-
if art.has_key?(:public_url)
|
56
|
-
@vars[art[:public_url]] = s3_obj.public_url
|
57
|
-
end
|
58
|
-
if art.has_key?(:read_url)
|
59
|
-
@vars[art[:read_url]] = s3_obj.url_for(:read) if art.has_key?(:read_url)
|
60
|
-
end
|
61
|
-
@logger.info "#{art[:label]}: #{@vars[art[:public_url]]}" if art.has_key?(:public_url)
|
62
|
-
# if size > 16 * 1024 * 1024
|
63
|
-
# if size < 5 * 1024 * 1024 * 1000
|
64
|
-
# @logger.debug "#{art[:label]}: Multipart etag: #{s3_obj.etag}"
|
65
|
-
# s3_obj.copy_to("#{art[:key]}.copy")
|
66
|
-
# s3_obj = bucket.objects["#{art[:key]}.copy"]
|
67
|
-
# s3_obj.move_to(art[:key])
|
68
|
-
# s3_obj = bucket.objects[art[:key]]
|
69
|
-
# @logger.debug "#{art[:label]}: Revised etag: #{s3_obj.etag}"
|
70
|
-
# else
|
71
|
-
# @logger.warn "#{art[:label]}: Multipart etag: #{s3_obj.etag} on asset > 5Gb"
|
72
|
-
# end
|
73
|
-
# end
|
74
|
-
end
|
75
|
-
}
|
76
|
-
0
|
77
|
-
end
|
78
|
-
|
79
|
-
# ---------------------------------------------------------------------------------------------------------------
|
80
|
-
def getArtifactsDefinition()
|
81
|
-
nil
|
82
|
-
end
|
83
|
-
|
84
|
-
# ---------------------------------------------------------------------------------------------------------------
|
85
|
-
def getNamingDefinition()
|
86
|
-
nil
|
87
|
-
end
|
88
|
-
|
89
|
-
# ---------------------------------------------------------------------------------------------------------------
|
90
|
-
def initInventory()
|
91
|
-
|
92
|
-
hash =
|
93
|
-
{
|
94
|
-
id: "#{@vars[:project_name]}",
|
95
|
-
# In case future generations introduce incompatible features
|
96
|
-
gen: "#{@options[:gen]}",
|
97
|
-
container: {
|
98
|
-
artifacts: %w(assembly metainfo checksum),
|
99
|
-
naming: '<product>-<major>.<minor>.<patch>-<branch>-release-<number>-build-<number>.<extension>',
|
100
|
-
assembly: {
|
101
|
-
extension: 'tar.gz',
|
102
|
-
type: 'targz'
|
103
|
-
},
|
104
|
-
metainfo: {
|
105
|
-
extension: 'MANIFEST.json',
|
106
|
-
type: 'json'
|
107
|
-
},
|
108
|
-
checksum: {
|
109
|
-
extension: 'checksum',
|
110
|
-
type: 'Digest::SHA256'
|
111
|
-
},
|
112
|
-
variants: {
|
113
|
-
:"#{@vars[:variant]}" => {
|
114
|
-
latest: {
|
115
|
-
build: 0,
|
116
|
-
branch: 0,
|
117
|
-
version: 0,
|
118
|
-
release: 0,
|
119
|
-
},
|
120
|
-
versions: [ "#{@vars[:build_ver]}" ],
|
121
|
-
branches: [ "#{@vars[:build_bra]}" ],
|
122
|
-
builds: [
|
123
|
-
{
|
124
|
-
drawer: @vars[:build_nam],
|
125
|
-
build_name: @vars[:build_rel],
|
126
|
-
build_number: @vars[:build_num],
|
127
|
-
release: @vars[:release],
|
128
|
-
}
|
129
|
-
],
|
130
|
-
}
|
131
|
-
}
|
132
|
-
}
|
133
|
-
}
|
134
|
-
artifacts = getArtifactsDefinition()
|
135
|
-
naming = getNamingDefinition()
|
136
|
-
|
137
|
-
# By default we use the internal definition ...
|
138
|
-
if artifacts
|
139
|
-
artifacts.each do |name,artifact|
|
140
|
-
hash[:container][name] = artifact
|
13
|
+
# ---------------------------------------------------------------------------------------------------------------
|
14
|
+
def getRepoClass(type = nil)
|
15
|
+
if type.nil?
|
16
|
+
type ||= 'S3'
|
17
|
+
if ENV.has_key?('REPO_TYPE')
|
18
|
+
type = ENV['REPO_TYPE']
|
141
19
|
end
|
142
20
|
end
|
143
21
|
|
144
|
-
|
145
|
-
if
|
146
|
-
|
147
|
-
|
148
|
-
JSON.pretty_generate( hash, { indent: "\t", space: ' '})
|
149
|
-
end
|
150
|
-
|
151
|
-
# ---------------------------------------------------------------------------------------------------------------
|
152
|
-
def takeInventory()
|
153
|
-
def _update(hash, key, value)
|
154
|
-
h = {}
|
155
|
-
i = -1
|
156
|
-
hash[key].each { |v| h[v] = i+=1 }
|
157
|
-
unless h.has_key?(value)
|
158
|
-
h[value] = h.keys.size # No -1 because this is evaluated BEFORE we make the addition!
|
22
|
+
clazz = Object.const_get("CiCd::Builder::Repo::#{type}")
|
23
|
+
if block_given?
|
24
|
+
if clazz.is_a?(Class) and not clazz.nil?
|
25
|
+
yield
|
159
26
|
end
|
160
|
-
|
161
|
-
s = s.map { |v| v[0] }
|
162
|
-
hash[key] = s
|
163
|
-
h[value]
|
164
|
-
end
|
165
|
-
|
166
|
-
# Read and parse in JSON
|
167
|
-
json_s = ''
|
168
|
-
json = nil
|
169
|
-
varianth = nil
|
170
|
-
|
171
|
-
bucket = getS3Bucket()
|
172
|
-
key = "#{@vars[:project_name]}/INVENTORY.json"
|
173
|
-
s3_obj = bucket.objects[key]
|
174
|
-
# If the inventory has started then add to it
|
175
|
-
if s3_obj.exists?
|
176
|
-
s3_obj.read(){|chunk|
|
177
|
-
json_s << chunk
|
178
|
-
}
|
179
|
-
json = Yajl::Parser.parse(json_s)
|
180
|
-
over = false
|
181
|
-
# Is the inventory format up to date ...
|
182
|
-
# TODO: [2014-07-27 Christo] Use semver gem ...
|
183
|
-
require 'chef/exceptions'
|
184
|
-
require 'chef/version_constraint'
|
185
|
-
require 'chef/version_class'
|
186
|
-
|
187
|
-
begin
|
188
|
-
version = Chef::Version.new(json['gen'])
|
189
|
-
rescue Chef::Exceptions::InvalidCookbookVersion => e
|
190
|
-
json['gen'] = "#{json['gen']}.0.0"
|
191
|
-
version = Chef::Version.new(json['gen'])
|
192
|
-
end
|
193
|
-
|
194
|
-
begin
|
195
|
-
our_ver = Chef::Version.new(@options[:gen])
|
196
|
-
constraint = Chef::VersionConstraint.new("<= #{@options[:gen]}")
|
197
|
-
rescue Chef::Exceptions::InvalidVersionConstraint => e
|
198
|
-
raise CiCd::Builder::Errors::InvalidVersionConstraint.new e.message
|
199
|
-
rescue Chef::Exceptions::InvalidCookbookVersion => e
|
200
|
-
raise CiCd::Builder::Errors::InvalidVersion.new e.message
|
201
|
-
end
|
202
|
-
|
203
|
-
unless constraint.include?(version)
|
204
|
-
raise CiCd::Builder::Errors::InvalidVersion.new "The inventory generation is newer than I can manage: #{version} <=> #{our_ver}"
|
205
|
-
end
|
206
|
-
if json['container'] and json['container']['variants']
|
207
|
-
# but does not have our variant then add it
|
208
|
-
variants = json['container']['variants']
|
209
|
-
unless variants[@vars[:variant]]
|
210
|
-
variants[@vars[:variant]] = {}
|
211
|
-
varianth = variants[@vars[:variant]]
|
212
|
-
varianth['builds'] = []
|
213
|
-
varianth['branches'] = []
|
214
|
-
varianth['versions'] = []
|
215
|
-
varianth['releases'] = []
|
216
|
-
varianth['latest'] = {
|
217
|
-
branch: -1,
|
218
|
-
version: -1,
|
219
|
-
build: -1,
|
220
|
-
release: -1,
|
221
|
-
}
|
222
|
-
end
|
223
|
-
varianth = variants[@vars[:variant]]
|
224
|
-
# If the inventory 'latest' format is up to date ...
|
225
|
-
unless varianth['latest'] and
|
226
|
-
varianth['latest'].is_a?(Hash)
|
227
|
-
# Start over ... too old/ incompatible
|
228
|
-
over = true
|
229
|
-
end
|
230
|
-
else
|
231
|
-
# Start over ... too old/ incompatible
|
232
|
-
over = true
|
233
|
-
end
|
234
|
-
else
|
235
|
-
# Start a new inventory
|
236
|
-
over = true
|
237
|
-
end
|
238
|
-
# Starting fresh ?
|
239
|
-
if over or json.nil?
|
240
|
-
json_s = initInventory()
|
241
|
-
else
|
242
|
-
raise CiCd::Builder::Errors::Internal.new sprintf('Internal logic error! %s::%d', __FILE__,__LINE__) if varianth.nil?
|
243
|
-
# Add the new build if we don't have it
|
244
|
-
unless varianth['builds'].map { |b| b['build_name'] }.include?(@vars[:build_rel])
|
245
|
-
#noinspection RubyStringKeysInHashInspection
|
246
|
-
filing = {
|
247
|
-
'drawer' => @vars[:build_nam],
|
248
|
-
'build_name' => @vars[:build_rel],
|
249
|
-
'build_number' => @vars[:build_num],
|
250
|
-
'release' => @vars[:release],
|
251
|
-
}
|
252
|
-
if @vars.has_key?(:artifacts)
|
253
|
-
filing['artifacts'] = @vars[:artifacts].map { |artifact| File.basename(artifact[:key]) }
|
254
|
-
end
|
255
|
-
assembly = json['container']['assembly'] or raise("Expected an 'assembly'")
|
256
|
-
if assembly['extension'] != !vars[:build_ext]
|
257
|
-
# noinspection RubyStringKeysInHashInspection
|
258
|
-
filing['assembly'] = {
|
259
|
-
'extension' => @vars[:build_ext],
|
260
|
-
'type' => 'tarbzip2'
|
261
|
-
}
|
262
|
-
end
|
263
|
-
varianth['builds'] << filing
|
264
|
-
end
|
265
|
-
build_lst = (varianth['builds'].size-1)
|
266
|
-
build_rel = build_lst
|
267
|
-
i = -1
|
268
|
-
varianth['builds'].each{ |h|
|
269
|
-
i += 1
|
270
|
-
convert_build(h)
|
271
|
-
convert_build(varianth['builds'][build_rel])
|
272
|
-
if h['release'].to_i > varianth['builds'][build_rel]['release'].to_i
|
273
|
-
build_rel = i
|
274
|
-
elsif h['release'] == varianth['builds'][build_rel]['release']
|
275
|
-
build_rel = i if h['build_number'].to_i > varianth['builds'][build_rel]['build_number'].to_i
|
276
|
-
end
|
277
|
-
}
|
278
|
-
|
279
|
-
# Add new branch ...
|
280
|
-
build_bra = _update(varianth, 'branches', @vars[:build_bra])
|
281
|
-
# Add new version ...
|
282
|
-
build_ver = _update(varianth, 'versions', @vars[:build_ver])
|
283
|
-
|
284
|
-
# Set latest
|
285
|
-
varianth['latest'] = {
|
286
|
-
branch: build_bra,
|
287
|
-
version: build_ver,
|
288
|
-
build: build_lst,
|
289
|
-
release: build_rel,
|
290
|
-
}
|
291
|
-
json['gen'] = @options[:gen]
|
292
|
-
json_s = JSON.pretty_generate( json, { indent: "\t", space: ' '})
|
293
|
-
end
|
294
|
-
begin
|
295
|
-
md5 = Digest::MD5.hexdigest(json_s)
|
296
|
-
resp = s3_obj.write({
|
297
|
-
:data => json_s,
|
298
|
-
:'x-amz-meta-digest' => "md5=#{md5}",
|
299
|
-
:metadata => { checksum: md5 },
|
300
|
-
})
|
301
|
-
|
302
|
-
@logger.info "Inventory URL: #{s3_obj.url_for(:read)}"
|
27
|
+
end
|
303
28
|
|
304
|
-
|
305
|
-
|
306
|
-
return 0
|
307
|
-
else
|
308
|
-
return 1
|
309
|
-
end
|
310
|
-
rescue Exception => e
|
311
|
-
return -1
|
312
|
-
end
|
313
|
-
end
|
29
|
+
clazz
|
30
|
+
end
|
314
31
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
32
|
+
# ---------------------------------------------------------------------------------------------------------------
|
33
|
+
def uploadBuildArtifacts()
|
34
|
+
clazz = getRepoClass()
|
35
|
+
if clazz.is_a?(Class) and not clazz.nil?
|
36
|
+
@repo = clazz.new(self)
|
37
|
+
@vars[:return_code] = @repo.uploadBuildArtifacts()
|
38
|
+
@vars[:return_code]
|
321
39
|
else
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
h['build_number'] = h_number
|
326
|
-
h['build_name'] = h_build
|
327
|
-
h.delete 'build'
|
328
|
-
h.delete 'number'
|
40
|
+
@logger.error "CiCd::Builder::Repo::#{type} is not a valid repo class"
|
41
|
+
@vars[:return_code] = Errors::BUILDER_REPO_TYPE
|
329
42
|
end
|
330
|
-
|
331
|
-
h_build = h.has_key?('build')
|
332
|
-
h_number = h_build.gsub(/^.*?-build-([0-9]+)$/, '\1').to_i
|
333
|
-
|
334
|
-
h['build_number'] = h_number
|
335
|
-
h['build_name'] = h_build
|
336
|
-
h.delete 'build'
|
337
|
-
h.delete 'number'
|
338
|
-
end
|
339
|
-
h
|
43
|
+
@vars[:return_code]
|
340
44
|
end
|
341
45
|
|
342
46
|
# ---------------------------------------------------------------------------------------------------------------
|
343
|
-
def uploadBuildArtifacts()
|
344
|
-
if @vars.has_key?(:build_dir) and @vars.has_key?(:build_pkg)
|
345
|
-
begin
|
346
|
-
if File.exists?(@vars[:build_pkg])
|
347
|
-
|
348
|
-
artifacts = @vars[:artifacts] rescue []
|
349
|
-
|
350
|
-
key = "#{@vars[:project_name]}/#{@vars[:variant]}/#{@vars[:build_nam]}/#{@vars[:build_rel]}"
|
351
|
-
# Store the assembly - be sure to inherit possible overrides in pkg name and ext but dictate the drawer!
|
352
|
-
artifacts << {
|
353
|
-
key: "#{File.join(File.dirname(key),File.basename(@vars[:build_pkg]))}",
|
354
|
-
data: {:file => @vars[:build_pkg]},
|
355
|
-
public_url: :build_url,
|
356
|
-
label: 'Package URL'
|
357
|
-
}
|
358
|
-
|
359
|
-
# Store the metadata
|
360
|
-
manifest = manifestMetadata()
|
361
|
-
artifacts << {
|
362
|
-
key: "#{key}.MANIFEST.json",
|
363
|
-
data: {:data => manifest},
|
364
|
-
public_url: :manifest_url,
|
365
|
-
read_url: :manifest_url,
|
366
|
-
label: 'Manifest URL'
|
367
|
-
}
|
368
|
-
|
369
|
-
# Store the checksum
|
370
|
-
artifacts << {
|
371
|
-
key: "#{@vars[:project_name]}/#{@vars[:variant]}/#{@vars[:build_nam]}/#{@vars[:build_rel]}.checksum",
|
372
|
-
data: {:data => @vars[:build_sha]},
|
373
|
-
public_url: :checksum_url,
|
374
|
-
read_url: :checksum_url,
|
375
|
-
label: 'Checksum URL'
|
376
|
-
}
|
377
|
-
|
378
|
-
@vars[:return_code] = uploadToS3(artifacts)
|
379
|
-
if 0 == @vars[:return_code]
|
380
|
-
@vars[:return_code] = takeInventory()
|
381
|
-
end
|
382
|
-
@vars[:return_code]
|
383
|
-
else
|
384
|
-
@vars[:return_code] = 1
|
385
|
-
end
|
386
|
-
rescue => e
|
387
|
-
@logger.error "#{e.class.name} #{e.message}"
|
388
|
-
@vars[:return_code] = -99
|
389
|
-
raise e
|
390
|
-
end
|
391
|
-
else
|
392
|
-
@vars[:return_code] = 2
|
393
|
-
end
|
394
|
-
@vars[:return_code]
|
395
|
-
end
|
396
|
-
|
397
|
-
# ---------------------------------------------------------------------------------------------------------------
|
398
47
|
def manifestMetadata
|
399
48
|
manifest = @vars[:build_mdd].dup
|
400
49
|
|
@@ -411,7 +60,7 @@ module CiCd
|
|
411
60
|
branch: @vars[:build_bra],
|
412
61
|
}
|
413
62
|
manifest[:build] = {
|
414
|
-
name: @vars[:
|
63
|
+
name: @vars[:build_nmn],
|
415
64
|
base: @vars[:build_nam],
|
416
65
|
date: @vars[:build_dte],
|
417
66
|
vrb: @vars[:build_vrb],
|
@@ -444,5 +93,15 @@ module CiCd
|
|
444
93
|
JSON.pretty_generate( manifest, { indent: "\t", space: ' '})
|
445
94
|
end
|
446
95
|
|
447
|
-
|
96
|
+
# ---------------------------------------------------------------------------------------------------------------
|
97
|
+
def getArtifactsDefinition()
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
|
101
|
+
# ---------------------------------------------------------------------------------------------------------------
|
102
|
+
def getNamingDefinition()
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
448
107
|
end
|