Allow setting default execution group pod spec

This will allow us to control the default container group created via settings, meaning
we could set this in the operator and the default container group would get created with it applied.

We need this for https://github.com/ansible/awx-operator/issues/242

Deepmerge the default podspec and the override

With out this, providing the `spec` for the podspec would override everything
contained, which ends up including the container used, which is not desired

Also, use the same deepmerge function def, as the code seems to be copypasted from
the utils
This commit is contained in:
Elijah DeLee 2021-11-29 14:30:19 -05:00
parent cdf14158b4
commit e10030b73d
5 changed files with 18 additions and 22 deletions

View File

@ -17,13 +17,14 @@ class InstanceNotFound(Exception):
class RegisterQueue:
def __init__(self, queuename, instance_percent, inst_min, hostname_list, is_container_group=None):
def __init__(self, queuename, instance_percent, inst_min, hostname_list, is_container_group=None, pod_spec_override=None):
self.instance_not_found_err = None
self.queuename = queuename
self.instance_percent = instance_percent
self.instance_min = inst_min
self.hostname_list = hostname_list
self.is_container_group = is_container_group
self.pod_spec_override = pod_spec_override
def get_create_update_instance_group(self):
created = False
@ -40,6 +41,10 @@ class RegisterQueue:
ig.is_container_group = self.is_container_group
changed = True
if self.pod_spec_override and (ig.pod_spec_override != self.pod_spec_override):
ig.pod_spec_override = self.pod_spec_override
changed = True
if changed:
ig.save()

View File

@ -179,7 +179,9 @@ class InstanceManager(models.Manager):
else:
registered = self.register(ip_address=pod_ip, uuid=settings.SYSTEM_UUID)
RegisterQueue(settings.DEFAULT_CONTROL_PLANE_QUEUE_NAME, 100, 0, [], is_container_group=False).register()
RegisterQueue(settings.DEFAULT_EXECUTION_QUEUE_NAME, 100, 0, [], is_container_group=True).register()
RegisterQueue(
settings.DEFAULT_EXECUTION_QUEUE_NAME, 100, 0, [], is_container_group=True, pod_spec_override=settings.DEFAULT_EXECUTION_QUEUE_POD_SPEC_OVERRIDE
).register()
return registered
else:
return (False, self.me())

View File

@ -9,29 +9,12 @@ from kubernetes import client, config
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from awx.main.utils.common import parse_yaml_or_json
from awx.main.utils.common import parse_yaml_or_json, deepmerge
from awx.main.utils.execution_environments import get_default_pod_spec
logger = logging.getLogger('awx.main.scheduler')
def deepmerge(a, b):
"""
Merge dict structures and return the result.
>>> a = {'first': {'all_rows': {'pass': 'dog', 'number': '1'}}}
>>> b = {'first': {'all_rows': {'fail': 'cat', 'number': '5'}}}
>>> import pprint; pprint.pprint(deepmerge(a, b))
{'first': {'all_rows': {'fail': 'cat', 'number': '5', 'pass': 'dog'}}}
"""
if isinstance(a, dict) and isinstance(b, dict):
return dict([(k, deepmerge(a.get(k), b.get(k))) for k in set(a.keys()).union(b.keys())])
elif b is None:
return a
else:
return b
class PodManager(object):
def __init__(self, task=None):
self.task = task
@ -183,7 +166,7 @@ class PodManager(object):
pod_spec_override = {}
if self.task and self.task.instance_group.pod_spec_override:
pod_spec_override = parse_yaml_or_json(self.task.instance_group.pod_spec_override)
pod_spec = {**default_pod_spec, **pod_spec_override}
pod_spec = deepmerge(default_pod_spec, pod_spec_override)
if self.task:
pod_spec['metadata'] = deepmerge(

View File

@ -3286,7 +3286,11 @@ class AWXReceptorJob:
pod_spec_override = {}
if self.task and self.task.instance.instance_group.pod_spec_override:
pod_spec_override = parse_yaml_or_json(self.task.instance.instance_group.pod_spec_override)
pod_spec = {**default_pod_spec, **pod_spec_override}
# According to the deepmerge docstring, the second dictionary will override when
# they share keys, which is the desired behavior.
# This allows user to only provide elements they want to override, and for us to still provide any
# defaults they don't want to change
pod_spec = deepmerge(default_pod_spec, pod_spec_override)
pod_spec['spec']['containers'][0]['image'] = ee.image
pod_spec['spec']['containers'][0]['args'] = ['ansible-runner', 'worker', '--private-data-dir=/runner']

View File

@ -986,5 +986,7 @@ DJANGO_GUID = {'GUID_HEADER_NAME': 'X-API-Request-Id'}
# Name of the default task queue
DEFAULT_EXECUTION_QUEUE_NAME = 'default'
# pod spec used when the default execution queue is a container group, e.g. when deploying on k8s/ocp with the operator
DEFAULT_EXECUTION_QUEUE_POD_SPEC_OVERRIDE = ''
# Name of the default controlplane queue
DEFAULT_CONTROL_PLANE_QUEUE_NAME = 'controlplane'