blob: 85f014fcb90014519b42eb8660742172c6d8acc9 [file] [log] [blame]
Sergey Kolekonovba203982016-12-21 18:32:17 +04001package com.mirantis.mk
2
3/**
4 *
5 * Openstack functions
6 *
7 */
8
9/**
Tomáš Kukrálc3964e52017-02-22 14:07:37 +010010 * Convert maps
11 *
12 */
13
14@NonCPS def entries(m) {
15 return m.collect {k, v -> [k, v]}
16}
17
18/**
Sergey Kolekonovba203982016-12-21 18:32:17 +040019 * Install OpenStack service clients in isolated environment
20 *
21 * @param path Path where virtualenv is created
22 * @param version Version of the OpenStack clients
23 */
24
Tomáš Kukrálbee0b992017-08-10 16:50:40 +020025def setupOpenstackVirtualenv(path, version = 'latest') {
iberezovskiyd4240b52017-02-20 17:18:28 +040026 def python = new com.mirantis.mk.Python()
Vasyl Saienko030fc182017-07-12 14:54:42 +030027 python.setupDocutilsVirtualenv(path)
Sergey Kolekonovba203982016-12-21 18:32:17 +040028
29 def openstack_kilo_packages = [
Jakub Josef268bc842017-10-10 14:36:17 +020030 //XXX: hack to fix https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1635463
31 'cliff==2.8',
Sergey Kolekonovba203982016-12-21 18:32:17 +040032 'python-cinderclient>=1.3.1,<1.4.0',
33 'python-glanceclient>=0.19.0,<0.20.0',
34 'python-heatclient>=0.6.0,<0.7.0',
35 'python-keystoneclient>=1.6.0,<1.7.0',
36 'python-neutronclient>=2.2.6,<2.3.0',
37 'python-novaclient>=2.19.0,<2.20.0',
38 'python-swiftclient>=2.5.0,<2.6.0',
Jakub Josefbd927322017-05-30 13:20:27 +000039 'python-openstackclient>=1.7.0,<1.8.0',
Sergey Kolekonovba203982016-12-21 18:32:17 +040040 'oslo.config>=2.2.0,<2.3.0',
41 'oslo.i18n>=2.3.0,<2.4.0',
42 'oslo.serialization>=1.8.0,<1.9.0',
43 'oslo.utils>=1.4.0,<1.5.0',
Jakub Josef60280212017-08-10 19:01:19 +020044 'docutils'
Sergey Kolekonovba203982016-12-21 18:32:17 +040045 ]
46
Tomáš Kukrál381a8c92017-06-21 09:01:52 +020047 def openstack_latest_packages = [
Jakub Josef268bc842017-10-10 14:36:17 +020048 //XXX: hack to fix https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1635463
49 'cliff==2.8',
Tomáš Kukrál381a8c92017-06-21 09:01:52 +020050 'python-openstackclient',
51 'python-heatclient',
Jakub Josef60280212017-08-10 19:01:19 +020052 'docutils'
Tomáš Kukrálc6a94c62017-06-19 14:44:24 +020053 ]
Sergey Kolekonovba203982016-12-21 18:32:17 +040054
Tomáš Kukrálc6a94c62017-06-19 14:44:24 +020055 if (version == 'kilo') {
Sergey Kolekonovba203982016-12-21 18:32:17 +040056 requirements = openstack_kilo_packages
Tomáš Kukrálc6a94c62017-06-19 14:44:24 +020057 } else if (version == 'liberty') {
Sergey Kolekonovba203982016-12-21 18:32:17 +040058 requirements = openstack_kilo_packages
Tomáš Kukrálc6a94c62017-06-19 14:44:24 +020059 } else if (version == 'mitaka') {
Sergey Kolekonovba203982016-12-21 18:32:17 +040060 requirements = openstack_kilo_packages
Tomáš Kukrál381a8c92017-06-21 09:01:52 +020061 } else {
Sergey Kolekonovba203982016-12-21 18:32:17 +040062 requirements = openstack_latest_packages
63 }
Tomáš Kukrálbee0b992017-08-10 16:50:40 +020064 python.setupVirtualenv(path, 'python2', requirements, null, true)
Sergey Kolekonovba203982016-12-21 18:32:17 +040065}
66
67/**
68 * create connection to OpenStack API endpoint
69 *
Jakub Josef6c963762018-01-18 16:02:22 +010070 * @param path Path to created venv
Sergey Kolekonovba203982016-12-21 18:32:17 +040071 * @param url OpenStack API endpoint address
72 * @param credentialsId Credentials to the OpenStack API
73 * @param project OpenStack project to connect to
74 */
Jakub Josef6c963762018-01-18 16:02:22 +010075def createOpenstackEnv(path, url, credentialsId, project, project_domain="default",
Tomáš Kukrál381a8c92017-06-21 09:01:52 +020076 project_id="", user_domain="default", api_ver="2", cacert="/etc/ssl/certs/ca-certificates.crt") {
iberezovskiyd4240b52017-02-20 17:18:28 +040077 def common = new com.mirantis.mk.Common()
Jakub Josef6c963762018-01-18 16:02:22 +010078 rcFile = "${path}/keystonerc"
Sergey Kolekonovba203982016-12-21 18:32:17 +040079 creds = common.getPasswordCredentials(credentialsId)
Alexander Tivelkovf89a1882017-01-11 13:29:35 +030080 rc = """set +x
81export OS_USERNAME=${creds.username}
Ales Komarek0e558ee2016-12-23 13:02:55 +010082export OS_PASSWORD=${creds.password.toString()}
83export OS_TENANT_NAME=${project}
84export OS_AUTH_URL=${url}
85export OS_AUTH_STRATEGY=keystone
kairat_kushaev0a26bf72017-05-18 13:20:09 +040086export OS_PROJECT_NAME=${project}
Jakub Josefbd927322017-05-30 13:20:27 +000087export OS_PROJECT_ID=${project_id}
kairat_kushaev0a26bf72017-05-18 13:20:09 +040088export OS_PROJECT_DOMAIN_ID=${project_domain}
Jakub Josefbd927322017-05-30 13:20:27 +000089export OS_USER_DOMAIN_NAME=${user_domain}
Kirill Mashchenko234708f2017-07-20 17:00:01 +030090export OS_IDENTITY_API_VERSION=${api_ver}
Tomáš Kukrál381a8c92017-06-21 09:01:52 +020091export OS_CACERT=${cacert}
Alexander Tivelkovf89a1882017-01-11 13:29:35 +030092set -x
Ales Komarek0e558ee2016-12-23 13:02:55 +010093"""
94 writeFile file: rcFile, text: rc
95 return rcFile
Sergey Kolekonovba203982016-12-21 18:32:17 +040096}
97
98/**
99 * Run command with OpenStack env params and optional python env
100 *
101 * @param cmd Command to be executed
102 * @param env Environmental parameters with endpoint credentials
103 * @param path Optional path to virtualenv with specific clients
104 */
105def runOpenstackCommand(cmd, venv, path = null) {
iberezovskiyd4240b52017-02-20 17:18:28 +0400106 def python = new com.mirantis.mk.Python()
Sergey Kolekonovba203982016-12-21 18:32:17 +0400107 openstackCmd = ". ${venv}; ${cmd}"
108 if (path) {
109 output = python.runVirtualenvCommand(path, openstackCmd)
110 }
111 else {
112 echo("[Command]: ${openstackCmd}")
113 output = sh (
114 script: openstackCmd,
115 returnStdout: true
116 ).trim()
117 }
118 return output
119}
120
121/**
122 * Get OpenStack Keystone token for current credentials
123 *
124 * @param env Connection parameters for OpenStack API endpoint
125 * @param path Optional path to the custom virtualenv
126 */
127def getKeystoneToken(client, path = null) {
iberezovskiyd4240b52017-02-20 17:18:28 +0400128 def python = new com.mirantis.mk.Python()
Jakub Josefbd927322017-05-30 13:20:27 +0000129 cmd = "openstack token issue"
Sergey Kolekonovba203982016-12-21 18:32:17 +0400130 outputTable = runOpenstackCommand(cmd, client, path)
Ales Komareke11e8792016-12-28 09:42:25 +0100131 output = python.parseTextTable(outputTable, 'item', 'prettytable', path)
Sergey Kolekonovba203982016-12-21 18:32:17 +0400132 return output
133}
134
135/**
Ales Komarek51b7b152017-06-27 11:14:50 +0200136 * Create OpenStack environment file
Sergey Kolekonovba203982016-12-21 18:32:17 +0400137 *
138 * @param env Connection parameters for OpenStack API endpoint
139 * @param path Optional path to the custom virtualenv
140 */
141def createHeatEnv(file, environment = [], original_file = null) {
142 if (original_file) {
143 envString = readFile file: original_file
Tomáš Kukrál03029442017-02-21 17:14:29 +0100144 } else {
Sergey Kolekonovba203982016-12-21 18:32:17 +0400145 envString = "parameters:\n"
146 }
Tomáš Kukrál03029442017-02-21 17:14:29 +0100147
Tomáš Kukrálc3964e52017-02-22 14:07:37 +0100148 p = entries(environment)
Tomáš Kukrálb1fe9642017-02-22 11:21:17 +0100149 for (int i = 0; i < p.size(); i++) {
150 envString = "${envString} ${p.get(i)[0]}: ${p.get(i)[1]}\n"
Sergey Kolekonovba203982016-12-21 18:32:17 +0400151 }
Tomáš Kukrál03029442017-02-21 17:14:29 +0100152
Tomáš Kukrále19ddea2017-02-21 11:09:40 +0100153 echo("writing to env file:\n${envString}")
Sergey Kolekonovba203982016-12-21 18:32:17 +0400154 writeFile file: file, text: envString
155}
156
157/**
158 * Create new OpenStack Heat stack
159 *
160 * @param env Connection parameters for OpenStack API endpoint
161 * @param template HOT template for the new Heat stack
162 * @param environment Environmentale parameters of the new Heat stack
163 * @param name Name of the new Heat stack
164 * @param path Optional path to the custom virtualenv
165 */
Tomáš Kukrála1152742017-08-22 16:21:50 +0200166def createHeatStack(client, name, template, params = [], environment = null, path = null, action="create") {
iberezovskiyd4240b52017-02-20 17:18:28 +0400167 def python = new com.mirantis.mk.Python()
Jakub Josef0a898762017-08-11 16:27:44 +0200168 def templateFile = "${env.WORKSPACE}/template/template/${template}.hot"
169 def envFile
170 def envSource
Sergey Kolekonovba203982016-12-21 18:32:17 +0400171 if (environment) {
Tomáš Kukrála1152742017-08-22 16:21:50 +0200172 envFile = "${env.WORKSPACE}/template/env/${name}.env"
173 if (environment.contains("/")) {
174 //init() returns all elements but the last in a collection.
175 def envPath = environment.tokenize("/").init().join("/")
176 if (envPath) {
177 envFile = "${env.WORKSPACE}/template/env/${envPath}/${name}.env"
178 }
Ales Komarek51b7b152017-06-27 11:14:50 +0200179 }
Tomáš Kukrála1152742017-08-22 16:21:50 +0200180 envSource = "${env.WORKSPACE}/template/env/${environment}.env"
Sergey Kolekonovba203982016-12-21 18:32:17 +0400181 createHeatEnv(envFile, params, envSource)
Jakub Josef9a59aeb2017-08-11 15:50:20 +0200182 } else {
Sergey Kolekonovba203982016-12-21 18:32:17 +0400183 envFile = "${env.WORKSPACE}/template/${name}.env"
184 createHeatEnv(envFile, params)
185 }
Tomáš Kukrála1152742017-08-22 16:21:50 +0200186
Mykyta Karpincf44f812017-08-28 14:45:21 +0300187 def cmd
188 def waitState
189
Tomáš Kukrála1152742017-08-22 16:21:50 +0200190 if (action == "create") {
Mykyta Karpincf44f812017-08-28 14:45:21 +0300191 cmd = "heat stack-create -f ${templateFile} -e ${envFile} ${name}"
192 waitState = "CREATE_COMPLETE"
Tomáš Kukrála1152742017-08-22 16:21:50 +0200193 } else {
Mykyta Karpincf44f812017-08-28 14:45:21 +0300194 cmd = "heat stack-update -f ${templateFile} -e ${envFile} ${name}"
195 waitState = "UPDATE_COMPLETE"
Tomáš Kukrála1152742017-08-22 16:21:50 +0200196 }
197
Sergey Kolekonovba203982016-12-21 18:32:17 +0400198 dir("${env.WORKSPACE}/template/template") {
199 outputTable = runOpenstackCommand(cmd, client, path)
200 }
Tomáš Kukrála1152742017-08-22 16:21:50 +0200201
Ales Komareke11e8792016-12-28 09:42:25 +0100202 output = python.parseTextTable(outputTable, 'item', 'prettytable', path)
Sergey Kolekonovba203982016-12-21 18:32:17 +0400203
Jakub Josef9a59aeb2017-08-11 15:50:20 +0200204 def heatStatusCheckerCount = 1
Jakub Josefe0337272017-09-12 14:15:27 +0200205 while (heatStatusCheckerCount <= 250) {
Sergey Kolekonovba203982016-12-21 18:32:17 +0400206 status = getHeatStackStatus(client, name, path)
Jakub Josef9a59aeb2017-08-11 15:50:20 +0200207 echo("[Heat Stack] Status: ${status}, Check: ${heatStatusCheckerCount}")
Ales Komarekdce8b472016-12-30 16:56:07 +0100208
Tomáš Kukrála1152742017-08-22 16:21:50 +0200209 if (status.contains('CREATE_FAILED')) {
Sergey Kolekonovba203982016-12-21 18:32:17 +0400210 info = getHeatStackInfo(client, name, path)
211 throw new Exception(info.stack_status_reason)
Tomáš Kukrála1152742017-08-22 16:21:50 +0200212
213 } else if (status.contains(waitState)) {
Sergey Kolekonovba203982016-12-21 18:32:17 +0400214 info = getHeatStackInfo(client, name, path)
215 echo(info.stack_status_reason)
216 break
217 }
Tomáš Kukrála1152742017-08-22 16:21:50 +0200218
Jakub Josefe0337272017-09-12 14:15:27 +0200219 sleep(30)
Jakub Josef9a59aeb2017-08-11 15:50:20 +0200220 heatStatusCheckerCount++
Sergey Kolekonovba203982016-12-21 18:32:17 +0400221 }
222 echo("[Heat Stack] Status: ${status}")
223}
224
225/**
Jakub Josefdb4baf22017-05-10 15:16:09 +0200226 * Returns list of stacks for stack name filter
227 *
228 * @param client Connection parameters for OpenStack API endpoint
229 * @param filter Stack name filter
230 * @param path Optional path to the custom virtualenv
231 */
232def getStacksForNameContains(client, filter, path = null){
Jakub Josef6465fca2017-05-10 16:09:20 +0200233 cmd = 'heat stack-list | awk \'NR>3 {print $4}\' | sed \'$ d\' | grep ' + filter + '|| true'
Jakub Josefdb4baf22017-05-10 15:16:09 +0200234 return runOpenstackCommand(cmd, client, path).trim().tokenize("\n")
235}
236
237
238/**
Jakub Josef5e238a22017-04-19 16:35:15 +0200239 * Get list of stack names with given stack status
240 *
Jakub Josefdb4baf22017-05-10 15:16:09 +0200241 * @param client Connection parameters for OpenStack API endpoint
Jakub Josef5e238a22017-04-19 16:35:15 +0200242 * @param status Stack status
243 * @param path Optional path to the custom virtualenv
244 */
245 def getStacksWithStatus(client, status, path = null) {
246 cmd = 'heat stack-list -f stack_status='+status+' | awk \'NR>3 {print $4}\' | sed \'$ d\''
247 return runOpenstackCommand(cmd, client, path).trim().tokenize("\n")
248 }
249
250/**
Sergey Kolekonovba203982016-12-21 18:32:17 +0400251 * Get life cycle status for existing OpenStack Heat stack
252 *
253 * @param env Connection parameters for OpenStack API endpoint
254 * @param name Name of the managed Heat stack instance
255 * @param path Optional path to the custom virtualenv
256 */
257def getHeatStackStatus(client, name, path = null) {
258 cmd = 'heat stack-list | awk -v stack='+name+' \'{if ($4==stack) print $6}\''
259 return runOpenstackCommand(cmd, client, path)
260}
261
262/**
263 * Get info about existing OpenStack Heat stack
264 *
265 * @param env Connection parameters for OpenStack API endpoint
266 * @param name Name of the managed Heat stack instance
267 * @param path Optional path to the custom virtualenv
268 */
269def getHeatStackInfo(env, name, path = null) {
iberezovskiyd4240b52017-02-20 17:18:28 +0400270 def python = new com.mirantis.mk.Python()
Sergey Kolekonovba203982016-12-21 18:32:17 +0400271 cmd = "heat stack-show ${name}"
272 outputTable = runOpenstackCommand(cmd, env, path)
Ales Komareke11e8792016-12-28 09:42:25 +0100273 output = python.parseTextTable(outputTable, 'item', 'prettytable', path)
Sergey Kolekonovba203982016-12-21 18:32:17 +0400274 return output
275}
276
277/**
278 * Get existing OpenStack Heat stack output parameter
279 *
280 * @param env Connection parameters for OpenStack API endpoint
281 * @param name Name of the managed Heat stack
282 * @param parameter Name of the output parameter
283 * @param path Optional path to the custom virtualenv
284 */
285def getHeatStackOutputParam(env, name, outputParam, path = null) {
Vasyl Saienkoea4b2812017-07-10 10:36:03 +0000286 cmd = "heat output-show ${name} ${outputParam}"
Sergey Kolekonovba203982016-12-21 18:32:17 +0400287 output = runOpenstackCommand(cmd, env, path)
Ales Komarekeedc2222017-01-03 10:10:03 +0100288 echo("${cmd}: ${output}")
Vasyl Saienko2a1c2de2017-07-11 11:41:53 +0300289 // NOTE(vsaienko) heatclient 1.5.1 returns output in "", while later
290 // versions returns string without "".
291 // TODO Use openstack 'stack output show' when all jobs using at least Mitaka heatclient
292 return "${output}".replaceAll('"', '')
Sergey Kolekonovba203982016-12-21 18:32:17 +0400293}
294
295/**
296 * List all resources from existing OpenStack Heat stack
297 *
298 * @param env Connection parameters for OpenStack API endpoint
299 * @param name Name of the managed Heat stack instance
300 * @param path Optional path to the custom virtualenv
Mykyta Karpin72306362018-02-08 16:40:43 +0200301 * @param depth Optional depth of stack for listing resources,
302 * 0 - do not list nested resources
Sergey Kolekonovba203982016-12-21 18:32:17 +0400303 */
Mykyta Karpin72306362018-02-08 16:40:43 +0200304def getHeatStackResources(env, name, path = null, depth = 0) {
iberezovskiyd4240b52017-02-20 17:18:28 +0400305 def python = new com.mirantis.mk.Python()
Mykyta Karpin72306362018-02-08 16:40:43 +0200306 cmd = "heat resource-list --nested-depth ${depth} ${name}"
Sergey Kolekonovba203982016-12-21 18:32:17 +0400307 outputTable = runOpenstackCommand(cmd, env, path)
Ales Komareke11e8792016-12-28 09:42:25 +0100308 output = python.parseTextTable(outputTable, 'list', 'prettytable', path)
Sergey Kolekonovba203982016-12-21 18:32:17 +0400309 return output
310}
311
312/**
313 * Get info about resource from existing OpenStack Heat stack
314 *
315 * @param env Connection parameters for OpenStack API endpoint
316 * @param name Name of the managed Heat stack instance
317 * @param path Optional path to the custom virtualenv
318 */
319def getHeatStackResourceInfo(env, name, resource, path = null) {
iberezovskiyd4240b52017-02-20 17:18:28 +0400320 def python = new com.mirantis.mk.Python()
Sergey Kolekonovba203982016-12-21 18:32:17 +0400321 cmd = "heat resource-show ${name} ${resource}"
322 outputTable = runOpenstackCommand(cmd, env, path)
Ales Komareke11e8792016-12-28 09:42:25 +0100323 output = python.parseTextTable(outputTable, 'item', 'prettytable', path)
Sergey Kolekonovba203982016-12-21 18:32:17 +0400324 return output
325}
326
327/**
328 * Update existing OpenStack Heat stack
329 *
330 * @param env Connection parameters for OpenStack API endpoint
331 * @param name Name of the managed Heat stack instance
332 * @param path Optional path to the custom virtualenv
333 */
334def updateHeatStack(env, name, path = null) {
iberezovskiyd4240b52017-02-20 17:18:28 +0400335 def python = new com.mirantis.mk.Python()
Sergey Kolekonovba203982016-12-21 18:32:17 +0400336 cmd = "heat stack-update ${name}"
337 outputTable = runOpenstackCommand(cmd, env, path)
Ales Komareke11e8792016-12-28 09:42:25 +0100338 output = python.parseTextTable(outputTable, 'item', 'prettytable', path)
Sergey Kolekonovba203982016-12-21 18:32:17 +0400339 return output
340}
341
342/**
343 * Delete existing OpenStack Heat stack
344 *
345 * @param env Connection parameters for OpenStack API endpoint
346 * @param name Name of the managed Heat stack instance
347 * @param path Optional path to the custom virtualenv
348 */
349def deleteHeatStack(env, name, path = null) {
350 cmd = "heat stack-delete ${name}"
351 outputTable = runOpenstackCommand(cmd, env, path)
352}
353
354/**
Mykyta Karpin72306362018-02-08 16:40:43 +0200355 * Return hashmap of hashes server_id:server_name of servers from OpenStack Heat stack
Sergey Kolekonovba203982016-12-21 18:32:17 +0400356 *
357 * @param env Connection parameters for OpenStack API endpoint
358 * @param name Name of the managed Heat stack instance
359 * @param path Optional path to the custom virtualenv
360 */
361def getHeatStackServers(env, name, path = null) {
Mykyta Karpin72306362018-02-08 16:40:43 +0200362 // set depth to 1000 to ensure all nested resources are shown
363 resources = getHeatStackResources(env, name, path, 1000)
364 servers = [:]
Sergey Kolekonovba203982016-12-21 18:32:17 +0400365 for (resource in resources) {
366 if (resource.resource_type == 'OS::Nova::Server') {
Mykyta Karpin67978112018-02-22 11:16:45 +0200367 server = getHeatStackResourceInfo(env, resource.stack_name, resource.resource_name, path)
Mykyta Karpin72306362018-02-08 16:40:43 +0200368 servers[server.attributes.id] = server.attributes.name
Sergey Kolekonovba203982016-12-21 18:32:17 +0400369 }
370 }
371 echo("[Stack ${name}] Servers: ${servers}")
372 return servers
373}
Jiri Broulikf8f96942018-02-15 10:03:42 +0100374
375/**
376 * Stops all services that contain specific string (for example nova,heat, etc.)
377 * @param env Salt Connection object or pepperEnv
378 * @param probe single node on which to list service names
379 * @param target all targeted nodes
380 * @param services lists of type of services to be stopped
Jiri Broulikf6daac62018-03-08 13:17:53 +0100381 * @param confirm enable/disable manual service stop confirmation
Jiri Broulikf8f96942018-02-15 10:03:42 +0100382 * @return output of salt commands
383 */
Jiri Broulik27e83052018-03-06 11:37:29 +0100384def stopServices(env, probe, target, services=[], confirm=false) {
Jiri Broulikf8f96942018-02-15 10:03:42 +0100385 def salt = new com.mirantis.mk.Salt()
Jiri Broulikf6daac62018-03-08 13:17:53 +0100386 def common = new com.mirantis.mk.Common()
Jiri Broulikf8f96942018-02-15 10:03:42 +0100387 for (s in services) {
388 def outputServicesStr = salt.getReturnValues(salt.cmdRun(env, "${probe}*", "service --status-all | grep ${s} | awk \'{print \$4}\'"))
Jiri Broulikf6daac62018-03-08 13:17:53 +0100389 def servicesList = outputServicesStr.tokenize("\n").init()
Jiri Broulik27e83052018-03-06 11:37:29 +0100390 if (confirm) {
Jiri Broulikf6daac62018-03-08 13:17:53 +0100391 if (servicesList) {
392 try {
393 input message: "Click PROCEED to stop ${servicesList}. Otherwise click ABORT to skip stopping them."
394 for (name in servicesList) {
395 if (!name.contains('Salt command')) {
396 salt.runSaltProcessStep(env, "${target}*", 'service.stop', ["${name}"])
397 }
398 }
399 } catch (Exception er) {
400 common.infoMsg("skipping stopping ${servicesList} services")
401 }
402 }
403 } else {
404 if (servicesList) {
Jiri Broulik27e83052018-03-06 11:37:29 +0100405 for (name in servicesList) {
406 if (!name.contains('Salt command')) {
407 salt.runSaltProcessStep(env, "${target}*", 'service.stop', ["${name}"])
408 }
409 }
Jiri Broulikf8f96942018-02-15 10:03:42 +0100410 }
411 }
412 }
413}
414
415/**
416 * Restores Galera database
417 * @param env Salt Connection object or pepperEnv
418 * @return output of salt commands
419 */
420def restoreGaleraDb(env) {
421 def salt = new com.mirantis.mk.Salt()
422 def common = new com.mirantis.mk.Common()
423 try {
424 salt.runSaltProcessStep(env, 'I@galera:slave', 'service.stop', ['mysql'])
425 } catch (Exception er) {
426 common.warningMsg('Mysql service already stopped')
427 }
428 try {
429 salt.runSaltProcessStep(env, 'I@galera:master', 'service.stop', ['mysql'])
430 } catch (Exception er) {
431 common.warningMsg('Mysql service already stopped')
432 }
433 try {
434 salt.cmdRun(env, 'I@galera:slave', "rm /var/lib/mysql/ib_logfile*")
435 } catch (Exception er) {
436 common.warningMsg('Files are not present')
437 }
438 try {
439 salt.cmdRun(env, 'I@galera:master', "mkdir /root/mysql/mysql.bak")
440 } catch (Exception er) {
441 common.warningMsg('Directory already exists')
442 }
443 try {
444 salt.cmdRun(env, 'I@galera:master', "rm -rf /root/mysql/mysql.bak/*")
445 } catch (Exception er) {
446 common.warningMsg('Directory already empty')
447 }
448 try {
449 salt.cmdRun(env, 'I@galera:master', "mv /var/lib/mysql/* /root/mysql/mysql.bak")
450 } catch (Exception er) {
451 common.warningMsg('Files were already moved')
452 }
453 try {
454 salt.runSaltProcessStep(env, 'I@galera:master', 'file.remove', ["/var/lib/mysql/.galera_bootstrap"])
455 } catch (Exception er) {
456 common.warningMsg('File is not present')
457 }
458 salt.cmdRun(env, 'I@galera:master', "sed -i '/gcomm/c\\wsrep_cluster_address=\"gcomm://\"' /etc/mysql/my.cnf")
459 def backup_dir = salt.getReturnValues(salt.getPillar(env, "I@galera:master", 'xtrabackup:client:backup_dir'))
460 if(backup_dir == null || backup_dir.isEmpty()) { backup_dir='/var/backups/mysql/xtrabackup' }
461 salt.runSaltProcessStep(env, 'I@galera:master', 'file.remove', ["${backup_dir}/dbrestored"])
462 salt.cmdRun(env, 'I@xtrabackup:client', "su root -c 'salt-call state.sls xtrabackup'")
463 salt.runSaltProcessStep(env, 'I@galera:master', 'service.start', ['mysql'])
464
465 // wait until mysql service on galera master is up
Jiri Broulik22b04572018-02-16 12:02:41 +0100466 try {
467 salt.commandStatus(env, 'I@galera:master', 'service mysql status', 'running')
468 } catch (Exception er) {
469 input message: "Database is not running please fix it first and only then click on PROCEED."
470 }
Jiri Broulikf8f96942018-02-15 10:03:42 +0100471
472 salt.runSaltProcessStep(env, 'I@galera:slave', 'service.start', ['mysql'])
473}