forked from batrick/ceph-linode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linode-nuke.py
87 lines (68 loc) · 2.52 KB
/
linode-nuke.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import linode.api as linapi
import logging
import os
import time
from contextlib import closing, contextmanager
from multiprocessing.dummy import Pool as ThreadPool
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s')
with open("LINODE_GROUP") as f:
GROUP = unicode(f.read().strip())
def nuke(client, linode):
changed = False
while True:
jobs = client.linode_job_list(LinodeID = linode[u'LINODEID'], pendingOnly = 1)
jobs = filter(lambda j: not j['HOST_FINISH_DT'], jobs)
if len(jobs) == 0:
break
logging.info("waiting for linode job queue to clear...")
time.sleep(5)
if linode[u'STATUS'] != 2:
client.linode_shutdown(LinodeID = linode[u'LINODEID'])
changed = True
configs = client.linode_config_list(LinodeID = linode[u'LINODEID'])
for config in configs:
client.linode_config_delete(LinodeID = config[u'LinodeID'], ConfigID = config[u'ConfigID'])
changed = True
disks = client.linode_disk_list(LinodeID = linode[u'LINODEID'])
for disk in disks:
client.linode_disk_delete(LinodeID = disk[u'LINODEID'], DiskID = disk[u'DISKID'])
changed = True
return changed
def newcb():
# and this is why local by default is stupid (and Python has a moronic design for closures):
changed = [False]
def cb(result):
changed[0] |= result
def status():
return changed[0]
return (status, cb)
def main():
key = os.getenv("LINODE_API_KEY")
if key is None:
raise RuntimeError("please specify Linode API key")
client = linapi.Api(key = key, batching = False)
while True:
# FIXME only nuke linodes which aren't done, and do one last check at the end
linodes = client.linode_list()
logging.info("%s", linodes)
with closing(ThreadPool(25)) as pool:
status, cb = newcb()
for linode in linodes:
if linode[u'LPM_DISPLAYGROUP'] == GROUP:
pool.apply_async(nuke, (client, linode), {}, cb)
pool.close()
pool.join()
if not status():
return
time.sleep(60)
# clear inventory file or else launch.sh won't create linodes
ansible_inv_file = os.getenv('ANSIBLE_INVENTORY')
if not ansible_inv_file:
ansible_inv_file = 'ansible_inventory'
try:
os.unlink(ansible_inv_file)
except OSError as e:
if e.errno != errno.ENOENT:
raise e
if __name__ == "__main__":
main()