| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 1 | def common = new com.mirantis.mk.Common() | 
 | 2 | def salt = new com.mirantis.mk.Salt() | 
 | 3 | def python = new com.mirantis.mk.Python() | 
 | 4 | def pepperEnv = "pepperEnv" | 
| Denis Egorenko | c304b4f | 2019-07-25 16:57:48 +0400 | [diff] [blame] | 5 | def askConfirmation = (env.getProperty('ASK_CONFIRMATION') ?: true).toBoolean() | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 6 |  | 
 | 7 | timeout(time: 12, unit: 'HOURS') { | 
 | 8 |     node() { | 
| Denis Egorenko | 37f41db | 2019-07-24 17:05:24 +0400 | [diff] [blame] | 9 |         def backupNode = '' | 
 | 10 |         def backupServer = '' | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 11 |         stage('Setup virtualenv for Pepper') { | 
 | 12 |             python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS) | 
 | 13 |         } | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 14 |         stage('Verify pillar for backups') { | 
 | 15 |             try { | 
 | 16 |                 def masterPillar = salt.getPillar(pepperEnv, "I@salt:master", 'salt:master:initial_data') | 
 | 17 |                 if (masterPillar['return'].isEmpty()) { | 
 | 18 |                     throw new Exception('Problem with salt-master pillar.') | 
 | 19 |                 } | 
 | 20 |                 def minionPillar = salt.getPillar(pepperEnv, "I@salt:master", 'salt:minion:initial_data') | 
 | 21 |                 if (minionPillar['return'].isEmpty()) { | 
 | 22 |                     throw new Exception('Problem with salt-minion pillar.') | 
 | 23 |                 } | 
 | 24 |             } | 
 | 25 |             catch (Exception e) { | 
 | 26 |                 common.errorMsg(e.getMessage()) | 
 | 27 |                 common.errorMsg('Please fix your pillar. For more information check docs: https://docs.mirantis.com/mcp/latest/mcp-operations-guide/backup-restore/salt-master.html') | 
 | 28 |                 return | 
 | 29 |             } | 
 | 30 |         } | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 31 |         stage('Check backup location') { | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 32 |             try { | 
 | 33 |                 backupNode = salt.getMinions(pepperEnv, "I@backupninja:client")[0] | 
 | 34 |                 salt.minionsReachable(pepperEnv, "I@salt:master", backupNode) | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 35 |             } | 
 | 36 |             catch (Exception e) { | 
 | 37 |                 common.errorMsg(e.getMessage()) | 
 | 38 |                 common.errorMsg("Pipeline wasn't able to detect backupninja:client pillar or the minion is not reachable") | 
 | 39 |                 currentBuild.result = "FAILURE" | 
 | 40 |                 return | 
 | 41 |             } | 
| Denis Egorenko | 37f41db | 2019-07-24 17:05:24 +0400 | [diff] [blame] | 42 |  | 
| Denis Egorenko | c304b4f | 2019-07-25 16:57:48 +0400 | [diff] [blame] | 43 |             def postgresqlMajorVersion = salt.getPillar(pepperEnv, 'I@salt:master', '_param:postgresql_major_version').get('return')[0].values()[0] | 
| Denis Egorenko | 37f41db | 2019-07-24 17:05:24 +0400 | [diff] [blame] | 44 |             if (! postgresqlMajorVersion) { | 
 | 45 |                 input message: "Can't get _param:postgresql_major_version parameter, which is required to determine postgresql-client version. Is it defined in pillar? Confirm to proceed anyway." | 
 | 46 |             } else { | 
 | 47 |                 def postgresqlClientPackage = "postgresql-client-${postgresqlMajorVersion}" | 
 | 48 |                 try { | 
 | 49 |                     if (!salt.isPackageInstalled(['saltId': pepperEnv, 'target': backupNode, 'packageName': postgresqlClientPackage, 'output': false])) { | 
 | 50 |                         if (askConfirmation) { | 
| Denis Egorenko | c304b4f | 2019-07-25 16:57:48 +0400 | [diff] [blame] | 51 |                             input message: "Do you want to install ${postgresqlClientPackage} package on targeted nodes: ${backupNode}? It's required to make backup. Click to confirm" | 
| Denis Egorenko | 37f41db | 2019-07-24 17:05:24 +0400 | [diff] [blame] | 52 |                         } | 
 | 53 |                         // update also common fake package | 
 | 54 |                         salt.runSaltProcessStep(pepperEnv, backupNode, 'pkg.install', ["postgresql-client,${postgresqlClientPackage}"]) | 
 | 55 |                     } | 
 | 56 |                 } catch (Exception e) { | 
| Denis Egorenko | c304b4f | 2019-07-25 16:57:48 +0400 | [diff] [blame] | 57 |                     common.errorMsg("Unable to determine status of ${postgresqlClientPackage} packages on target nodes: ${backupNode}.") | 
| Denis Egorenko | 37f41db | 2019-07-24 17:05:24 +0400 | [diff] [blame] | 58 |                     if (askConfirmation) { | 
 | 59 |                         input message: "Do you want to continue? Click to confirm" | 
 | 60 |                     } | 
 | 61 |                 } | 
 | 62 |             } | 
 | 63 |  | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 64 |             try { | 
 | 65 |                 backupServer = salt.getMinions(pepperEnv, "I@backupninja:server")[0] | 
 | 66 |                 salt.minionsReachable(pepperEnv, "I@salt:master", backupServer) | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 67 |             } | 
 | 68 |             catch (Exception e) { | 
 | 69 |                 common.errorMsg(e.getMessage()) | 
 | 70 |                 common.errorMsg("Pipeline wasn't able to detect backupninja:server pillar or the minion is not reachable") | 
 | 71 |                 currentBuild.result = "FAILURE" | 
 | 72 |                 return | 
 | 73 |             } | 
 | 74 |         } | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 75 |         stage('Prepare for backup') { | 
 | 76 |             salt.enforceState(['saltId': pepperEnv, 'target': 'I@backupninja:server', 'state': 'backupninja']) | 
 | 77 |             salt.enforceState(['saltId': pepperEnv, 'target': 'I@backupninja:client', 'state': 'backupninja']) | 
 | 78 |             def backupMasterSource = salt.getReturnValues(salt.getPillar(pepperEnv, backupNode, 'salt:master:initial_data:source')) | 
 | 79 |             def backupMinionSource = salt.getReturnValues(salt.getPillar(pepperEnv, backupNode, 'salt:minion:initial_data:source')) | 
 | 80 |             [backupServer, backupMasterSource, backupMinionSource].unique().each { | 
 | 81 |                 salt.cmdRun(pepperEnv, backupNode, "ssh-keygen -F ${it} || ssh-keyscan -H ${it} >> /root/.ssh/known_hosts") | 
 | 82 |             } | 
| Ivan Berezovskiy | 34035bf | 2019-08-09 21:07:37 +0400 | [diff] [blame] | 83 |             def maasNodes = salt.getMinions(pepperEnv, 'I@maas:region') | 
 | 84 |             if (!maasNodes.isEmpty()) { | 
 | 85 |                 common.infoMsg("Trying to save maas file permissions on ${maasNodes} if possible") | 
 | 86 |                 salt.cmdRun(pepperEnv, 'I@maas:region', 'which getfacl && getfacl -pR /var/lib/maas/ > /var/lib/maas/file_permissions.txt || true') | 
 | 87 |             } | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 88 |         } | 
 | 89 |         stage('Backup') { | 
 | 90 |             def output = salt.getReturnValues(salt.cmdRun(pepperEnv, backupNode, "su root -c 'backupninja --now -d'")).readLines()[-2] | 
 | 91 |             def outputPattern = java.util.regex.Pattern.compile("\\d+") | 
 | 92 |             def outputMatcher = outputPattern.matcher(output) | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 93 |             if (outputMatcher.find()) { | 
 | 94 |                 try { | 
 | 95 |                     result = outputMatcher.getAt([0, 1, 2, 3]) | 
 | 96 |                 } | 
 | 97 |                 catch (Exception e) { | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 98 |                     common.errorMsg(e.getMessage()) | 
 | 99 |                     common.errorMsg("Parsing failed.") | 
 | 100 |                     currentBuild.result = "FAILURE" | 
 | 101 |                     return | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 102 |                 } | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 103 |             } | 
| Ivan Berezovskiy | 2219bf4 | 2019-07-22 16:54:06 +0400 | [diff] [blame] | 104 |             if (result[1] != null && result[1] instanceof String && result[1].isInteger() && (result[1].toInteger() < 1)) { | 
 | 105 |                 common.successMsg("Backup successfully finished " + result[1] + " fatals, " + result[2] + " errors " + result[3] + " warnings.") | 
 | 106 |             } else { | 
 | 107 |                 common.errorMsg("Backup failed. Found " + result[1] + " fatals, " + result[2] + " errors " + result[3] + " warnings.") | 
| Pavel Cizinsky | 2c681d6 | 2019-03-19 11:08:05 +0100 | [diff] [blame] | 108 |                 currentBuild.result = "FAILURE" | 
 | 109 |                 return | 
 | 110 |             } | 
 | 111 |         } | 
 | 112 |     } | 
 | 113 | } |