cicd-builder 0.9.23 → 0.9.25
Sign up to get free protection for your applications and to get access to all the features.
- 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
|