blob: 7a41304eb95236b5322dfe06cf087a0d58b8e14f [file] [log] [blame]
Richard Felkl2e9e5452017-10-16 09:52:10 +02001/**
2 *
3 * Update Salt environment pipeline
4 *
5 * Expected parameters:
6 * SALT_MASTER_URL Salt API server location
7 * SALT_MASTER_CREDENTIALS Credentials to the Salt API
8 * UPDATE_FORMULAS Boolean switch for enforcing updating formulas
9 */
10
11// Load shared libs
12def salt = new com.mirantis.mk.Salt()
13def common = new com.mirantis.mk.Common()
14def python = new com.mirantis.mk.Python()
15def openstack = new com.mirantis.mk.Openstack()
16def git = new com.mirantis.mk.Git()
17def date = new Date()
18def dateTime = date.format("ddMMyyyy-HHmmss")
19def venvPepper = "venvPepper"
20def venvS4cmd = "venvS4cmd"
21def privateKey = ""
22def floatingIP = ""
23def openstackServer = ""
24def rcFile = ""
25def openstackEnv = ""
26def serverStatus = ""
Richard Felkl802e4462017-12-06 10:08:05 +010027def uploadImageStatus = ""
28def uploadMd5Status = ""
Richard Felkl2e9e5452017-10-16 09:52:10 +020029
30def retry(int times = 5, int delay = 0, Closure body) {
31 int retries = 0
32 def exceptions = []
33 while(retries++ < times) {
34 try {
35 return body.call()
36 } catch(e) {
37 sleep(delay)
38 }
39 }
40 currentBuild.result = "FAILURE"
41 throw new Exception("Failed after $times retries")
42}
43
44node("python&&disk-xl") {
45 try {
46 def workspace = common.getWorkspace()
47 rcFile = openstack.createOpenstackEnv(OS_URL, OS_CREDENTIALS_ID, OS_PROJECT, "default", "", "default", "2", "")
48 openstackEnv = String.format("%s/venv", workspace)
Richard Felkl077b6422017-12-14 16:19:54 +010049 def openstackVersion = OS_VERSION
Richard Felkl2e9e5452017-10-16 09:52:10 +020050
51 VM_IP_DELAY = VM_IP_DELAY as Integer
52 VM_IP_RETRIES = VM_IP_RETRIES as Integer
53 VM_CONNECT_DELAY = VM_CONNECT_DELAY as Integer
54 VM_CONNECT_RETRIES = VM_CONNECT_RETRIES as Integer
55
56 stage("Get templates"){
57
58 if (!fileExists("${workspace}/tmp")) {
59 sh "mkdir -p ${workspace}/tmp"
60 }
61
Richard Felkl077b6422017-12-14 16:19:54 +010062 sh "wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/salt-bootstrap.sh"
Richard Felkl2e9e5452017-10-16 09:52:10 +020063 openstack.setupOpenstackVirtualenv(openstackEnv, openstackVersion)
64 }
65
66 stage("Spawn Instance"){
67 privateKey = openstack.runOpenstackCommand("openstack keypair create mcp-offline-keypair-${dateTime}", rcFile, openstackEnv)
68
69 common.infoMsg(privateKey)
70 sh "echo '${privateKey}' > id_rsa;chmod 600 id_rsa"
71
72 floatingIP = openstack.runOpenstackCommand("openstack ip floating create --format value -c floating_ip_address ${VM_FLOATING_IP_POOL}", rcFile, openstackEnv)
73
74 withEnv(["CLUSTER_NAME=${CLUSTER_NAME}", "CLUSTER_MODEL=${CLUSTER_MODEL}"]) {
75 sh "envsubst < salt-bootstrap.sh > salt-bootstrap.sh.temp;mv salt-bootstrap.sh.temp salt-bootstrap.sh; cat salt-bootstrap.sh"
76 }
77
Richard Felkl54cc3d52017-11-28 17:19:22 +010078 openstackServer = openstack.runOpenstackCommand("openstack server create --key-name mcp-offline-keypair-${dateTime} --availability-zone ${VM_AVAILABILITY_ZONE} --image ${VM_IMAGE} --flavor ${VM_FLAVOR} --nic net-id=${VM_NETWORK_ID},v4-fixed-ip=${VM_IP} --user-data salt-bootstrap.sh mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
Richard Felkl2e9e5452017-10-16 09:52:10 +020079 sleep(60)
80
81 retry(VM_IP_RETRIES, VM_IP_DELAY){
82 openstack.runOpenstackCommand("openstack ip floating add ${floatingIP} mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
83 }
84
85 sleep(500)
86
87 retry(VM_CONNECT_RETRIES, VM_CONNECT_DELAY){
88 sh "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i id_rsa root@${floatingIP}:/srv/initComplete ./"
89 }
90
91 python.setupPepperVirtualenv(venvPepper, "http://${floatingIP}:6969", SALT_MASTER_CREDENTIALS)
92 }
93 stage("Prepare instance"){
94 salt.runSaltProcessStep(venvPepper, '*apt*', 'saltutil.refresh_pillar', [], null, true)
95 salt.runSaltProcessStep(venvPepper, '*apt*', 'saltutil.sync_all', [], null, true)
96 salt.enforceState(venvPepper, '*apt*', ['salt'], true, false, null, false, -1, 2)
97 salt.enforceState(venvPepper, '*apt*', ['linux'], true, false, null, false, -1, 2)
98 salt.enforceState(venvPepper, '*apt*', ['nginx'], true, false, null, false, -1, 2)
99 }
100
101 stage("Create Docker Registry"){
102 common.infoMsg("Creating Docker Registry")
Richard Felklae5ef472017-12-21 15:35:54 +0100103 salt.enforceState(venvPepper, '*apt*', ["docker.host"], true, false, null, false, -1, 2)
104 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["docker run --restart always -d -p 5000:5000 --name registry registry:2"], null, true)
105 salt.enforceState(venvPepper, '*apt*', ["docker.client.registry"], true, false, null, false, -1, 2)
106 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["docker system prune --all --force"], null, true)
Richard Felkl2e9e5452017-10-16 09:52:10 +0200107 }
108
109 stage("Create Aptly"){
110 common.infoMsg("Creating Aptly")
111 salt.enforceState(venvPepper, '*apt*', ['aptly'], true, false, null, false, -1, 2)
112 //TODO: Do it new way
Richard Felklae5ef472017-12-21 15:35:54 +0100113 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly_mirror_update.sh -s -v", "runas=aptly"], null, true)
114 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["nohup aptly api serve --no-lock > /dev/null 2>&1 </dev/null &", "runas=aptly"], null, true)
115 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly-publisher --timeout=1200 publish -v -c /etc/aptly-publisher.yaml --architectures amd64 --url http://127.0.0.1:8080 --recreate --force-overwrite", "runas=aptly"], null, true)
116 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly db cleanup", "runas=aptly"], null, true)
Richard Felkl2e9e5452017-10-16 09:52:10 +0200117 //NEW way
Richard Felklae5ef472017-12-21 15:35:54 +0100118 //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", "runas=aptly"], null, true)
119 //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-acrfv", "runas=aptly"], null, true)
120 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/aptly/aptly-update.sh -O /srv/scripts/aptly-update.sh"], null, true)
121 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["chmod +x /srv/scripts/aptly-update.sh"], null, true)
Richard Felkl2e9e5452017-10-16 09:52:10 +0200122 }
123
124 stage("Create Git mirror"){
125 common.infoMsg("Creating Git mirror")
126 salt.enforceState(venvPepper, '*apt*', ['git.server'], true, false, null, false, -1, 2)
127 }
128
129 stage("Create PyPi mirror"){
130 common.infoMsg("Creating PyPi mirror")
Richard Felklae5ef472017-12-21 15:35:54 +0100131 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["pip install pip2pi"], null, true)
132 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/pypi_mirror/requirements.txt -O /srv/pypi_mirror/requirements.txt"], null, true)
133 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["pip2pi /srv/pypi_mirror/packages/ -r /srv/pypi_mirror/requirements.txt"], null, true)
Richard Felkl2e9e5452017-10-16 09:52:10 +0200134 }
135
136 stage("Create mirror of images"){
137 common.infoMsg("Creating mirror of images")
Richard Felklae5ef472017-12-21 15:35:54 +0100138 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/images_mirror/images.txt -O /srv/images.txt"], null, true)
139 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/images_mirror/update-images.sh -O /srv/scripts/update-images.sh"], null, true)
140 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["chmod +x /srv/scripts/update-images.sh"], null, true)
141 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["/srv/scripts/update-images.sh -u http://ci.mcp.mirantis.net:8085/images"], null, true)
Richard Felkl2e9e5452017-10-16 09:52:10 +0200142 }
143
144 stage("Create instance snapshot"){
Richard Felklae5ef472017-12-21 15:35:54 +0100145 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["rm -rf /var/lib/cloud/sem/* /var/lib/cloud/instance /var/lib/cloud/instances/*"], null, true)
146 salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["cloud-init init"], null, true)
Richard Felkl14a4c6f2017-11-29 09:10:10 +0100147
Richard Felkl7a006072017-12-13 09:47:07 +0100148 retry(3, 5){
149 openstack.runOpenstackCommand("openstack server stop mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
150 }
Richard Felkl14a4c6f2017-11-29 09:10:10 +0100151
Richard Felkl2e9e5452017-10-16 09:52:10 +0200152 retry(6, 30){
153 serverStatus = openstack.runOpenstackCommand("openstack server show --format value -c status mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
154 if(serverStatus != "SHUTOFF"){
155 throw new ResourceException("Instance is not ready for image create.")
156 }
157 }
Richard Felkl7a006072017-12-13 09:47:07 +0100158 retry(3, 5){
159 openstack.runOpenstackCommand("openstack server image create --name ${IMAGE_NAME}-${dateTime} --wait mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
160 }
Richard Felkl2e9e5452017-10-16 09:52:10 +0200161 }
162
163 stage("Publish image"){
Richard Felkl802e4462017-12-06 10:08:05 +0100164 common.infoMsg("Saving image ${IMAGE_NAME}-${dateTime}")
Richard Felkl7a006072017-12-13 09:47:07 +0100165 retry(3, 5){
166 openstack.runOpenstackCommand("openstack image save --file ${IMAGE_NAME}-${dateTime} ${IMAGE_NAME}-${dateTime}", rcFile, openstackEnv)
167 }
Richard Felkl802e4462017-12-06 10:08:05 +0100168 sh "md5sum ${IMAGE_NAME}-${dateTime} > ${IMAGE_NAME}-${dateTime}.md5"
169
170 common.infoMsg("Uploading image ${IMAGE_NAME}-${dateTime}")
171 retry(3, 5){
172 uploadImageStatus = sh(script: "curl -f -T ${IMAGE_NAME}-${dateTime} ${UPLOAD_URL}", returnStatus: true)
173 if(uploadImageStatus!=0){
174 throw new Exception("Image upload failed")
175 }
176 }
177 retry(3, 5){
178 uploadMd5Status = sh(script: "curl -f -T ${IMAGE_NAME}-${dateTime}.md5 ${UPLOAD_URL}", returnStatus: true)
179 if(uploadMd5Status != 0){
180 throw new Exception("MD5 sum upload failed")
181 }
182 }
Richard Felkl2e9e5452017-10-16 09:52:10 +0200183 }
184
185 } catch (Throwable e) {
186 // If there was an error or exception thrown, the build failed
187 currentBuild.result = "FAILURE"
188 throw e
189 } finally {
190 stage("Cleanup"){
191 if(openstackServer != ""){
192 openstack.runOpenstackCommand("openstack ip floating remove ${floatingIP} mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
193 openstack.runOpenstackCommand("openstack server delete mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
194 }
195 if(privateKey != ""){
196 openstack.runOpenstackCommand("openstack keypair delete mcp-offline-keypair-${dateTime}", rcFile, openstackEnv)
197 }
198 sh "rm -rf ./*"
199 }
200 }
201}