1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-01 08:21:15 +03:00

Merge pull request #7077 from ryanpetrello/fix-7040

wrap instance and queue registration in postgres advisory locks
This commit is contained in:
Ryan Petrello 2017-07-14 15:05:14 -04:00 committed by GitHub
commit cb929ea4d8
4 changed files with 88 additions and 67 deletions

View File

@ -1,10 +1,14 @@
# Copyright (c) 2016 Ansible, Inc.
# All Rights Reserved
import subprocess
from django.core.management.base import BaseCommand, CommandError
from optparse import make_option
import subprocess
from django.db import transaction
from django.core.management.base import BaseCommand, CommandError
from awx.main.models import Instance
from awx.main.utils.pglock import advisory_lock
class Command(BaseCommand):
@ -17,19 +21,22 @@ class Command(BaseCommand):
help='Hostname used during provisioning'),
)
@transaction.atomic
def handle(self, *args, **options):
if not options.get('name'):
hostname = options.get('name')
if not hostname:
raise CommandError("--name is a required argument")
instance = Instance.objects.filter(hostname=options.get('name'))
if instance.exists():
instance.delete()
print("Instance Removed")
result = subprocess.Popen("rabbitmqctl forget_cluster_node rabbitmq@{}".format(options.get('name')), shell=True).wait()
if result != 0:
print("Node deprovisioning may have failed when attempting to remove the RabbitMQ instance from the cluster")
with advisory_lock('instance_registration_%s' % hostname):
instance = Instance.objects.filter(hostname=hostname)
if instance.exists():
instance.delete()
print("Instance Removed")
result = subprocess.Popen("rabbitmqctl forget_cluster_node rabbitmq@{}".format(hostname), shell=True).wait()
if result != 0:
print("Node deprovisioning may have failed when attempting to remove the RabbitMQ instance from the cluster")
else:
print('Successfully deprovisioned {}'.format(hostname))
print('(changed: True)')
else:
print('Successfully deprovisioned {}'.format(options.get('name')))
print('(changed: True)')
else:
print('No instance found matching name {}'.format(options.get('name')))
print('No instance found matching name {}'.format(hostname))

View File

@ -2,9 +2,11 @@
# All Rights Reserved
from awx.main.models import Instance
from awx.main.utils.pglock import advisory_lock
from django.conf import settings
from optparse import make_option
from django.db import transaction
from django.core.management.base import BaseCommand
@ -25,15 +27,17 @@ class Command(BaseCommand):
def _register_hostname(self, hostname):
if not hostname:
return
instance = Instance.objects.filter(hostname=hostname)
if instance.exists():
print("Instance already registered {}".format(instance[0]))
return
instance = Instance(uuid=self.uuid, hostname=hostname)
instance.save()
with advisory_lock('instance_registration_%s' % hostname):
instance = Instance.objects.filter(hostname=hostname)
if instance.exists():
print("Instance already registered {}".format(instance[0]))
return
instance = Instance(uuid=self.uuid, hostname=hostname)
instance.save()
print('Successfully registered instance {}'.format(hostname))
self.changed = True
@transaction.atomic
def handle(self, **options):
self.uuid = settings.SYSTEM_UUID
self.changed = False

View File

@ -2,9 +2,11 @@
# All Rights Reserved.
import sys
from awx.main.utils.pglock import advisory_lock
from awx.main.models import Instance, InstanceGroup
from optparse import make_option
from django.db import transaction
from django.core.management.base import BaseCommand, CommandError
@ -19,45 +21,48 @@ class Command(BaseCommand):
help='The controlling group (makes this an isolated group)'),
)
@transaction.atomic
def handle(self, **options):
if not options.get('queuename'):
queuename = options.get('queuename')
if not queuename:
raise CommandError("Specify `--queuename` to use this command.")
changed = False
ig = InstanceGroup.objects.filter(name=options.get('queuename'))
control_ig = None
if options.get('controller'):
control_ig = InstanceGroup.objects.filter(name=options.get('controller')).first()
if ig.exists():
print("Instance Group already registered {}".format(ig[0].name))
ig = ig[0]
if control_ig and ig.controller_id != control_ig.pk:
ig.controller = control_ig
ig.save()
print("Set controller group {} on {}.".format(control_ig.name, ig.name))
changed = True
else:
print("Creating instance group {}".format(options.get('queuename')))
ig = InstanceGroup(name=options.get('queuename'))
if control_ig:
ig.controller = control_ig
ig.save()
changed = True
hostname_list = []
if options.get('hostnames'):
hostname_list = options.get('hostnames').split(",")
instance_list = [x.strip() for x in hostname_list if x]
for inst_name in instance_list:
instance = Instance.objects.filter(hostname=inst_name)
if instance.exists() and instance[0] not in ig.instances.all():
ig.instances.add(instance[0])
print("Added instance {} to {}".format(instance[0].hostname, ig.name))
changed = True
elif not instance.exists():
print("Instance does not exist: {}".format(inst_name))
if changed:
print('(changed: True)')
sys.exit(1)
with advisory_lock('instance_group_registration_%s' % queuename):
ig = InstanceGroup.objects.filter(name=queuename)
control_ig = None
if options.get('controller'):
control_ig = InstanceGroup.objects.filter(name=options.get('controller')).first()
if ig.exists():
print("Instance Group already registered {}".format(ig[0].name))
ig = ig[0]
if control_ig and ig.controller_id != control_ig.pk:
ig.controller = control_ig
ig.save()
print("Set controller group {} on {}.".format(control_ig.name, ig.name))
changed = True
else:
print("Instance already registered {}".format(instance[0].hostname))
if changed:
print('(changed: True)')
print("Creating instance group {}".format(queuename))
ig = InstanceGroup(name=queuename)
if control_ig:
ig.controller = control_ig
ig.save()
changed = True
hostname_list = []
if options.get('hostnames'):
hostname_list = options.get('hostnames').split(",")
instance_list = [x.strip() for x in hostname_list if x]
for inst_name in instance_list:
instance = Instance.objects.filter(hostname=inst_name)
if instance.exists() and instance[0] not in ig.instances.all():
ig.instances.add(instance[0])
print("Added instance {} to {}".format(instance[0].hostname, ig.name))
changed = True
elif not instance.exists():
print("Instance does not exist: {}".format(inst_name))
if changed:
print('(changed: True)')
sys.exit(1)
else:
print("Instance already registered {}".format(instance[0].hostname))
if changed:
print('(changed: True)')

View File

@ -2,9 +2,11 @@
# All Rights Reserved.
import sys
from awx.main.utils.pglock import advisory_lock
from awx.main.models import InstanceGroup
from optparse import make_option
from django.db import transaction
from django.core.management.base import BaseCommand, CommandError
@ -20,14 +22,17 @@ class Command(BaseCommand):
help='Queue to create/update'),
)
@transaction.atomic
def handle(self, **options):
if not options.get('queuename'):
queuename = options.get('queuename')
if not queuename:
raise CommandError('Must specify `--queuename` in order to use command.')
ig = InstanceGroup.objects.filter(name=options.get('queuename'))
if not ig.exists():
print("Instance group doesn't exist")
sys.exit(1)
ig = ig.first()
ig.delete()
print("Instance Group Removed")
print('(changed: True)')
with advisory_lock('instance_group_registration_%s' % queuename):
ig = InstanceGroup.objects.filter(name=queuename)
if not ig.exists():
print("Instance group doesn't exist")
sys.exit(1)
ig = ig.first()
ig.delete()
print("Instance Group Removed")
print('(changed: True)')