blob: 169bbd06e2f4e2f4e82e48f73d623fc2515e6e16 [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()) {
59 // dev = /dev/sdi
60 def dev = partition.replaceAll('\\d+$', "")
61 // part_id = 2
Jiri Broulika5bc8f62018-01-31 15:04:40 +010062 def part_id = partition.substring(partition.lastIndexOf("/")+1).replaceAll("[^0-9]+", "")
63 runCephCommand(master, target, "Ignore | parted ${dev} rm ${part_id}")
Jiri Broulikeb7b82f2017-11-30 13:55:40 +010064 }
65 return
66}
67
68def runCephCommand(master, target, cmd) {
69 return salt.cmdRun(master, target, cmd)
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020070}
71
Jiri Broulik96c867a2017-11-07 16:14:10 +010072def waitForHealthy(master, count=0, attempts=300) {
73 // wait for healthy cluster
74 while (count<attempts) {
75 def health = runCephCommand(master, ADMIN_HOST, 'ceph health')['return'][0].values()[0]
76 if (health.contains('HEALTH_OK')) {
77 common.infoMsg('Cluster is healthy')
78 break;
79 }
80 count++
81 sleep(10)
82 }
83}
Jakub Josefa63f9862018-01-11 17:58:38 +010084timeout(time: 12, unit: 'HOURS') {
85 node("python") {
Jiri Broulik96c867a2017-11-07 16:14:10 +010086
Jakub Josefa63f9862018-01-11 17:58:38 +010087 // create connection to salt master
88 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020089
Jakub Josefa63f9862018-01-11 17:58:38 +010090 if (flags.size() > 0) {
91 stage('Set cluster flags') {
92 for (flag in flags) {
93 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd set ' + flag)
94 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020095 }
96 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020097
Jakub Josefa63f9862018-01-11 17:58:38 +010098 def osd_ids = []
Tomáš Kukrálf72096d2017-08-11 12:58:03 +020099
Jakub Josefa63f9862018-01-11 17:58:38 +0100100 // get list of osd disks of the host
101 salt.runSaltProcessStep(pepperEnv, HOST, 'saltutil.sync_grains', [], null, true, 5)
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100102 def cephGrain = salt.getGrain(pepperEnv, HOST, 'ceph')
103
Jakub Josefed670ca2018-01-18 14:22:20 +0100104 if(cephGrain['return'].isEmpty()){
105 throw new Exception("Ceph salt grain cannot be found!")
106 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100107 common.print(cephGrain)
Jakub Josefed670ca2018-01-18 14:22:20 +0100108 def ceph_disks = cephGrain['return'][0].values()[0].values()[0]['ceph_disk']
Jakub Josefa63f9862018-01-11 17:58:38 +0100109 common.prettyPrint(ceph_disks)
Jiri Broulikadc7ecd2017-10-18 06:59:27 +0200110
Jakub Josefa63f9862018-01-11 17:58:38 +0100111 for (i in ceph_disks) {
112 def osd_id = i.getKey().toString()
113 if (osd_id in osds || OSD == '*') {
114 osd_ids.add('osd.' + osd_id)
115 print("Will delete " + osd_id)
116 } else {
117 print("Skipping " + osd_id)
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100118 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100119 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100120
121 // wait for healthy cluster
Jakub Josefed670ca2018-01-18 14:22:20 +0100122 if (WAIT_FOR_HEALTHY.toBoolean()) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100123 waitForHealthy(pepperEnv)
124 }
125
126 // `ceph osd out <id> <id>`
127 stage('Set OSDs out') {
128 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd out ' + osd_ids.join(' '))
129 }
130
131 // wait for healthy cluster
Jakub Josefed670ca2018-01-18 14:22:20 +0100132 if (WAIT_FOR_HEALTHY.toBoolean()) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100133 sleep(5)
134 waitForHealthy(pepperEnv)
135 }
136
137 // stop osd daemons
138 stage('Stop OSD daemons') {
139 for (i in osd_ids) {
140 salt.runSaltProcessStep(pepperEnv, HOST, 'service.stop', ['ceph-osd@' + i.replaceAll('osd.', '')], null, true)
141 }
142 }
143
144 // `ceph osd crush remove osd.2`
145 stage('Remove OSDs from CRUSH') {
146 for (i in osd_ids) {
147 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd crush remove ' + i)
148 }
149 }
150
151 // remove keyring `ceph auth del osd.3`
152 stage('Remove OSD keyrings from auth') {
153 for (i in osd_ids) {
154 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph auth del ' + i)
155 }
156 }
157
158 // remove osd `ceph osd rm osd.3`
159 stage('Remove OSDs') {
160 for (i in osd_ids) {
161 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd rm ' + i)
162 }
163 }
164
165 for (osd_id in osd_ids) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100166 id = osd_id.replaceAll('osd.', '')
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100167 /*
168
Jakub Josefa63f9862018-01-11 17:58:38 +0100169 def dmcrypt = ""
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100170 try {
Jakub Josefa63f9862018-01-11 17:58:38 +0100171 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 +0100172 } catch (Exception e) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100173 common.warningMsg(e)
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100174 }
175
Jakub Josefa63f9862018-01-11 17:58:38 +0100176 if (dmcrypt?.trim()) {
177 mount = runCephCommand(pepperEnv, HOST, "lsblk -rp | grep /var/lib/ceph/osd/ceph-${id} -B1")['return'][0].values()[0]
178 dev = mount.split()[0].replaceAll("[0-9]","")
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100179
Jakub Josefa63f9862018-01-11 17:58:38 +0100180 // remove partition tables
181 stage("dd part table on ${dev}") {
182 runCephCommand(pepperEnv, HOST, "dd if=/dev/zero of=${dev} bs=512 count=1 conv=notrunc")
183 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100184
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100185 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100186 */
187
Jakub Josefa63f9862018-01-11 17:58:38 +0100188 // remove journal, block_db, block_wal partition `parted /dev/sdj rm 3`
189 stage('Remove journal / block_db / block_wal partition') {
190 def partition_uuid = ""
191 def journal_partition_uuid = ""
192 def block_db_partition_uuid = ""
193 def block_wal_partition_uuid = ""
194 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100195 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 +0100196 } catch (Exception e) {
197 common.infoMsg(e)
198 }
199 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100200 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 +0100201 } catch (Exception e) {
202 common.infoMsg(e)
203 }
204
205 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100206 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 +0100207 } catch (Exception e) {
208 common.infoMsg(e)
209 }
210
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100211 // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
Jakub Josefa63f9862018-01-11 17:58:38 +0100212 if (journal_partition_uuid?.trim()) {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100213 removePartition(pepperEnv, HOST, journal_partition_uuid)
Jakub Josefa63f9862018-01-11 17:58:38 +0100214 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100215 if (block_db_partition_uuid?.trim()) {
216 removePartition(pepperEnv, HOST, block_db_partition_uuid)
Jakub Josefa63f9862018-01-11 17:58:38 +0100217 }
218 if (block_wal_partition_uuid?.trim()) {
219 removePartition(pepperEnv, HOST, block_wal_partition_uuid)
220 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100221
222 try {
223 runCephCommand(pepperEnv, HOST, "partprobe")
224 } catch (Exception e) {
225 common.warningMsg(e)
226 }
227 }
228
229 // remove data / block / lockbox partition `parted /dev/sdj rm 3`
230 stage('Remove data / block / lockbox partition') {
231 def data_partition_uuid = ""
232 def block_partition_uuid = ""
233 def lockbox_partition_uuid = ""
234 try {
235 data_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/fsid")['return'][0].values()[0].split("\n")[0]
236 common.print(data_partition_uuid)
237 } catch (Exception e) {
238 common.infoMsg(e)
239 }
240 try {
241 block_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block_uuid")['return'][0].values()[0].split("\n")[0]
242 } catch (Exception e) {
243 common.infoMsg(e)
244 }
245
246 try {
247 lockbox_partition_uuid = data_partition_uuid
248 } catch (Exception e) {
249 common.infoMsg(e)
250 }
251
252 // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
253 if (block_partition_uuid?.trim()) {
254 removePartition(pepperEnv, HOST, block_partition_uuid)
255 }
256 if (data_partition_uuid?.trim()) {
257 removePartition(pepperEnv, HOST, data_partition_uuid, 'data', id)
258 }
259 if (lockbox_partition_uuid?.trim()) {
260 removePartition(pepperEnv, HOST, lockbox_partition_uuid, 'lockbox')
261 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100262 }
263 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100264 // remove cluster flags
265 if (flags.size() > 0) {
266 stage('Unset cluster flags') {
267 for (flag in flags) {
268 common.infoMsg('Removing flag ' + flag)
269 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd unset ' + flag)
270 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200271 }
272 }
273 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200274}