blob: 66e942224834b7fe81582bd8f263e0a3481e51ad [file] [log] [blame]
Tomáš Kukrálf72096d2017-08-11 12:58:03 +02001/**
2 *
3 * Remove OSD from existing cluster
4 *
5 * Requred parameters:
6 * SALT_MASTER_URL URL of Salt master
7 * SALT_MASTER_CREDENTIALS Credentials to the Salt API
8 *
9 * HOST Host (minion id) to be removed
Jiri Broulik2c00f4c2017-10-26 13:23:11 +020010 * OSD Comma separated list of osd ids to be removed
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020011 * ADMIN_HOST Host (minion id) with admin keyring
12 * CLUSTER_FLAGS Comma separated list of tags to apply to cluster
13 * WAIT_FOR_HEALTHY Wait for cluster rebalance before stoping daemons
14 *
15 */
16
17common = new com.mirantis.mk.Common()
18salt = new com.mirantis.mk.Salt()
chnyda625f4b42017-10-11 14:10:31 +020019def python = new com.mirantis.mk.Python()
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020020
chnyda625f4b42017-10-11 14:10:31 +020021def pepperEnv = "pepperEnv"
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020022def flags = CLUSTER_FLAGS.tokenize(',')
Tomáš Kukrál9d6228b2017-08-15 16:54:55 +020023def osds = OSD.tokenize(',')
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020024
Jiri Broulikeb7b82f2017-11-30 13:55:40 +010025
Jiri Broulika5bc8f62018-01-31 15:04:40 +010026def removePartition(master, target, partition_uuid, type='', id=-1) {
27 def partition = ""
28 if (type == 'lockbox') {
29 try {
30 // umount - partition = /dev/sdi2
31 partition = runCephCommand(master, target, "lsblk -rp | grep -v mapper | grep ${partition_uuid} ")['return'][0].values()[0].split()[0]
32 runCephCommand(master, target, "umount ${partition}")
33 } catch (Exception e) {
34 common.warningMsg(e)
35 }
36 } else if (type == 'data') {
37 try {
38 // umount - partition = /dev/sdi2
39 partition = runCephCommand(master, target, "df | grep /var/lib/ceph/osd/ceph-${id}")['return'][0].values()[0].split()[0]
40 runCephCommand(master, target, "umount ${partition}")
41 } catch (Exception e) {
42 common.warningMsg(e)
43 }
44 try {
45 // partition = /dev/sdi2
46 partition = runCephCommand(master, target, "blkid | grep ${partition_uuid} ")['return'][0].values()[0].split(":")[0]
47 } catch (Exception e) {
48 common.warningMsg(e)
49 }
50 } else {
51 try {
52 // partition = /dev/sdi2
53 partition = runCephCommand(master, target, "blkid | grep ${partition_uuid} ")['return'][0].values()[0].split(":")[0]
54 } catch (Exception e) {
55 common.warningMsg(e)
56 }
57 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +010058 if (partition?.trim()) {
Mateusz Losaba63db2019-09-02 18:28:55 +020059 def part_id
60 if (partition.contains("nvme")) {
61 part_id = partition.substring(partition.lastIndexOf("p")+1).replaceAll("[^0-9]+", "")
62 }
63 else {
64 part_id = partition.substring(partition.lastIndexOf("/")+1).replaceAll("[^0-9]+", "")
65 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +010066 def dev = partition.replaceAll('\\d+$', "")
Jiri Broulika5bc8f62018-01-31 15:04:40 +010067 runCephCommand(master, target, "Ignore | parted ${dev} rm ${part_id}")
Jiri Broulikeb7b82f2017-11-30 13:55:40 +010068 }
69 return
70}
71
72def runCephCommand(master, target, cmd) {
73 return salt.cmdRun(master, target, cmd)
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020074}
75
Jiri Broulik96c867a2017-11-07 16:14:10 +010076def waitForHealthy(master, count=0, attempts=300) {
77 // wait for healthy cluster
78 while (count<attempts) {
79 def health = runCephCommand(master, ADMIN_HOST, 'ceph health')['return'][0].values()[0]
80 if (health.contains('HEALTH_OK')) {
81 common.infoMsg('Cluster is healthy')
82 break;
83 }
84 count++
85 sleep(10)
86 }
87}
Jakub Josefa63f9862018-01-11 17:58:38 +010088timeout(time: 12, unit: 'HOURS') {
89 node("python") {
Jiri Broulik96c867a2017-11-07 16:14:10 +010090
Jakub Josefa63f9862018-01-11 17:58:38 +010091 // create connection to salt master
92 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020093
Jakub Josefa63f9862018-01-11 17:58:38 +010094 if (flags.size() > 0) {
95 stage('Set cluster flags') {
96 for (flag in flags) {
97 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd set ' + flag)
98 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020099 }
100 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200101
Jakub Josefa63f9862018-01-11 17:58:38 +0100102 def osd_ids = []
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200103
Jakub Josefa63f9862018-01-11 17:58:38 +0100104 // get list of osd disks of the host
105 salt.runSaltProcessStep(pepperEnv, HOST, 'saltutil.sync_grains', [], null, true, 5)
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100106 def cephGrain = salt.getGrain(pepperEnv, HOST, 'ceph')
107
Jakub Josefed670ca2018-01-18 14:22:20 +0100108 if(cephGrain['return'].isEmpty()){
109 throw new Exception("Ceph salt grain cannot be found!")
110 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100111 common.print(cephGrain)
Jakub Josefed670ca2018-01-18 14:22:20 +0100112 def ceph_disks = cephGrain['return'][0].values()[0].values()[0]['ceph_disk']
Jakub Josefa63f9862018-01-11 17:58:38 +0100113 common.prettyPrint(ceph_disks)
Jiri Broulikadc7ecd2017-10-18 06:59:27 +0200114
Jakub Josefa63f9862018-01-11 17:58:38 +0100115 for (i in ceph_disks) {
116 def osd_id = i.getKey().toString()
117 if (osd_id in osds || OSD == '*') {
118 osd_ids.add('osd.' + osd_id)
119 print("Will delete " + osd_id)
120 } else {
121 print("Skipping " + osd_id)
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100122 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100123 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100124
125 // wait for healthy cluster
Jakub Josefed670ca2018-01-18 14:22:20 +0100126 if (WAIT_FOR_HEALTHY.toBoolean()) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100127 waitForHealthy(pepperEnv)
128 }
129
130 // `ceph osd out <id> <id>`
131 stage('Set OSDs out') {
132 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd out ' + osd_ids.join(' '))
133 }
134
135 // wait for healthy cluster
Jakub Josefed670ca2018-01-18 14:22:20 +0100136 if (WAIT_FOR_HEALTHY.toBoolean()) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100137 sleep(5)
138 waitForHealthy(pepperEnv)
139 }
140
141 // stop osd daemons
142 stage('Stop OSD daemons') {
143 for (i in osd_ids) {
144 salt.runSaltProcessStep(pepperEnv, HOST, 'service.stop', ['ceph-osd@' + i.replaceAll('osd.', '')], null, true)
145 }
146 }
147
148 // `ceph osd crush remove osd.2`
149 stage('Remove OSDs from CRUSH') {
150 for (i in osd_ids) {
151 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd crush remove ' + i)
152 }
153 }
154
155 // remove keyring `ceph auth del osd.3`
156 stage('Remove OSD keyrings from auth') {
157 for (i in osd_ids) {
158 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph auth del ' + i)
159 }
160 }
161
162 // remove osd `ceph osd rm osd.3`
163 stage('Remove OSDs') {
164 for (i in osd_ids) {
165 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd rm ' + i)
166 }
167 }
168
169 for (osd_id in osd_ids) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100170 id = osd_id.replaceAll('osd.', '')
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100171 /*
172
Jakub Josefa63f9862018-01-11 17:58:38 +0100173 def dmcrypt = ""
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100174 try {
Jakub Josefa63f9862018-01-11 17:58:38 +0100175 dmcrypt = runCephCommand(pepperEnv, HOST, "ls -la /var/lib/ceph/osd/ceph-${id}/ | grep dmcrypt")['return'][0].values()[0]
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100176 } catch (Exception e) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100177 common.warningMsg(e)
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100178 }
179
Jakub Josefa63f9862018-01-11 17:58:38 +0100180 if (dmcrypt?.trim()) {
181 mount = runCephCommand(pepperEnv, HOST, "lsblk -rp | grep /var/lib/ceph/osd/ceph-${id} -B1")['return'][0].values()[0]
182 dev = mount.split()[0].replaceAll("[0-9]","")
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100183
Jakub Josefa63f9862018-01-11 17:58:38 +0100184 // remove partition tables
185 stage("dd part table on ${dev}") {
186 runCephCommand(pepperEnv, HOST, "dd if=/dev/zero of=${dev} bs=512 count=1 conv=notrunc")
187 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100188
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100189 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100190 */
191
Jakub Josefa63f9862018-01-11 17:58:38 +0100192 // remove journal, block_db, block_wal partition `parted /dev/sdj rm 3`
193 stage('Remove journal / block_db / block_wal partition') {
194 def partition_uuid = ""
195 def journal_partition_uuid = ""
196 def block_db_partition_uuid = ""
197 def block_wal_partition_uuid = ""
198 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100199 journal_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/journal_uuid")['return'][0].values()[0].split("\n")[0]
Jakub Josefa63f9862018-01-11 17:58:38 +0100200 } catch (Exception e) {
201 common.infoMsg(e)
202 }
203 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100204 block_db_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block.db_uuid")['return'][0].values()[0].split("\n")[0]
Jakub Josefa63f9862018-01-11 17:58:38 +0100205 } catch (Exception e) {
206 common.infoMsg(e)
207 }
208
209 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100210 block_wal_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block.wal_uuid")['return'][0].values()[0].split("\n")[0]
Jakub Josefa63f9862018-01-11 17:58:38 +0100211 } catch (Exception e) {
212 common.infoMsg(e)
213 }
214
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100215 // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
Jakub Josefa63f9862018-01-11 17:58:38 +0100216 if (journal_partition_uuid?.trim()) {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100217 removePartition(pepperEnv, HOST, journal_partition_uuid)
Jakub Josefa63f9862018-01-11 17:58:38 +0100218 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100219 if (block_db_partition_uuid?.trim()) {
220 removePartition(pepperEnv, HOST, block_db_partition_uuid)
Jakub Josefa63f9862018-01-11 17:58:38 +0100221 }
222 if (block_wal_partition_uuid?.trim()) {
223 removePartition(pepperEnv, HOST, block_wal_partition_uuid)
224 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100225
226 try {
227 runCephCommand(pepperEnv, HOST, "partprobe")
228 } catch (Exception e) {
229 common.warningMsg(e)
230 }
231 }
232
233 // remove data / block / lockbox partition `parted /dev/sdj rm 3`
234 stage('Remove data / block / lockbox partition') {
235 def data_partition_uuid = ""
236 def block_partition_uuid = ""
237 def lockbox_partition_uuid = ""
238 try {
239 data_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/fsid")['return'][0].values()[0].split("\n")[0]
240 common.print(data_partition_uuid)
241 } catch (Exception e) {
242 common.infoMsg(e)
243 }
244 try {
245 block_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block_uuid")['return'][0].values()[0].split("\n")[0]
246 } catch (Exception e) {
247 common.infoMsg(e)
248 }
249
250 try {
251 lockbox_partition_uuid = data_partition_uuid
252 } catch (Exception e) {
253 common.infoMsg(e)
254 }
255
256 // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
257 if (block_partition_uuid?.trim()) {
258 removePartition(pepperEnv, HOST, block_partition_uuid)
259 }
260 if (data_partition_uuid?.trim()) {
261 removePartition(pepperEnv, HOST, data_partition_uuid, 'data', id)
262 }
263 if (lockbox_partition_uuid?.trim()) {
264 removePartition(pepperEnv, HOST, lockbox_partition_uuid, 'lockbox')
265 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100266 }
267 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100268 // remove cluster flags
269 if (flags.size() > 0) {
270 stage('Unset cluster flags') {
271 for (flag in flags) {
272 common.infoMsg('Removing flag ' + flag)
273 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd unset ' + flag)
274 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200275 }
276 }
277 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200278}