forked from Mirantis/mk-pipelines
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpromote-vcp-images.groovy
136 lines (126 loc) · 7.28 KB
/
promote-vcp-images.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
*
* Promote VCP(qcow2) images
*
* Expected parameters:
* VCP_IMAGE_LIST - multiline with qcow2 file names
* TAG - Target tag of image.Possible are: "nightly|testing|proposed|201X.X.X"
* SOURCE_TAG - Initial tag to be tagged with TAG. Will replace SUBS_SOURCE_VCP_IMAGE_TAG in VCP_IMAGE_LIST
* UPLOAD_URL - WebDav url with creds, from\to download images
*
*/
def common = new com.mirantis.mk.Common()
def jenkinsUtils = new com.mirantis.mk.JenkinsUtils()
// Better to chose slave with ssd and fast network to webDav host
slaveNode = env.SLAVE_NODE ?: 'promotion'
def job_env = env.getEnvironment().findAll { k, v -> v }
def verify = job_env.VERIFY_DOWNLOAD ?: true
def overwrite = job_env.FORCE_OVERWRITE.toBoolean() ?: false
timeout(time: 6, unit: 'HOURS') {
node(slaveNode) {
String description = ''
insufficientPermissions = false
try {
// Pre-run verify
// promote is restricted to users in aptly-promote-users LDAP group
if (!jenkinsUtils.currentUserInGroups(["mcp-cicd-admins", "aptly-promote-users"])) {
insufficientPermissions = true
error(String.format("You don't have permissions to make promote from source:%s to target:%s! Only CI/CD and QA team can perform promote.", job_env.SOURCE_TAG, job_env.TAG))
}
// Check for required opts
for (opt in ['UPLOAD_URL', 'SOURCE_TAG', 'TAG', 'VCP_IMAGE_LIST']) {
if (!job_env.get(opt, null)) {
error("Invalid input params, at least ${opt} param missing")
}
}
def images = job_env.VCP_IMAGE_LIST.trim().tokenize()
for (image in images) {
if (image.startsWith('#')) {
common.warningMsg("Skipping image ${image}")
continue
}
common.infoMsg("Replacing SUBS_SOURCE_VCP_IMAGE_TAG => ${job_env.SOURCE_TAG}")
sourceImage = image.replace('SUBS_SOURCE_VCP_IMAGE_TAG', job_env.SOURCE_TAG)
targetImage = image.replace('SUBS_SOURCE_VCP_IMAGE_TAG', job_env.TAG)
// TODO: normalize url's?
sourceImageUrl = job_env.UPLOAD_URL + '/' + sourceImage
sourceImageMd5Url = job_env.UPLOAD_URL + '/' + sourceImage + '.md5'
targetImageUrl = job_env.UPLOAD_URL + '/' + targetImage
targetImageMd5Url = job_env.UPLOAD_URL + '/' + targetImage + '.md5'
common.infoMsg("Attempt to download: ${sourceImage} => ${targetImage}")
common.retry(3, 5) {
sh(script: "wget --progress=dot:giga --auth-no-challenge -O ${targetImage} ${sourceImageUrl}")
}
def targetImageMd5 = common.cutOrDie("md5sum ${targetImage} | tee ${targetImage}.md5", 0)
if (verify.toBoolean()) {
common.infoMsg("Checking md5's ")
sh(script: "wget --progress=dot:giga --auth-no-challenge -O ${targetImage}_source_md5 ${sourceImageMd5Url}")
def sourceImageMd5 = readFile(file: "${targetImage}_source_md5").tokenize(' ')[0]
// Compare downloaded and remote files
if (sourceImageMd5 != targetImageMd5) {
error("Image ${targetImage} md5sum verify failed!")
} else {
common.infoMsg("sourceImageMd5: ${sourceImageMd5} == target to upload ImageMd5: ${targetImageMd5}")
}
// Compare downloaded file, and remote file-to-be-promoted. If same - no sense to promote same file
remoteImageMd5Status = sh(script: "wget --progress=dot:giga --auth-no-challenge -O ${targetImage}_expected_target_md5 ${targetImageMd5Url}", returnStatus: true)
if (remoteImageMd5Status == '8') {
common.infoMsg("target to upload ImageMd5 file not even exist.Continue..")
} else {
def remoteImageMd5 = readFile(file: "${targetImage}_expected_target_md5").tokenize(' ')[0]
if (sourceImageMd5 == remoteImageMd5) {
common.infoMsg("sourceImageMd5: ${sourceImageMd5} and target to upload ImageMd5: ${targetImageMd5} are same")
common.warningMsg("Skipping to upload: ${targetImage} since it already same")
description += "Skipping to upload: ${targetImage} since it already same\n"
continue
}
}
common.infoMsg("Check, that we are not going to overwrite released file..")
if (['proposed', 'testing', 'nightly'].contains(job_env.TAG)) {
common.infoMsg("Uploading to ${job_env.TAG} looks safe..")
} else if (['stable'].contains(job_env.TAG)) {
common.warningMsg("Uploading to ${job_env.TAG} not safe! But still possible")
} else {
common.warningMsg("Looks like uploading to new release: ${job_env.TAG}. Checking, that it is not exist yet..")
remoteImageStatus = ''
remoteImageStatus = sh(script: "wget --auth-no-challenge --spider ${targetImageUrl} 2>/dev/null", returnStatus: true)
// wget return code 8 ,if file not exist
if (remoteImageStatus != 8 && !overwrite) {
error("Attempt to overwrite existing release! Target: ${targetImage} already exist!")
}
}
}
common.infoMsg("Attempt to UPLOAD: ${targetImage} => ${targetImageUrl}")
//
def uploadImageStatus = ''
def uploadImageMd5Status = ''
common.retry(3, 5) {
uploadImageStatus = sh(script: "curl -f -T ${targetImage} ${job_env.UPLOAD_URL}", returnStatus: true)
if (uploadImageStatus != 0) {
error("Uploading file: ${targetImage} failed!")
}
}
uploadImageMd5Status = sh(script: "curl -f -T ${targetImage}.md5 ${job_env.UPLOAD_URL}", returnStatus: true)
if (uploadImageMd5Status != 0) {
error("Uploading file: ${targetImage}.md5 failed!")
}
description += "<a href='http://images.mcp.mirantis.net/${targetImage}'>${job_env.SOURCE_TAG}=>${targetImage}</a>"
}
currentBuild.description = description
} catch (Throwable e) {
// If there was an error or exception thrown, the build failed
if (insufficientPermissions) {
currentBuild.result = "ABORTED"
currentBuild.description = "Promote aborted due to insufficient permissions"
} else {
currentBuild.result = "FAILURE"
currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
}
throw e
}
finally {
common.infoMsg("Cleanup..")
sh(script: 'find . -mindepth 1 -delete > /dev/null || true')
}
}
}