blob: b89f3f20e5ee14e27ad3165d6eed07d063854b83 [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
Mateusz Los63811962019-03-28 14:12:23 +0100122 // if (WAIT_FOR_HEALTHY.toBoolean()) {
123 // waitForHealthy(pepperEnv)
124 // }
125
126 if ( osd_ids == [] )
127 {
128 currentBuild.result = 'SUCCESS'
129 return
Jakub Josefa63f9862018-01-11 17:58:38 +0100130 }
131
132 // `ceph osd out <id> <id>`
133 stage('Set OSDs out') {
134 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd out ' + osd_ids.join(' '))
135 }
136
137 // wait for healthy cluster
Jakub Josefed670ca2018-01-18 14:22:20 +0100138 if (WAIT_FOR_HEALTHY.toBoolean()) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100139 sleep(5)
140 waitForHealthy(pepperEnv)
141 }
142
143 // stop osd daemons
144 stage('Stop OSD daemons') {
145 for (i in osd_ids) {
146 salt.runSaltProcessStep(pepperEnv, HOST, 'service.stop', ['ceph-osd@' + i.replaceAll('osd.', '')], null, true)
147 }
148 }
149
150 // `ceph osd crush remove osd.2`
151 stage('Remove OSDs from CRUSH') {
152 for (i in osd_ids) {
153 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd crush remove ' + i)
154 }
155 }
156
157 // remove keyring `ceph auth del osd.3`
158 stage('Remove OSD keyrings from auth') {
159 for (i in osd_ids) {
160 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph auth del ' + i)
161 }
162 }
163
164 // remove osd `ceph osd rm osd.3`
165 stage('Remove OSDs') {
166 for (i in osd_ids) {
167 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd rm ' + i)
168 }
169 }
170
171 for (osd_id in osd_ids) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100172 id = osd_id.replaceAll('osd.', '')
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100173 /*
174
Jakub Josefa63f9862018-01-11 17:58:38 +0100175 def dmcrypt = ""
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100176 try {
Jakub Josefa63f9862018-01-11 17:58:38 +0100177 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 +0100178 } catch (Exception e) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100179 common.warningMsg(e)
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100180 }
181
Jakub Josefa63f9862018-01-11 17:58:38 +0100182 if (dmcrypt?.trim()) {
183 mount = runCephCommand(pepperEnv, HOST, "lsblk -rp | grep /var/lib/ceph/osd/ceph-${id} -B1")['return'][0].values()[0]
184 dev = mount.split()[0].replaceAll("[0-9]","")
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100185
Jakub Josefa63f9862018-01-11 17:58:38 +0100186 // remove partition tables
187 stage("dd part table on ${dev}") {
188 runCephCommand(pepperEnv, HOST, "dd if=/dev/zero of=${dev} bs=512 count=1 conv=notrunc")
189 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100190
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100191 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100192 */
193
Jakub Josefa63f9862018-01-11 17:58:38 +0100194 // remove journal, block_db, block_wal partition `parted /dev/sdj rm 3`
195 stage('Remove journal / block_db / block_wal partition') {
196 def partition_uuid = ""
197 def journal_partition_uuid = ""
198 def block_db_partition_uuid = ""
199 def block_wal_partition_uuid = ""
200 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100201 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 +0100202 } catch (Exception e) {
203 common.infoMsg(e)
204 }
205 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100206 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 +0100207 } catch (Exception e) {
208 common.infoMsg(e)
209 }
210
211 try {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100212 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 +0100213 } catch (Exception e) {
214 common.infoMsg(e)
215 }
216
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100217 // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
Jakub Josefa63f9862018-01-11 17:58:38 +0100218 if (journal_partition_uuid?.trim()) {
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100219 removePartition(pepperEnv, HOST, journal_partition_uuid)
Jakub Josefa63f9862018-01-11 17:58:38 +0100220 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100221 if (block_db_partition_uuid?.trim()) {
222 removePartition(pepperEnv, HOST, block_db_partition_uuid)
Jakub Josefa63f9862018-01-11 17:58:38 +0100223 }
224 if (block_wal_partition_uuid?.trim()) {
225 removePartition(pepperEnv, HOST, block_wal_partition_uuid)
226 }
Jiri Broulika5bc8f62018-01-31 15:04:40 +0100227
228 try {
229 runCephCommand(pepperEnv, HOST, "partprobe")
230 } catch (Exception e) {
231 common.warningMsg(e)
232 }
233 }
234
235 // remove data / block / lockbox partition `parted /dev/sdj rm 3`
236 stage('Remove data / block / lockbox partition') {
237 def data_partition_uuid = ""
238 def block_partition_uuid = ""
239 def lockbox_partition_uuid = ""
240 try {
241 data_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/fsid")['return'][0].values()[0].split("\n")[0]
242 common.print(data_partition_uuid)
243 } catch (Exception e) {
244 common.infoMsg(e)
245 }
246 try {
247 block_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block_uuid")['return'][0].values()[0].split("\n")[0]
248 } catch (Exception e) {
249 common.infoMsg(e)
250 }
251
252 try {
253 lockbox_partition_uuid = data_partition_uuid
254 } catch (Exception e) {
255 common.infoMsg(e)
256 }
257
258 // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
259 if (block_partition_uuid?.trim()) {
260 removePartition(pepperEnv, HOST, block_partition_uuid)
261 }
262 if (data_partition_uuid?.trim()) {
263 removePartition(pepperEnv, HOST, data_partition_uuid, 'data', id)
264 }
265 if (lockbox_partition_uuid?.trim()) {
266 removePartition(pepperEnv, HOST, lockbox_partition_uuid, 'lockbox')
267 }
Jiri Broulikeb7b82f2017-11-30 13:55:40 +0100268 }
269 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100270 // remove cluster flags
271 if (flags.size() > 0) {
272 stage('Unset cluster flags') {
273 for (flag in flags) {
274 common.infoMsg('Removing flag ' + flag)
275 runCephCommand(pepperEnv, ADMIN_HOST, 'ceph osd unset ' + flag)
276 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200277 }
278 }
279 }
Tomáš Kukrálf72096d2017-08-11 12:58:03 +0200280}