Revision 26515bc1 snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
b/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py | ||
---|---|---|
30 | 30 |
|
31 | 31 |
from django.core.management.base import BaseCommand, CommandError |
32 | 32 |
from synnefo.management.common import get_backend |
33 |
from synnefo.db.models import VirtualMachine, BackendNetwork |
|
33 |
from synnefo.logic import backend as backend_mod |
|
34 |
from synnefo.db.models import Backend |
|
35 |
from django.db import transaction, models |
|
34 | 36 |
|
35 | 37 |
|
36 |
class Command(BaseCommand): |
|
37 |
can_import_settings = True |
|
38 |
HELP_MSG = """\ |
|
39 |
Remove a backend from the Database. Backend should be set to drained before |
|
40 |
trying to remove it, in order to avoid the allocation of a new instances in |
|
41 |
this Backend. Removal of a backend will fail if the backend hosts any |
|
42 |
non-deleted instances.""" |
|
38 | 43 |
|
39 |
help = "Remove a backend from the Database. Backend should be set\n" \ |
|
40 |
"to drained before trying to remove it, in order to avoid the\n" \ |
|
41 |
"allocation of a new instances in this Backend.\n\n" \ |
|
42 |
"Removal of a backend will fail if the backend hosts any\n" \ |
|
43 |
"non-deleted instances." |
|
44 | 44 |
|
45 |
output_transaction = True # The management command runs inside
|
|
46 |
# an SQL transaction
|
|
45 |
class Command(BaseCommand):
|
|
46 |
help = HELP_MSG
|
|
47 | 47 |
|
48 | 48 |
def handle(self, *args, **options): |
49 | 49 |
write = self.stdout.write |
... | ... | |
52 | 52 |
|
53 | 53 |
backend = get_backend(args[0]) |
54 | 54 |
|
55 |
write('Trying to remove backend: %s\n' % backend.clustername) |
|
56 |
|
|
57 |
vms_in_backend = VirtualMachine.objects.filter(backend=backend, |
|
58 |
deleted=False) |
|
55 |
write("Trying to remove backend: %s\n" % backend.clustername) |
|
59 | 56 |
|
60 |
if vms_in_backend:
|
|
57 |
if backend.virtual_machines.filter(deleted=False).exists():
|
|
61 | 58 |
raise CommandError('Backend hosts non-deleted vms. Can not delete') |
62 | 59 |
|
63 |
networks = BackendNetwork.objects.filter(backend=backend,
|
|
64 |
deleted=False)
|
|
65 |
networks = [net.network.backend_id for net in networks]
|
|
60 |
# Get networks before deleting backend, because after deleting the
|
|
61 |
# backend, all BackendNetwork objects are deleted!
|
|
62 |
networks = [bn.network for bn in backend.networks.all()]
|
|
66 | 63 |
|
67 |
backend.delete() |
|
64 |
try: |
|
65 |
delete_backend(backend) |
|
66 |
except models.ProtectedError as e: |
|
67 |
msg = ("Can not delete backend because it contains" |
|
68 |
"non-deleted VMs:\n%s" % e) |
|
69 |
raise CommandError(msg) |
|
68 | 70 |
|
69 |
write('Successfully removed backend.\n') |
|
71 |
write('Successfully removed backend from DB.\n')
|
|
70 | 72 |
|
71 | 73 |
if networks: |
72 |
write('Left the following orphans networks in Ganeti:\n') |
|
73 |
write(' ' + '\n * '.join(networks) + '\n') |
|
74 |
write('Manually remove them.\n') |
|
74 |
write("Clearing networks from %s..\n" % backend.clustername) |
|
75 |
for network in networks: |
|
76 |
backend_mod.delete_network(network=network, backend=backend) |
|
77 |
write("Successfully issued jobs to remove all networks.\n") |
|
78 |
|
|
79 |
|
|
80 |
@transaction.commit_on_success |
|
81 |
def delete_backend(backend): |
|
82 |
# Get X-Lock |
|
83 |
backend = Backend.objects.select_for_update().get(id=backend.id) |
|
84 |
# Clear 'backend' field of 'deleted' VirtualMachines |
|
85 |
backend.virtual_machines.filter(deleted=True).update(backend=None) |
|
86 |
# Delete all BackendNetwork objects of this backend |
|
87 |
backend.networks.all().delete() |
|
88 |
backend.delete() |
Also available in: Unified diff