blob: 054c0ccc4070cf50ce640e9ca53cb9c6c98f4fa8 [file] [log] [blame]
Martin Polreichf7a1bb02018-12-05 11:12:23 +01001/**
2 * Verify and restore Galera cluster
3 *
4 * Expected parameters:
5 * SALT_MASTER_CREDENTIALS Credentials to the Salt API.
6 * SALT_MASTER_URL Full Salt API address [http://10.10.10.1:8000].
Sergey6579de62019-01-15 17:27:59 +04007 * ASK_CONFIRMATION Ask confirmation for restore
Martin Polreich721b7252019-01-21 14:42:48 +01008 * CHECK_TIME_SYNC Set to true to check time synchronization accross selected nodes.
Martin Polreichf7889b52019-02-01 14:46:10 +01009 * VERIFICATION_RETRIES Number of restries to verify the restoration.
Martin Polreichddfdb612019-03-21 15:12:15 +010010 * RESTORE_TYPE Sets restoration method
Martin Polreichf7a1bb02018-12-05 11:12:23 +010011 *
12**/
13
14def common = new com.mirantis.mk.Common()
15def salt = new com.mirantis.mk.Salt()
Martin Polreich208c4872019-02-15 10:09:10 +010016def galera = new com.mirantis.mk.Galera()
Martin Polreichf7a1bb02018-12-05 11:12:23 +010017def python = new com.mirantis.mk.Python()
Martin Polreichf7a1bb02018-12-05 11:12:23 +010018def pepperEnv = "pepperEnv"
19def resultCode = 99
Martin Polreichddfdb612019-03-21 15:12:15 +010020def restoreType = env.RESTORE_TYPE
21def runRestoreDb = false
22def runBackupDb = false
Martin Polreichf7a1bb02018-12-05 11:12:23 +010023
Sergey6579de62019-01-15 17:27:59 +040024askConfirmation = (env.getProperty('ASK_CONFIRMATION') ?: true).toBoolean()
Martin Polreich721b7252019-01-21 14:42:48 +010025checkTimeSync = (env.getProperty('CHECK_TIME_SYNC') ?: true).toBoolean()
Martin Polreich49f16c02019-02-04 13:14:01 +010026if (common.validInputParam('VERIFICATION_RETRIES') && VERIFICATION_RETRIES.isInteger()) {
Martin Polreichf7889b52019-02-01 14:46:10 +010027 verificationRetries = VERIFICATION_RETRIES.toInteger()
28} else {
29 verificationRetries = 5
30}
Martin Polreichddfdb612019-03-21 15:12:15 +010031if (restoreType.equals("BACKUP_AND_RESTORE") || restoreType.equals("ONLY_RESTORE")) {
32 runRestoreDb = true
33}
34if (restoreType.equals("BACKUP_AND_RESTORE")) {
35 runBackupDb = true
36}
Sergey6579de62019-01-15 17:27:59 +040037
Martin Polreichf7a1bb02018-12-05 11:12:23 +010038timeout(time: 12, unit: 'HOURS') {
39 node() {
40 stage('Setup virtualenv for Pepper') {
41 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
42 }
Martin Polreichddfdb612019-03-21 15:12:15 +010043 stage('Verify status') {
Martin Polreich208c4872019-02-15 10:09:10 +010044 resultCode = galera.verifyGaleraStatus(pepperEnv, false, checkTimeSync)
Martin Polreichf7a1bb02018-12-05 11:12:23 +010045 if (resultCode == 128) {
46 common.errorMsg("Unable to connect to Galera Master. Trying slaves...")
Martin Polreich208c4872019-02-15 10:09:10 +010047 resultCode = galera.verifyGaleraStatus(pepperEnv, true, checkTimeSync)
Martin Polreichf7a1bb02018-12-05 11:12:23 +010048 if (resultCode == 129) {
Martin Polreich0f3b85d2019-04-02 14:22:11 +020049 common.errorMsg("Unable to obtain Galera slave minions list". "Without fixing this issue, pipeline cannot continue in verification, backup and restoration.")
Martin Polreichf7a1bb02018-12-05 11:12:23 +010050 currentBuild.result = "FAILURE"
Martin Polreichf7889b52019-02-01 14:46:10 +010051 return
Martin Polreichf7a1bb02018-12-05 11:12:23 +010052 } else if (resultCode == 130) {
Martin Polreich0f3b85d2019-04-02 14:22:11 +020053 common.errorMsg("Neither master or slaves are reachable. Without fixing this issue, pipeline cannot continue in verification, backup and restoration.")
Martin Polreichf7a1bb02018-12-05 11:12:23 +010054 currentBuild.result = "FAILURE"
Martin Polreichf7889b52019-02-01 14:46:10 +010055 return
Martin Polreichf7a1bb02018-12-05 11:12:23 +010056 }
57 }
Martin Polreich721b7252019-01-21 14:42:48 +010058 if (resultCode == 131) {
Martin Polreich0f3b85d2019-04-02 14:22:11 +020059 common.errorMsg("Time desynced - Please fix this issue and rerun the pipeline.")
Martin Polreich721b7252019-01-21 14:42:48 +010060 currentBuild.result = "FAILURE"
Martin Polreich0f3b85d2019-04-02 14:22:11 +020061 return
62 }
63 if (resultCode == 140 || resultCode == 141) {
64 common.errorMsg("Disk utilization check failed - Please fix this issue and rerun the pipeline.")
65 currentBuild.result = "FAILURE"
66 return
Martin Polreich721b7252019-01-21 14:42:48 +010067 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +010068 if (resultCode == 1) {
Sergey6579de62019-01-15 17:27:59 +040069 if(askConfirmation){
70 common.warningMsg("There was a problem with parsing the status output or with determining it. Do you want to run a restore?")
71 } else {
72 common.warningMsg("There was a problem with parsing the status output or with determining it. Try to restore.")
73 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +010074 } else if (resultCode > 1) {
Sergey6579de62019-01-15 17:27:59 +040075 if(askConfirmation){
Martin Polreich0f3b85d2019-04-02 14:22:11 +020076 common.warningMsg("There's something wrong with the cluster, do you want to continue with backup and/or restore?")
Sergey6579de62019-01-15 17:27:59 +040077 } else {
Martin Polreich0f3b85d2019-04-02 14:22:11 +020078 common.warningMsg("There's something wrong with the cluster, try to backup and/or restore.")
Sergey6579de62019-01-15 17:27:59 +040079 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +010080 } else {
Sergey6579de62019-01-15 17:27:59 +040081 if(askConfirmation){
Martin Polreich0f3b85d2019-04-02 14:22:11 +020082 common.warningMsg("There seems to be everything alright with the cluster, do you still want to continue with backup and/or restore?")
Sergey6579de62019-01-15 17:27:59 +040083 } else {
Martin Polreich0f3b85d2019-04-02 14:22:11 +020084 common.warningMsg("There seems to be everything alright with the cluster, no backup and no restoration will be done.")
85 currentBuild.result = "SUCCESS"
86 return
Sergey6579de62019-01-15 17:27:59 +040087 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +010088 }
Martin Polreich0f3b85d2019-04-02 14:22:11 +020089 }
90 if (runBackupDb) {
91 stage('Backup') {
92 common.infoMsg("Running backup job.")
93 deployBuild = build( job: "galera-database-backup-pipeline", parameters: [
Martin Polreich7b1766c2019-04-11 16:45:54 +020094 [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: SALT_MASTER_URL],
95 [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: SALT_MASTER_CREDENTIALS],
96 [$class: 'StringParameterValue', name: 'OVERRIDE_BACKUP_NODE', value: "none"],
Martin Polreich0f3b85d2019-04-02 14:22:11 +020097 ]
98 )
99 }
100 }
101 stage('Restore') {
Sergey6579de62019-01-15 17:27:59 +0400102 if(askConfirmation){
103 input message: "Are you sure you want to run a restore? Click to confirm"
104 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +0100105 try {
Sergey6579de62019-01-15 17:27:59 +0400106 if((!askConfirmation && resultCode > 0) || askConfirmation){
Martin Polreichddfdb612019-03-21 15:12:15 +0100107 galera.restoreGaleraCluster(pepperEnv, runRestoreDb)
Sergey6579de62019-01-15 17:27:59 +0400108 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +0100109 } catch (Exception e) {
110 common.errorMsg("Restoration process has failed.")
111 }
112 }
Martin Polreich7bc654c2019-01-18 14:17:52 +0100113 stage('Verify restoration result') {
Martin Polreichf7889b52019-02-01 14:46:10 +0100114 common.retry(verificationRetries, 15) {
Martin Polreich208c4872019-02-15 10:09:10 +0100115 exitCode = galera.verifyGaleraStatus(pepperEnv, false, false)
Martin Polreichf7889b52019-02-01 14:46:10 +0100116 if (exitCode >= 1) {
Martin Polreich49f16c02019-02-04 13:14:01 +0100117 error("Verification attempt finished with an error. This may be caused by cluster not having enough time to come up or to sync. Next verification attempt in 15 seconds.")
Martin Polreichf7889b52019-02-01 14:46:10 +0100118 } else {
119 common.infoMsg("Restoration procedure seems to be successful. See verification report to be sure.")
120 currentBuild.result = "SUCCESS"
121 }
Martin Polreich7bc654c2019-01-18 14:17:52 +0100122 }
123 }
Martin Polreichf7a1bb02018-12-05 11:12:23 +0100124 }
125}