Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Downstream fixes #10532

Merged
merged 43 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0be68fe
reduce duplicate network request in JT form
keithjgrant Jun 18, 2021
55b5060
remove duplicate JT credential fetch
keithjgrant Jun 18, 2021
9316ace
delete commented line
keithjgrant Jun 18, 2021
88d4923
Link users to workflow approval details from workflow node
mabashian Jun 21, 2021
cd83030
Rename sosreport plugin
wenottingham Jun 21, 2021
8246d4a
Remove smart inventories from host form inv lookup
mabashian Jun 21, 2021
f0a6567
Hide host_filter search key when hiding smart inventories
mabashian Jun 22, 2021
487d78c
Don't reload template when navigating to edit form
keithjgrant Jun 21, 2021
77b0b9a
Disable edit fields for managed EE, except pull
nixocio Jun 22, 2021
f08bf47
Add read-only settings for IS_K8S
jakemcdermott Jun 22, 2021
4cc734c
Enable instance group creation for non-k8s deployments only
jakemcdermott Jun 22, 2021
4de4776
Update help text for hashivault credential plugin
jakemcdermott Jun 22, 2021
673f722
Update inventory list filters
nixocio Jun 22, 2021
9fddf7c
Add draggable selected list to galaxy credential lookup
marshmalien Jun 22, 2021
f06490a
Fix disparity of dev server and prod build
nixocio Jun 22, 2021
d3c5397
Add link to project update job details on job details page.
kialam Jun 23, 2021
28a62ea
properly validates credential password fields
AlexSCorey Jun 23, 2021
0f25720
Update minikube docs
shanemcd Jun 23, 2021
dc327ce
Autofix problematic dependencies
jakemcdermott Jun 23, 2021
1211faf
Only derive row count from max counter when job is running.
jakemcdermott Jun 22, 2021
0d7ef70
Prevent jobs from trying to run on controlplane in k8s
shanemcd Jun 23, 2021
b985442
Rename draggable prop and fix typos
marshmalien Jun 23, 2021
5ffffeb
Attempt to check/wait for migrations 30x (~12 min)
rooftopcellist Jun 23, 2021
d0b7d97
Create partition for 2 job types that bypass TM (#5138)
AlanCoding Jun 23, 2021
057bd6e
Remove plus button job output
nixocio Jun 23, 2021
2fa2700
Prevent inventory updates started via projects from running on contro…
shanemcd Jun 23, 2021
1ba51c0
Fix unit tests
shanemcd Jun 23, 2021
1e750cf
Add datalist test selectors
marshmalien Jun 23, 2021
69388ed
fix lint
tiagodread Jun 23, 2021
03fb12d
Force system jobs to always run on control plane
shanemcd Jun 24, 2021
3be29d5
Bump ansible-runner to 2.0.0.0rc2 and receptorctl to 1.0.0.0rc1
jbradberry Jun 24, 2021
3979085
Disable activity stream for updates in status handler
shanemcd Jun 24, 2021
8dc788d
clean up responsive behavior of advanced search
keithjgrant Jun 24, 2021
390e1f9
Fix obvious logical bug with project folder pre-creation (#5155)
AlanCoding Jun 24, 2021
f1273d5
Show tracebacks from dependency failures (#5154)
AlanCoding Jun 24, 2021
162ea77
Add order selected list to instance group lookups
marshmalien Jun 24, 2021
f541fe9
Add comment to explain why we resolve the promises sequentially
marshmalien Jun 24, 2021
04839a0
prevent delete of instance groups list item controlplan and default
AlexSCorey Jun 10, 2021
9992bf0
resolves crashing details view
AlexSCorey Jun 11, 2021
d5deedc
Make sure that validation of managed EEs makes sense
jbradberry Jun 24, 2021
1ed170f
Dont overwrite result_traceback if it was already set.
shanemcd Jun 25, 2021
40f5ff3
Bump ansible-runner to 2.0.0.0rc3
jbradberry Jun 25, 2021
f126a63
Fix bug setting execution_node to null (not blank) (#5169)
AlanCoding Jun 28, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion awx/api/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,8 +710,12 @@ def update(self, request, *args, **kwargs):
fields_to_check = ['name', 'description', 'organization', 'image', 'credential']
if instance.managed and request.user.can_access(models.ExecutionEnvironment, 'change', instance):
for field in fields_to_check:
if kwargs.get('partial') and field not in request.data:
continue
left = getattr(instance, field, None)
right = request.data.get(field, None)
if hasattr(left, 'id'):
left = left.id
right = request.data.get(field)
if left != right:
raise PermissionDenied(_("Only the 'pull' field can be edited for managed execution environments."))
return super().update(request, *args, **kwargs)
Expand Down
9 changes: 9 additions & 0 deletions awx/main/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,15 @@
unit=_('seconds'),
)

register(
'IS_K8S',
field_class=fields.BooleanField,
read_only=True,
category=_('System'),
category_slug='system',
help_text=_('Indicates whether the instance is part of a kubernetes-based deployment.'),
)


def logging_validate(serializer, attrs):
if not serializer.instance or not hasattr(serializer.instance, 'LOG_AGGREGATOR_HOST') or not hasattr(serializer.instance, 'LOG_AGGREGATOR_TYPE'):
Expand Down
10 changes: 9 additions & 1 deletion awx/main/credential_plugins/hashivault.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@
'id': 'secret_path',
'label': _('Path to Secret'),
'type': 'string',
'help_text': _('The path to the secret stored in the secret backend e.g, /some/secret/'),
'help_text': _(
(
'The path to the secret stored in the secret backend e.g, /some/secret/. It is recommended'
' that you use the secret backend field to identify the storage backend and to use this field'
' for locating a specific secret within that store. However, if you prefer to fully identify'
' both the secret backend and one of its secrets using only this field, join their locations'
' into a single path without any additional separators, e.g, /location/of/backend/some/secret.'
)
),
},
{
'id': 'auth_path',
Expand Down
2 changes: 1 addition & 1 deletion awx/main/models/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ def task_impact(self):

@property
def preferred_instance_groups(self):
return self.global_instance_groups
return self.control_plane_instance_group

'''
JobNotificationMixin
Expand Down
7 changes: 6 additions & 1 deletion awx/main/models/unified_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1437,7 +1437,12 @@ def control_plane_instance_group(self):
def global_instance_groups(self):
from awx.main.models.ha import InstanceGroup

default_instance_groups = InstanceGroup.objects.filter(name__in=[settings.DEFAULT_EXECUTION_QUEUE_NAME, settings.DEFAULT_CONTROL_PLANE_QUEUE_NAME])
default_instance_group_names = [settings.DEFAULT_EXECUTION_QUEUE_NAME]

if not settings.IS_K8S:
default_instance_group_names.append(settings.DEFAULT_CONTROL_PLANE_QUEUE_NAME)

default_instance_groups = InstanceGroup.objects.filter(name__in=default_instance_group_names)

return list(default_instance_groups)

Expand Down
31 changes: 24 additions & 7 deletions awx/main/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
from awx.main.queue import CallbackQueueDispatcher
from awx.main.dispatch.publish import task
from awx.main.dispatch import get_local_queuename, reaper
from awx.main.utils import (
from awx.main.utils.common import (
update_scm_url,
ignore_inventory_computed_fields,
ignore_inventory_group_removal,
Expand All @@ -97,6 +97,7 @@
deepmerge,
parse_yaml_or_json,
cleanup_new_process,
create_partition,
)
from awx.main.utils.execution_environments import get_default_pod_spec, CONTAINER_ROOT, to_container_path
from awx.main.utils.ansible import read_ansible_config
Expand Down Expand Up @@ -1267,11 +1268,17 @@ def status_handler(self, status_data, runner_config):
for k, v in self.safe_env.items():
if k in job_env:
job_env[k] = v
self.instance = self.update_model(self.instance.pk, job_args=json.dumps(runner_config.command), job_cwd=runner_config.cwd, job_env=job_env)
from awx.main.signals import disable_activity_stream # Circular import

with disable_activity_stream():
self.instance = self.update_model(self.instance.pk, job_args=json.dumps(runner_config.command), job_cwd=runner_config.cwd, job_env=job_env)
elif status_data['status'] == 'error':
result_traceback = status_data.get('result_traceback', None)
if result_traceback:
self.instance = self.update_model(self.instance.pk, result_traceback=result_traceback)
from awx.main.signals import disable_activity_stream # Circular import

with disable_activity_stream():
self.instance = self.update_model(self.instance.pk, result_traceback=result_traceback)

@with_path_cleanup
def run(self, pk, **kwargs):
Expand Down Expand Up @@ -1791,6 +1798,7 @@ def pre_run_hook(self, job, private_data_dir):
if 'update_' not in sync_metafields['job_tags']:
sync_metafields['scm_revision'] = job_revision
local_project_sync = job.project.create_project_update(_eager_fields=sync_metafields)
create_partition(local_project_sync.event_class._meta.db_table, start=local_project_sync.created)
# save the associated job before calling run() so that a
# cancel() call on the job can cancel the project update
job = self.update_model(job.pk, project_update=local_project_sync)
Expand Down Expand Up @@ -2070,17 +2078,24 @@ def _update_dependent_inventories(self, project_update, dependent_inventory_sour
if InventoryUpdate.objects.filter(inventory_source=inv_src, status__in=ACTIVE_STATES).exists():
logger.debug('Skipping SCM inventory update for `{}` because ' 'another update is already active.'.format(inv_src.name))
continue

if settings.IS_K8S:
instance_group = InventoryUpdate(inventory_source=inv_src).preferred_instance_groups[0]
else:
instance_group = project_update.instance_group

local_inv_update = inv_src.create_inventory_update(
_eager_fields=dict(
launch_type='scm',
status='running',
instance_group=project_update.instance_group,
instance_group=instance_group,
execution_node=project_update.execution_node,
source_project_update=project_update,
celery_task_id=project_update.celery_task_id,
)
)
try:
create_partition(local_inv_update.event_class._meta.db_table, start=local_inv_update.created)
inv_update_class().run(local_inv_update.id)
except Exception:
logger.exception('{} Unhandled exception updating dependent SCM inventory sources.'.format(project_update.log_format))
Expand Down Expand Up @@ -2161,8 +2176,6 @@ def pre_run_hook(self, instance, private_data_dir):
if not os.path.exists(settings.PROJECTS_ROOT):
os.mkdir(settings.PROJECTS_ROOT)
project_path = instance.project.get_project_path(check_if_exists=False)
if not os.path.exists(project_path):
os.makedirs(project_path) # used as container mount

self.acquire_lock(instance)

Expand All @@ -2175,6 +2188,9 @@ def pre_run_hook(self, instance, private_data_dir):
else:
self.original_branch = git_repo.active_branch

if not os.path.exists(project_path):
os.makedirs(project_path) # used as container mount

stage_path = os.path.join(instance.get_cache_path(), 'stage')
if os.path.exists(stage_path):
logger.warning('{0} unexpectedly existed before update'.format(stage_path))
Expand Down Expand Up @@ -2988,7 +3004,8 @@ def _run_internal(self, receptor_ctl):
if state_name == 'Succeeded':
return res

raise RuntimeError(detail)
if self.task.instance.result_traceback is None:
raise RuntimeError(detail)

return res

Expand Down
2 changes: 1 addition & 1 deletion awx/main/tests/factories/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def mk_instance(persisted=True, hostname='instance.example.org'):
return Instance.objects.get_or_create(uuid=settings.SYSTEM_UUID, hostname=hostname)[0]


def mk_instance_group(name='tower', instance=None, minimum=0, percentage=0):
def mk_instance_group(name='default', instance=None, minimum=0, percentage=0):
ig, status = InstanceGroup.objects.get_or_create(name=name, policy_instance_minimum=minimum, policy_instance_percentage=percentage)
if instance is not None:
if type(instance) == list:
Expand Down
26 changes: 14 additions & 12 deletions awx/main/tests/functional/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,19 @@ def test_no_unwanted_dependent_inventory_updates(self, project, scm_revision_fil
task.post_run_hook(proj_update, 'successful')
assert not inv_update_mck.called

def test_dependent_inventory_updates(self, scm_inventory_source):
def test_dependent_inventory_updates(self, scm_inventory_source, default_instance_group):
task = RunProjectUpdate()
scm_inventory_source.scm_last_revision = ''
proj_update = ProjectUpdate.objects.create(project=scm_inventory_source.source_project)
with mock.patch.object(RunInventoryUpdate, 'run') as iu_run_mock:
task._update_dependent_inventories(proj_update, [scm_inventory_source])
assert InventoryUpdate.objects.count() == 1
inv_update = InventoryUpdate.objects.first()
iu_run_mock.assert_called_once_with(inv_update.id)
assert inv_update.source_project_update_id == proj_update.pk
with mock.patch('awx.main.tasks.create_partition'):
task._update_dependent_inventories(proj_update, [scm_inventory_source])
assert InventoryUpdate.objects.count() == 1
inv_update = InventoryUpdate.objects.first()
iu_run_mock.assert_called_once_with(inv_update.id)
assert inv_update.source_project_update_id == proj_update.pk

def test_dependent_inventory_project_cancel(self, project, inventory):
def test_dependent_inventory_project_cancel(self, project, inventory, default_instance_group):
"""
Test that dependent inventory updates exhibit good behavior on cancel
of the source project update
Expand All @@ -63,8 +64,9 @@ def user_cancels_project(pk):
ProjectUpdate.objects.all().update(cancel_flag=True)

with mock.patch.object(RunInventoryUpdate, 'run') as iu_run_mock:
iu_run_mock.side_effect = user_cancels_project
task._update_dependent_inventories(proj_update, [is1, is2])
# Verify that it bails after 1st update, detecting a cancel
assert is2.inventory_updates.count() == 0
iu_run_mock.assert_called_once()
with mock.patch('awx.main.tasks.create_partition'):
iu_run_mock.side_effect = user_cancels_project
task._update_dependent_inventories(proj_update, [is1, is2])
# Verify that it bails after 1st update, detecting a cancel
assert is2.inventory_updates.count() == 0
iu_run_mock.assert_called_once()
1 change: 1 addition & 0 deletions awx/ui_next/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"aria-labelledby",
"aria-hidden",
"aria-controls",
"aria-pressed",
"sortKey",
"ouiaId",
"credentialTypeNamespace",
Expand Down
Loading