blob: 3c195ea9a6e3c251bd8a30c7de7a8e4cffbf88b7 [file] [log] [blame]
Mateusz Los36e64e02019-03-11 14:31:14 +01001/**
2 *
Roman Lubianyiaf11e532020-03-13 16:04:09 +02003 * Add Ceph OSD node to existing cluster using upmap mechanism
Mateusz Los36e64e02019-03-11 14:31:14 +01004 *
5 * Requred parameters:
6 * SALT_MASTER_URL URL of Salt master
7 * SALT_MASTER_CREDENTIALS Credentials to the Salt API
Roman Lubianyiaf11e532020-03-13 16:04:09 +02008 * HOST OSD Host (minion id) to be added
Mateusz Los36e64e02019-03-11 14:31:14 +01009 *
10 */
11
Mateusz Los36e64e02019-03-11 14:31:14 +010012salt = new com.mirantis.mk.Salt()
13def python = new com.mirantis.mk.Python()
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040014def ceph = new com.mirantis.mk.Ceph()
Mateusz Los36e64e02019-03-11 14:31:14 +010015orchestrate = new com.mirantis.mk.Orchestrate()
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040016pepperEnv = "pepperEnv"
Ivan Berezovskiy4c39c7d2019-11-19 20:04:12 +040017def flags = CLUSTER_FLAGS ? CLUSTER_FLAGS.tokenize(',') : []
Mateusz Los36e64e02019-03-11 14:31:14 +010018
19def runCephCommand(cmd) {
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040020 return salt.cmdRun(pepperEnv, "I@ceph:mon and I@ceph:common:keyring:admin", cmd, checkResponse = true, batch = null, output = false)
Mateusz Los36e64e02019-03-11 14:31:14 +010021}
22
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040023def getpgmap() {
24 return runCephCommand('ceph pg ls remapped --format=json')['return'][0].values()[0]
Mateusz Los36e64e02019-03-11 14:31:14 +010025}
26
27def generatemapping(master,pgmap,map) {
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040028 def pg_new
29 def pg_old
30 for (pg in pgmap) {
31 pg_new = pg["up"].minus(pg["acting"])
32 pg_old = pg["acting"].minus(pg["up"])
33 for (i = 0; i < pg_new.size(); i++) {
34 def string = "ceph osd pg-upmap-items " + pg["pgid"].toString() + " " + pg_new[i] + " " + pg_old[i] + ";"
35 map.add(string)
36 }
Mateusz Los36e64e02019-03-11 14:31:14 +010037 }
Mateusz Los36e64e02019-03-11 14:31:14 +010038}
39
Mateusz Los36e64e02019-03-11 14:31:14 +010040timeout(time: 12, unit: 'HOURS') {
41 node("python") {
Roman Lubianyiaf11e532020-03-13 16:04:09 +020042 try {
43 // create connection to salt master
44 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Mateusz Los36e64e02019-03-11 14:31:14 +010045
Roman Lubianyiaf11e532020-03-13 16:04:09 +020046 if (!HOST.toLowerCase().contains("osd")) {
47 common.errorMsg("This pipeline can only be used to add new OSD nodes to an existing Ceph cluster.")
48 throw new InterruptedException()
Mateusz Los36e64e02019-03-11 14:31:14 +010049 }
Mateusz Los36e64e02019-03-11 14:31:14 +010050
Roman Lubianyiaf11e532020-03-13 16:04:09 +020051 stage ("verify client versions")
52 {
53 // I@docker:swarm and I@prometheus:server - mon* nodes
54 def nodes = salt.getMinions(pepperEnv, "I@ceph:common and not ( I@docker:swarm and I@prometheus:server )")
55 for ( node in nodes )
56 {
57 def versions = salt.cmdRun(pepperEnv, node, "ceph features --format json", checkResponse=true, batch=null, output=false).values()[0]
58 versions = new groovy.json.JsonSlurperClassic().parseText(versions[0][node])
59 if ( versions['client']['group']['release'] != 'luminous' )
60 {
61 throw new Exception("client installed on " + node + " is not luminous. Update all clients to luminous before using this pipeline")
62 }
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040063 }
Mateusz Los36e64e02019-03-11 14:31:14 +010064 }
Mateusz Los36e64e02019-03-11 14:31:14 +010065
Roman Lubianyiaf11e532020-03-13 16:04:09 +020066 stage("enable luminous compat") {
67 runCephCommand('ceph osd set-require-min-compat-client luminous')['return'][0].values()[0]
68 }
69
70 stage("enable upmap balancer") {
71 runCephCommand('ceph balancer on')['return'][0].values()[0]
72 runCephCommand('ceph balancer mode upmap')['return'][0].values()[0]
73 }
74
75 stage("set norebalance") {
76 runCephCommand('ceph osd set norebalance')['return'][0].values()[0]
77 }
78
79 stage('Install infra') {
80 orchestrate.installFoundationInfraOnTarget(pepperEnv, HOST)
81 }
82
83 stage('Install Ceph OSD') {
84 orchestrate.installCephOsd(pepperEnv, HOST)
85 }
86
87 stage("Update/Install monitoring") {
88 def prometheusNodes = salt.getMinions(pepperEnv, 'I@prometheus:server')
89 if (!prometheusNodes.isEmpty()) {
90 //Collect Grains
91 salt.enforceState(pepperEnv, HOST, 'salt.minion.grains')
92 salt.runSaltProcessStep(pepperEnv, HOST, 'saltutil.refresh_modules')
93 salt.runSaltProcessStep(pepperEnv, HOST, 'mine.update')
94 sleep(5)
95 salt.enforceState(pepperEnv, HOST, ['fluentd', 'telegraf', 'prometheus'])
96 salt.enforceState(pepperEnv, 'I@prometheus:server', 'prometheus')
97 } else {
98 common.infoMsg('No Prometheus nodes in cluster. Nothing to do')
99 }
100 }
101
102 stage("Update host files") {
103 salt.enforceState(pepperEnv, '*', 'linux.network.host')
104 }
105
106 def mapping = []
107
108 stage("update mappings") {
109 def pgmap
110 for (int x = 1; x <= 3; x++) {
111 pgmap = getpgmap()
112 if (pgmap == '') {
113 return 1
114 } else {
115 pgmap = new groovy.json.JsonSlurperClassic().parseText(pgmap)
116 generatemapping(pepperEnv, pgmap, mapping)
117 mapping.each(this.&runCephCommand)
118 sleep(30)
119 }
120 }
121 }
122
123 stage("unset norebalance") {
124 runCephCommand('ceph osd unset norebalance')['return'][0].values()[0]
125 }
126
127 stage("wait for healthy cluster") {
128 ceph.waitForHealthy(pepperEnv, "I@ceph:mon and I@ceph:common:keyring:admin", flags)
129 }
130 }
131 catch (Throwable e) {
132 // There was an error or exception thrown. Unset norebalance.
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +0400133 runCephCommand('ceph osd unset norebalance')['return'][0].values()[0]
Roman Lubianyiaf11e532020-03-13 16:04:09 +0200134 throw e
Mateusz Los36e64e02019-03-11 14:31:14 +0100135 }
Mateusz Los36e64e02019-03-11 14:31:14 +0100136 }
137}