blob: 4bab0867117e7990444c55afd945f793ffbe35d3 [file] [log] [blame]
Richard Felkl2e9e5452017-10-16 09:52:10 +02001/**
2 *
Richard Felkl859f4dd2018-01-04 23:03:27 +01003 * Build mirror image pipeline
Richard Felkl2e9e5452017-10-16 09:52:10 +02004 *
5 * Expected parameters:
Richard Felkl859f4dd2018-01-04 23:03:27 +01006 * IMAGE_NAME - Name of the result image.
7 * OS_CREDENTIALS_ID - ID of credentials for OpenStack API stored in Jenkins.
8 * OS_PROJECT - Project in OpenStack under the VM will be spawned.
9 * OS_URL - Keystone auth endpoint of the OpenStack.
10 * OS_VERSION - OpenStack version
Richard Felkl859f4dd2018-01-04 23:03:27 +010011 * UPLOAD_URL - URL of an WebDAV used to upload the image after creating.
12 * VM_AVAILABILITY_ZONE - Availability zone in OpenStack in the VM will be spawned.
Richard Felkl859f4dd2018-01-04 23:03:27 +010013 * VM_FLAVOR - Flavor to be used for VM in OpenStack.
14 * VM_FLOATING_IP_POOL - Floating IP pool to be used to assign floating IP to the VM.
15 * VM_IMAGE - Name of the image to be used for VM in OpenStack.
16 * VM_IP - Static IP that is assigned to the VM which belongs to the network used.
Richard Felkl859f4dd2018-01-04 23:03:27 +010017 * VM_NETWORK_ID - ID of the network that VM connects to.
azvyagintseva0bc6142018-03-02 21:24:30 +020018 * EXTRA_VARIABLES - list of key:value variables required by template.json
Richard Felkl859f4dd2018-01-04 23:03:27 +010019 *
Richard Felkl2e9e5452017-10-16 09:52:10 +020020 */
21
22// Load shared libs
Richard Felkl2e9e5452017-10-16 09:52:10 +020023def common = new com.mirantis.mk.Common()
Richard Felkl2e9e5452017-10-16 09:52:10 +020024def openstack = new com.mirantis.mk.Openstack()
azvyagintsev1c79f4d2018-03-02 14:25:37 +020025def git = new com.mirantis.mk.Git()
Richard Felkl2e9e5452017-10-16 09:52:10 +020026def date = new Date()
27def dateTime = date.format("ddMMyyyy-HHmmss")
Richard Felkl2e9e5452017-10-16 09:52:10 +020028def rcFile = ""
29def openstackEnv = ""
Richard Felkl802e4462017-12-06 10:08:05 +010030def uploadImageStatus = ""
31def uploadMd5Status = ""
Richard Felkl3e93eeb2018-03-06 14:51:45 +010032def creds
33ArrayList extra_vars = EXTRA_VARIABLES.readLines()
34IMAGE_NAME = IMAGE_NAME + "-" + dateTime
Richard Felkl2e9e5452017-10-16 09:52:10 +020035
azvyagintsev1c79f4d2018-03-02 14:25:37 +020036timeout(time: 8, unit: 'HOURS') {
37 node("python&&disk-xl") {
38 try {
39 def workspace = common.getWorkspace()
40 openstackEnv = "${workspace}/venv"
Richard Felkl2e9e5452017-10-16 09:52:10 +020041
azvyagintsev1c79f4d2018-03-02 14:25:37 +020042 stage("Prepare env") {
azvyagintsev1c79f4d2018-03-02 14:25:37 +020043 if (!fileExists("${workspace}/tmp")) {
44 sh "mkdir -p ${workspace}/tmp"
Richard Felkl2e9e5452017-10-16 09:52:10 +020045 }
azvyagintsev1c79f4d2018-03-02 14:25:37 +020046 if (!fileExists("${workspace}/images")) {
47 sh "mkdir ${workspace}/images"
48 }
49 if (!fileExists("bin")) {
50 common.infoMsg("Downloading packer")
51 sh "mkdir -p bin"
52 dir("bin") {
azvyagintseva0bc6142018-03-02 21:24:30 +020053 sh "wget --quiet -O ${PACKER_ZIP} ${PACKER_URL}"
azvyagintsev1c79f4d2018-03-02 14:25:37 +020054 sh "echo \"${PACKER_ZIP_MD5} ${PACKER_ZIP}\" >> md5sum"
55 sh "md5sum -c --status md5sum"
56 sh "unzip ${PACKER_ZIP}"
57 }
58 }
59 // clean images dir before building
60 sh(script: "rm -rf ${BUILD_OS}/images/*", returnStatus: true)
61 // clean virtualenv is exists
62 sh(script: "rm -rf ${workspace}/venv", returnStatus: true)
63
64 openstack.setupOpenstackVirtualenv(openstackEnv, OS_VERSION)
65 git.checkoutGitRepository(PACKER_TEMPLATES_REPO_NAME, PACKER_TEMPLATES_REPO_URL, PACKER_TEMPLATES_BRANCH)
Richard Felkl3e93eeb2018-03-06 14:51:45 +010066 creds = common.getPasswordCredentials(OS_CREDENTIALS_ID)
azvyagintsev1c79f4d2018-03-02 14:25:37 +020067 }
68
69 stage("Build Instance") {
azvyagintsev1c79f4d2018-03-02 14:25:37 +020070 dir("${workspace}/${PACKER_TEMPLATES_REPO_NAME}/${BUILD_OS}/") {
azvyagintseva0bc6142018-03-02 21:24:30 +020071 withEnv(extra_vars + ["PATH=${env.PATH}:${workspace}/bin",
72 "PACKER_LOG_PATH=${workspace}/packer.log",
73 "PACKER_LOG=1",
Richard Felkl3e93eeb2018-03-06 14:51:45 +010074 "TMPDIR=${workspace}/tmp",
75 "OS_USERNAME=${creds.username}",
76 "OS_PASSWORD=${creds.password.toString()}"]) {
azvyagintsev1c79f4d2018-03-02 14:25:37 +020077 if (PACKER_DEBUG.toBoolean()) {
78 PACKER_ARGS = "${PACKER_ARGS} -debug"
79 }
80
Richard Felkl3e93eeb2018-03-06 14:51:45 +010081 sh "packer build -only=${BUILD_ONLY} ${PACKER_ARGS} -parallel=false template.json"
azvyagintsev1c79f4d2018-03-02 14:25:37 +020082
83 def packerStatus = sh(script: "grep \"Some builds didn't complete successfully and had errors\" ${PACKER_LOG_PATH}", returnStatus: true)
84 // grep returns 0 if find something
85 if (packerStatus != 0) {
Richard Felkl3e93eeb2018-03-06 14:51:45 +010086 common.infoMsg("Openstack instance complete")
azvyagintsev1c79f4d2018-03-02 14:25:37 +020087 } else {
88 throw new Exception("Packer build failed")
89 }
90 }
91 }
92 }
93
94 stage("Publish image") {
azvyagintseva0bc6142018-03-02 21:24:30 +020095 common.infoMsg("Saving image ${IMAGE_NAME}")
Richard Felkl3e93eeb2018-03-06 14:51:45 +010096 rcFile = openstack.createOpenstackEnv(workspace, OS_URL, OS_CREDENTIALS_ID, OS_PROJECT, "default", "", "default", "2", "")
97
azvyagintsev1c79f4d2018-03-02 14:25:37 +020098 common.retry(3, 5) {
azvyagintseva0bc6142018-03-02 21:24:30 +020099 openstack.runOpenstackCommand("openstack image save --file ${IMAGE_NAME}.qcow2 ${IMAGE_NAME}", rcFile, openstackEnv)
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200100 }
azvyagintseva0bc6142018-03-02 21:24:30 +0200101 sh "md5sum ${IMAGE_NAME}.qcow2 > ${IMAGE_NAME}.qcow2.md5"
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200102
azvyagintseva0bc6142018-03-02 21:24:30 +0200103 common.infoMsg("Uploading image ${IMAGE_NAME}")
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200104 common.retry(3, 5) {
azvyagintseva0bc6142018-03-02 21:24:30 +0200105 uploadImageStatus = sh(script: "curl -f -T ${IMAGE_NAME}.qcow2 ${UPLOAD_URL}", returnStatus: true)
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200106 if (uploadImageStatus != 0) {
107 throw new Exception("Image upload failed")
108 }
109 }
110
111 common.retry(3, 5) {
azvyagintseva0bc6142018-03-02 21:24:30 +0200112 uploadMd5Status = sh(script: "curl -f -T ${IMAGE_NAME}.qcow2.md5 ${UPLOAD_URL}", returnStatus: true)
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200113 if (uploadMd5Status != 0) {
114 throw new Exception("MD5 sum upload failed")
115 }
116 }
azvyagintseva0bc6142018-03-02 21:24:30 +0200117 currentBuild.description = "<a href='http://ci.mcp.mirantis.net:8085/images/${IMAGE_NAME}.qcow2'>${IMAGE_NAME}.qcow2</a>"
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200118 }
119
120 } catch (Throwable e) {
121 // If there was an error or exception thrown, the build failed
122 currentBuild.result = "FAILURE"
123 throw e
124 } finally {
125 if (CLEANUP_AFTER) {
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200126 dir(workspace) {
127 sh "rm -rf ./*"
128 }
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200129 } else {
130 common.infoMsg("Env has not been cleanup!")
131 common.infoMsg("Packer private key:")
132 dir("${workspace}/${PACKER_TEMPLATES_REPO_NAME}/${BUILD_OS}/") {
133 sh "cat os_${BUILD_OS}.pem"
134 }
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200135 }
Richard Felkl2e9e5452017-10-16 09:52:10 +0200136 }
azvyagintsev1c79f4d2018-03-02 14:25:37 +0200137 }
Jakub Josef88aaf832018-01-18 16:18:28 +0100138}