diff --git a/awx/api/metadata.py b/awx/api/metadata.py index 2d45f27f..f3546cef 100644 --- a/awx/api/metadata.py +++ b/awx/api/metadata.py @@ -153,7 +153,7 @@ def get_field_info(self, field): pass if field.field_name == 'type': field_info['type'] = 'choice' - elif field.field_name in ('url', 'custom_virtualenv', 'token'): + elif field.field_name in ('url', 'token'): field_info['type'] = 'string' elif field.field_name in ('related', 'summary_fields'): field_info['type'] = 'object' diff --git a/awx/api/serializers.py b/awx/api/serializers.py index d987e181..b84a80e7 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1321,8 +1321,8 @@ class OrganizationSerializer(BaseSerializer): class Meta: model = Organization - fields = ('*', 'max_hosts', 'custom_virtualenv', 'default_environment') - read_only_fields = ('*', 'custom_virtualenv') + fields = ('*', 'max_hosts', 'default_environment') + read_only_fields = ('*',) def get_related(self, obj): res = super(OrganizationSerializer, self).get_related(obj) @@ -1490,14 +1490,13 @@ class Meta: 'scm_update_on_launch', 'scm_update_cache_timeout', 'allow_override', - 'custom_virtualenv', 'default_environment', 'signature_validation_credential', ) + ( 'last_update_failed', 'last_updated', ) # Backwards compatibility - read_only_fields = ('*', 'custom_virtualenv') + read_only_fields = ('*',) def get_related(self, obj): res = super(ProjectSerializer, self).get_related(obj) @@ -2359,12 +2358,11 @@ class Meta: 'host_filter', 'overwrite', 'overwrite_vars', - 'custom_virtualenv', 'timeout', 'verbosity', 'limit', ) - read_only_fields = ('*', 'custom_virtualenv') + read_only_fields = ('*',) def get_related(self, obj): res = super(InventorySourceOptionsSerializer, self).get_related(obj) @@ -2568,8 +2566,6 @@ def validate(self, attrs): class InventoryUpdateSerializer(UnifiedJobSerializer, InventorySourceOptionsSerializer): - custom_virtualenv = serializers.ReadOnlyField() - class Meta: model = InventoryUpdate fields = ( @@ -2579,7 +2575,6 @@ class Meta: 'license_error', 'org_host_limit_error', 'source_project_update', - 'custom_virtualenv', 'instance_group', 'scm_revision', ) @@ -3288,13 +3283,12 @@ class Meta: 'become_enabled', 'diff_mode', 'allow_simultaneous', - 'custom_virtualenv', 'job_slice_count', 'webhook_service', 'webhook_credential', 'prevent_instance_group_fallback', ) - read_only_fields = ('*', 'custom_virtualenv') + read_only_fields = ('*',) def get_related(self, obj): res = super(JobTemplateSerializer, self).get_related(obj) @@ -3461,11 +3455,10 @@ def get_summary_fields(self, obj): class JobDetailSerializer(JobSerializer): playbook_counts = serializers.SerializerMethodField(help_text=_('A count of all plays and tasks for the job run.')) - custom_virtualenv = serializers.ReadOnlyField() class Meta: model = Job - fields = ('*', 'host_status_counts', 'playbook_counts', 'custom_virtualenv') + fields = ('*', 'host_status_counts', 'playbook_counts') def get_playbook_counts(self, obj): task_count = obj.get_event_queryset().filter(event='playbook_on_task_start').count() diff --git a/awx/api/templates/api/api_v2_config_view.md b/awx/api/templates/api/api_v2_config_view.md index 725669bd..65d043a7 100644 --- a/awx/api/templates/api/api_v2_config_view.md +++ b/awx/api/templates/api/api_v2_config_view.md @@ -11,8 +11,6 @@ the following fields (some fields may not be visible to all users): * `time_zone`: The configured time zone for the server. * `license_info`: Information about the current license. * `version`: Version of Ansible Tower package installed. -* `custom_virtualenvs`: Deprecated venv locations from before migration to - execution environments. Export tooling is in `awx-manage` commands. * `eula`: The current End-User License Agreement {% endifmeth %} diff --git a/awx/api/views/root.py b/awx/api/views/root.py index 65f3e0e1..f4d5a1c4 100644 --- a/awx/api/views/root.py +++ b/awx/api/views/root.py @@ -25,11 +25,11 @@ from awx.conf.registry import settings_registry from awx.main.analytics import all_collectors from awx.main.ha import is_ha_environment -from awx.main.utils import get_awx_version, get_custom_venv_choices +from awx.main.utils import get_awx_version from awx.main.utils.licensing import validate_entitlement_manifest from awx.api.versioning import reverse, drf_reverse from awx.main.constants import PRIVILEGE_ESCALATION_METHODS -from awx.main.models import Project, Organization, Instance, InstanceGroup, JobTemplate +from awx.main.models import Project, Organization, Instance, InstanceGroup from awx.main.utils import set_environ from awx.main.utils.licensing import get_licenser @@ -314,11 +314,8 @@ def get(self, request, format=None): dict( project_base_dir=settings.PROJECTS_ROOT, project_local_paths=Project.get_local_path_choices(), - custom_virtualenvs=get_custom_venv_choices(), ) ) - elif JobTemplate.accessible_objects(request.user, 'admin_role').exists(): - data['custom_virtualenvs'] = get_custom_venv_choices() return Response(data) diff --git a/awx/main/access.py b/awx/main/access.py index c768e74c..30238e05 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -1664,7 +1664,6 @@ def changes_are_non_sensitive(self, obj, data): 'ask_inventory_on_launch', 'ask_credential_on_launch', 'survey_enabled', - 'custom_virtualenv', 'diff_mode', 'timeout', 'job_slice_count', diff --git a/awx/main/conf.py b/awx/main/conf.py index 7c9d1f9e..e8cb2c1e 100644 --- a/awx/main/conf.py +++ b/awx/main/conf.py @@ -222,15 +222,6 @@ category_slug='system', ) -register( - 'CUSTOM_VENV_PATHS', - field_class=fields.StringListPathField, - label=_('Custom virtual environment paths'), - help_text=_('Paths where Tower will look for custom virtual environments (in addition to /var/lib/awx/venv/). Enter one path per line.'), - category=_('System'), - category_slug='system', - default=[], -) register( 'AD_HOC_COMMANDS', diff --git a/awx/main/management/commands/custom_venv_associations.py b/awx/main/management/commands/custom_venv_associations.py deleted file mode 100644 index 736dfe25..00000000 --- a/awx/main/management/commands/custom_venv_associations.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2021 Ansible, Inc. -# All Rights Reserved - -from django.core.management.base import BaseCommand -from awx.main.utils.common import get_custom_venv_choices -from awx.main.models import Organization, InventorySource, JobTemplate, Project -import yaml - - -class Command(BaseCommand): - """Returns the pip freeze from the path passed in the argument""" - - def add_arguments(self, parser): - parser.add_argument( - 'path', - type=str, - nargs=1, - default='', - help='run this with a path to a virtual environment as an argument to see the associated Job Templates, Organizations, Projects, and Inventory Sources.', - ) - parser.add_argument('-q', action='store_true', help='run with -q to output only the results of the query.') - - def handle(self, *args, **options): - # look organiztions and unified job templates (which include JTs, workflows, and Inventory updates) - super(Command, self).__init__() - results = {} - path = options.get('path') - if path: - all_venvs = get_custom_venv_choices() - if path[0] in all_venvs: # verify this is a valid path - path = path[0] - orgs = [{"name": org.name, "id": org.id} for org in Organization.objects.filter(custom_virtualenv=path)] - jts = [{"name": jt.name, "id": jt.id} for jt in JobTemplate.objects.filter(custom_virtualenv=path)] - proj = [{"name": proj.name, "id": proj.id} for proj in Project.objects.filter(custom_virtualenv=path)] - invsrc = [{"name": inv.name, "id": inv.id} for inv in InventorySource.objects.filter(custom_virtualenv=path)] - results["organizations"] = orgs - results["job_templates"] = jts - results["projects"] = proj - results["inventory_sources"] = invsrc - if not options.get('q'): - msg = [ - '# Virtual Environments Associations:', - yaml.dump(results), - '- To list all (now deprecated) custom virtual environments run:', - 'awx-manage list_custom_venvs', - '', - '- To export the contents of a (deprecated) virtual environment, run the following command while supplying the path as an argument:', - 'awx-manage export_custom_venv /path/to/venv', - '', - '- Run these commands with `-q` to remove tool tips.', - '', - ] - print('\n'.join(msg)) - else: - print(yaml.dump(results)) - - else: - print('\n', '# Incorrect path, verify your path is from the following list:') - print('\n'.join(all_venvs), '\n') diff --git a/awx/main/management/commands/export_custom_venv.py b/awx/main/management/commands/export_custom_venv.py deleted file mode 100644 index 82065b78..00000000 --- a/awx/main/management/commands/export_custom_venv.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) 2021 Ansible, Inc. -# All Rights Reserved - -from awx.main.utils.common import get_custom_venv_pip_freeze, get_custom_venv_choices -from django.core.management.base import BaseCommand - - -class Command(BaseCommand): - """Returns the pip freeze from the path passed in the argument""" - - def add_arguments(self, parser): - parser.add_argument( - 'path', - type=str, - nargs=1, - default='', - help='run this with a path to a virtual environment as an argument to see the pip freeze data', - ) - parser.add_argument('-q', action='store_true', help='run with -q to output only the results of the query.') - - def handle(self, *args, **options): - super(Command, self).__init__() - if options.get('path'): - path = options.get('path') - all_venvs = get_custom_venv_choices() - if path[0] in all_venvs: - pip_data = get_custom_venv_pip_freeze(options.get('path')[0]) - if pip_data: - if not options.get('q'): - msg = [ - '# Virtual environment contents:', - pip_data, - '- To list all (now deprecated) custom virtual environments run:', - 'awx-manage list_custom_venvs', - '', - '- To view the connections a (deprecated) virtual environment had in the database, run the following command while supplying the path as an argument:', - 'awx-manage custom_venv_associations /path/to/venv', - '', - '- Run these commands with `-q` to remove tool tips.', - '', - ] - print('\n'.join(msg)) - else: - print(pip_data) - - else: - print('\n', '# Incorrect path, verify your path is from the following list:') - print('\n'.join(all_venvs)) diff --git a/awx/main/management/commands/list_custom_venvs.py b/awx/main/management/commands/list_custom_venvs.py deleted file mode 100644 index 0df98c47..00000000 --- a/awx/main/management/commands/list_custom_venvs.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2021 Ansible, Inc. -# All Rights Reserved -import sys - -from awx.main.utils.common import get_custom_venv_choices -from django.core.management.base import BaseCommand -from django.conf import settings - - -class Command(BaseCommand): - """Returns a list of custom venv paths from the path passed in the argument""" - - def add_arguments(self, parser): - parser.add_argument('-q', action='store_true', help='run with -q to output only the results of the query.') - - def handle(self, *args, **options): - super(Command, self).__init__() - venvs = get_custom_venv_choices() - if venvs: - if not options.get('q'): - msg = [ - '# Discovered Virtual Environments:', - '\n'.join(venvs), - '', - '- To export the contents of a (deprecated) virtual environment, run the following command while supplying the path as an argument:', - 'awx-manage export_custom_venv /path/to/venv', - '', - '- To view the connections a (deprecated) virtual environment had in the database, run the following command while supplying the path as an argument:', - 'awx-manage custom_venv_associations /path/to/venv', - '', - '- Run these commands with `-q` to remove tool tips.', - '', - ] - print('\n'.join(msg)) - else: - print('\n'.join(venvs), '\n') - else: - msg = ["No custom virtual environments detected in:", settings.BASE_VENV_PATH] - - for path in settings.CUSTOM_VENV_PATHS: - msg.append(path) - - print('\n'.join(msg), file=sys.stderr) diff --git a/awx/main/migrations/0195_remove_custom_virtualenv.py b/awx/main/migrations/0195_remove_custom_virtualenv.py new file mode 100644 index 00000000..a3936693 --- /dev/null +++ b/awx/main/migrations/0195_remove_custom_virtualenv.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated for custom venv removal + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ('main', '0194_add_github_app_credential'), + ] + + operations = [ + migrations.RemoveField( + model_name='inventorysource', + name='custom_virtualenv', + ), + migrations.RemoveField( + model_name='inventoryupdate', + name='custom_virtualenv', + ), + migrations.RemoveField( + model_name='job', + name='custom_virtualenv', + ), + migrations.RemoveField( + model_name='jobtemplate', + name='custom_virtualenv', + ), + migrations.RemoveField( + model_name='organization', + name='custom_virtualenv', + ), + migrations.RemoveField( + model_name='project', + name='custom_virtualenv', + ), + ] diff --git a/awx/main/models/__init__.py b/awx/main/models/__init__.py index 3148f44f..fadff9fd 100644 --- a/awx/main/models/__init__.py +++ b/awx/main/models/__init__.py @@ -65,7 +65,6 @@ ROLE_SINGLETON_SYSTEM_AUDITOR, ) from awx.main.models.mixins import ( # noqa - CustomVirtualEnvMixin, ExecutionEnvironmentMixin, ResourceMixin, SurveyJobMixin, diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index bf7b86c7..1fe9af0c 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -47,7 +47,6 @@ ResourceMixin, TaskManagerInventoryUpdateMixin, RelatedJobsMixin, - CustomVirtualEnvMixin, ) from awx.main.models.notifications import ( NotificationTemplate, @@ -1093,7 +1092,7 @@ def credential(self): source_vars_dict = VarsDictProperty('source_vars') -class InventorySource(UnifiedJobTemplate, InventorySourceOptions, CustomVirtualEnvMixin, RelatedJobsMixin): +class InventorySource(UnifiedJobTemplate, InventorySourceOptions, RelatedJobsMixin): SOFT_UNIQUE_TOGETHER = [('polymorphic_ctype', 'name', 'inventory')] class Meta: @@ -1269,7 +1268,7 @@ def _get_related_jobs(self): return InventoryUpdate.objects.filter(inventory_source=self) -class InventoryUpdate(UnifiedJob, InventorySourceOptions, JobNotificationMixin, TaskManagerInventoryUpdateMixin, CustomVirtualEnvMixin): +class InventoryUpdate(UnifiedJob, InventorySourceOptions, JobNotificationMixin, TaskManagerInventoryUpdateMixin): """ Internal job for tracking inventory updates from external sources. """ diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 7bd52d44..f2f08c73 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -47,7 +47,6 @@ SurveyJobTemplateMixin, SurveyJobMixin, TaskManagerJobMixin, - CustomVirtualEnvMixin, RelatedJobsMixin, WebhookMixin, WebhookTemplateMixin, @@ -192,7 +191,7 @@ def passwords_needed_to_start(self): return needed -class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, ResourceMixin, CustomVirtualEnvMixin, RelatedJobsMixin, WebhookTemplateMixin): +class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, ResourceMixin, RelatedJobsMixin, WebhookTemplateMixin): """ A job template is a reusable job definition for applying a project (with playbook) to an inventory source with a given credential. @@ -553,7 +552,7 @@ def _get_related_jobs(self): return UnifiedJob.objects.filter(unified_job_template=self) -class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskManagerJobMixin, CustomVirtualEnvMixin, WebhookMixin): +class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskManagerJobMixin, WebhookMixin): """ A job applies a project (with playbook) to an inventory source with a given credential. It represents a single invocation of ansible-playbook with the diff --git a/awx/main/models/mixins.py b/awx/main/models/mixins.py index b8547225..ca12330d 100644 --- a/awx/main/models/mixins.py +++ b/awx/main/models/mixins.py @@ -2,7 +2,6 @@ from copy import copy, deepcopy import json import logging -import os import requests @@ -10,7 +9,6 @@ from django.apps import apps from django.conf import settings from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import ValidationError from django.db import models from django.db.models.query import QuerySet from django.utils.crypto import get_random_string @@ -20,7 +18,7 @@ # AWX from awx.main.models.rbac import Role, RoleAncestorEntry -from awx.main.utils import parse_yaml_or_json, get_custom_venv_choices, get_licenser, polymorphic +from awx.main.utils import parse_yaml_or_json, get_licenser, polymorphic from awx.main.utils.execution_environments import get_default_execution_environment from awx.main.utils.encryption import decrypt_value, get_encryption_key, is_encrypted from awx.main.utils.polymorphic import build_polymorphic_ctypes_map @@ -40,7 +38,6 @@ 'TaskManagerProjectUpdateMixin', 'TaskManagerInventoryUpdateMixin', 'ExecutionEnvironmentMixin', - 'CustomVirtualEnvMixin', ] @@ -523,23 +520,6 @@ def resolve_execution_environment(self): return get_default_execution_environment() -class CustomVirtualEnvMixin(models.Model): - class Meta: - abstract = True - - custom_virtualenv = models.CharField( - blank=True, null=True, default=None, max_length=100, help_text=_('Local absolute file path containing a custom Python virtualenv to use') - ) - - def clean_custom_virtualenv(self): - value = self.custom_virtualenv - if value and os.path.join(value, '') not in get_custom_venv_choices(): - raise ValidationError(_('{} is not a valid virtualenv in {}').format(value, settings.BASE_VENV_PATH)) - if value: - return os.path.join(value, '') - return None - - class RelatedJobsMixin(object): """ This method is intended to be overwritten. diff --git a/awx/main/models/notifications.py b/awx/main/models/notifications.py index 77f8032c..87db1834 100644 --- a/awx/main/models/notifications.py +++ b/awx/main/models/notifications.py @@ -280,7 +280,6 @@ class JobNotificationMixin(object): 'diff_mode', 'job_slice_number', 'job_slice_count', - 'custom_virtualenv', 'approval_status', 'approval_node_name', 'workflow_url', @@ -327,7 +326,6 @@ def context_stub(cls): 'artifacts': {}, 'controller_node': 'foo_controller', 'created': datetime.datetime(2018, 11, 13, 6, 4, 0, 0, tzinfo=datetime.timezone.utc), - 'custom_virtualenv': 'my_venv', 'description': 'Sample job description', 'diff_mode': False, 'elapsed': 0.403018, diff --git a/awx/main/models/organization.py b/awx/main/models/organization.py index 5e90c51a..7b97f5db 100644 --- a/awx/main/models/organization.py +++ b/awx/main/models/organization.py @@ -20,12 +20,12 @@ ROLE_SINGLETON_SYSTEM_AUDITOR, ) from awx.main.models.unified_jobs import UnifiedJob -from awx.main.models.mixins import ResourceMixin, CustomVirtualEnvMixin, RelatedJobsMixin +from awx.main.models.mixins import ResourceMixin, RelatedJobsMixin __all__ = ['Organization', 'Team', 'Profile', 'UserSessionMembership'] -class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVirtualEnvMixin, RelatedJobsMixin): +class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, RelatedJobsMixin): """ An organization is the basic unit of multi-tenancy divisions """ diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index e81fd578..0879df32 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -32,7 +32,7 @@ UnifiedJobTemplate, ) from awx.main.models.jobs import Job -from awx.main.models.mixins import ResourceMixin, TaskManagerProjectUpdateMixin, CustomVirtualEnvMixin, RelatedJobsMixin +from awx.main.models.mixins import ResourceMixin, TaskManagerProjectUpdateMixin, RelatedJobsMixin from awx.main.utils import update_scm_url, polymorphic from awx.main.utils.ansible import skip_directory, could_be_inventory, could_be_playbook from awx.main.utils.execution_environments import get_control_plane_execution_environment @@ -249,7 +249,7 @@ def get_lock_file(self): return proj_path + '.lock' -class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEnvMixin, RelatedJobsMixin): +class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, RelatedJobsMixin): """ A project represents a playbook git repo that can access a set of inventories """ diff --git a/awx/main/tests/functional/models/test_notifications.py b/awx/main/tests/functional/models/test_notifications.py index 2c1d6022..39fb6fe5 100644 --- a/awx/main/tests/functional/models/test_notifications.py +++ b/awx/main/tests/functional/models/test_notifications.py @@ -14,7 +14,6 @@ class TestJobNotificationMixin(object): 'job': { 'allow_simultaneous': bool, 'artifacts': {}, - 'custom_virtualenv': str, 'controller_node': str, 'created': datetime.datetime, 'description': str, diff --git a/awx/main/utils/common.py b/awx/main/utils/common.py index 81c64066..915314a3 100644 --- a/awx/main/utils/common.py +++ b/awx/main/utils/common.py @@ -10,7 +10,6 @@ import time import psycopg import os -import subprocess import re import stat import sys @@ -80,7 +79,6 @@ 'has_model_field_prefetched', 'set_environ', 'IllegalArgumentError', - 'get_custom_venv_choices', 'ScheduleTaskManager', 'ScheduleDependencyManager', 'ScheduleWorkflowManager', @@ -1011,35 +1009,6 @@ def get_current_apps(): return current_apps -def get_custom_venv_choices(): - from django.conf import settings - - all_venv_paths = settings.CUSTOM_VENV_PATHS + [settings.BASE_VENV_PATH] - custom_venv_choices = [] - - for venv_path in all_venv_paths: - if os.path.exists(venv_path): - for d in os.listdir(venv_path): - if venv_path == settings.BASE_VENV_PATH and d == 'awx': - continue - - if os.path.exists(os.path.join(venv_path, d, 'bin', 'pip')): - custom_venv_choices.append(os.path.join(venv_path, d)) - - return custom_venv_choices - - -def get_custom_venv_pip_freeze(venv_path): - pip_path = os.path.join(venv_path, 'bin', 'pip') - - try: - freeze_data = subprocess.run([pip_path, "freeze"], capture_output=True) - pip_data = (freeze_data.stdout).decode('UTF-8') - return pip_data - except Exception: - logger.exception("Encountered an error while trying to run 'pip freeze' for custom virtual environments:") - - def is_ansible_variable(key): return key.startswith('ansible_') diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 9120a707..2bb51ca3 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -179,7 +179,6 @@ # If this setting is an empty list (the default), we will only trust ourself CSRF_TRUSTED_ORIGINS = [] -CUSTOM_VENV_PATHS = [] # Warning: this is a placeholder for a database setting # This should not be set via a file. diff --git a/awx/settings/development.py b/awx/settings/development.py index df6676c6..9240a061 100644 --- a/awx/settings/development.py +++ b/awx/settings/development.py @@ -59,10 +59,6 @@ SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' INSTALL_UUID = '00000000-0000-0000-0000-000000000000' -# Ansible base virtualenv paths and enablement -# only used for deprecated fields and management commands for them -BASE_VENV_PATH = os.path.realpath("/var/lib/awx/venv") - CLUSTER_HOST_ID = socket.gethostname() AWX_CALLBACK_PROFILE = True diff --git a/awx/settings/production.py b/awx/settings/production.py index fa74bc7f..e6b1c8c6 100644 --- a/awx/settings/production.py +++ b/awx/settings/production.py @@ -30,10 +30,6 @@ # See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts ALLOWED_HOSTS = [] -# Ansible base virtualenv paths and enablement -# only used for deprecated fields and management commands for them -BASE_VENV_PATH = os.path.realpath("/var/lib/awx/venv") - # Very important that this is editable (not read_only) in the API AWX_ISOLATION_SHOW_PATHS = [ '/etc/pki/ca-trust:/etc/pki/ca-trust:O', diff --git a/awx/ui/CONTRIBUTING.md b/awx/ui/CONTRIBUTING.md index e3f09090..26167d8e 100644 --- a/awx/ui/CONTRIBUTING.md +++ b/awx/ui/CONTRIBUTING.md @@ -309,16 +309,13 @@ If you want to stub the value of a context, or assert actions taken on it, you c ```javascript const config = { - custom_virtualenvs: ['foo', 'bar'], + isDev: true, }; mountWithContexts(, { context: { config }, }); ``` -Now that these custom virtual environments are available in this `OrganizationForm` test we can assert that the component that displays -them is rendering properly. - The object containing context values looks for five known contexts, identified by the keys `linguiPublisher`, `router`, `config`, `network`, and `dialog` — the latter three each referring to the contexts defined in `src/contexts`. You can pass `false` for any of these values, and the corresponding context will be omitted from your test. For example, this will mount your component without the dialog context: ```javascript diff --git a/awx/ui/src/components/AppContainer/AppContainer.test.js b/awx/ui/src/components/AppContainer/AppContainer.test.js index 7c5a9ee8..4d0b0e67 100644 --- a/awx/ui/src/components/AppContainer/AppContainer.test.js +++ b/awx/ui/src/components/AppContainer/AppContainer.test.js @@ -64,7 +64,6 @@ describe('', () => { config: { analytics_status: 'detailed', ansible_version: null, - custom_virtualenvs: [], version: '9000', me: { is_superuser: true }, toJSON: () => '/config/', @@ -109,7 +108,6 @@ describe('', () => { config: { analytics_status: 'detailed', ansible_version: null, - custom_virtualenvs: [], version: '9000', me: { is_superuser: true }, toJSON: () => '/config/', @@ -132,7 +130,6 @@ describe('', () => { config: { analytics_status: 'off', ansible_version: null, - custom_virtualenvs: [], version: '9000', me: { is_superuser: true }, toJSON: () => '/config/', diff --git a/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.test.js b/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.test.js index a0e84e68..84e6471c 100644 --- a/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.test.js +++ b/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.test.js @@ -11,8 +11,6 @@ const mockExecutionEnvironment = { description: '', }; -const virtualEnvironment = 'var/lib/awx/custom_env'; - describe('', () => { test('should display execution environment detail', async () => { const wrapper = mountWithContexts( @@ -30,37 +28,6 @@ describe('', () => { ); }); - test('should display execution environment detail even with a previous virtual env present', async () => { - const wrapper = mountWithContexts( - - ); - const executionEnvironment = wrapper.find('ExecutionEnvironmentDetail'); - expect(executionEnvironment).toHaveLength(1); - expect(executionEnvironment.find('dt').text()).toEqual( - 'Execution Environment' - ); - expect(executionEnvironment.find('dd').text()).toEqual( - mockExecutionEnvironment.name - ); - }); - - test('should display warning missing execution environment', async () => { - const wrapper = mountWithContexts( - - ); - const executionEnvironment = wrapper.find('ExecutionEnvironmentDetail'); - expect(executionEnvironment).toHaveLength(1); - expect(executionEnvironment.find('dt').text()).toEqual( - 'Execution Environment' - ); - expect(executionEnvironment.find('dd').text()).toEqual('Missing resource'); - expect(wrapper.find('ExclamationTrianglePopover').length).toBe(1); - expect(wrapper.find('Popover').length).toBe(1); - }); - test('should display warning deleted execution environment', async () => { const wrapper = mountWithContexts( diff --git a/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js b/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js index ba1705ce..f29d05e0 100644 --- a/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js +++ b/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js @@ -17,7 +17,6 @@ import { VERBOSITY } from '../VerbositySelectField'; function PromptInventorySourceDetail({ resource }) { const { - custom_virtualenv, group_by, instance_filters, overwrite, @@ -93,7 +92,6 @@ function PromptInventorySourceDetail({ resource }) { /> )} diff --git a/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js b/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js index 1fd0877d..df04971a 100644 --- a/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js +++ b/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js @@ -41,7 +41,6 @@ function PromptJobTemplateDetail({ resource }) { verbosity, webhook_key, webhook_service, - custom_virtualenv, } = resource; let optionsList = ''; @@ -144,7 +143,6 @@ function PromptJobTemplateDetail({ resource }) { )} diff --git a/awx/ui/src/components/PromptDetail/PromptProjectDetail.js b/awx/ui/src/components/PromptDetail/PromptProjectDetail.js index a51e49f4..dd1cebd2 100644 --- a/awx/ui/src/components/PromptDetail/PromptProjectDetail.js +++ b/awx/ui/src/components/PromptDetail/PromptProjectDetail.js @@ -17,7 +17,6 @@ function PromptProjectDetail({ resource }) { const { t } = useLingui(); const { allow_override, - custom_virtualenv, local_path, scm_branch, scm_clean, @@ -89,7 +88,6 @@ function PromptProjectDetail({ resource }) { )} diff --git a/awx/ui/src/components/PromptDetail/data.inventory_source.json b/awx/ui/src/components/PromptDetail/data.inventory_source.json index 57a0d750..9c9b11fc 100644 --- a/awx/ui/src/components/PromptDetail/data.inventory_source.json +++ b/awx/ui/src/components/PromptDetail/data.inventory_source.json @@ -101,7 +101,6 @@ "group_by": "group1,group2,group3", "overwrite":true, "overwrite_vars":true, - "custom_virtualenv":null, "timeout":0, "verbosity":2, "last_job_run":null, diff --git a/awx/ui/src/components/PromptDetail/data.job_template.json b/awx/ui/src/components/PromptDetail/data.job_template.json index 620bbb9f..7a518ba3 100644 --- a/awx/ui/src/components/PromptDetail/data.job_template.json +++ b/awx/ui/src/components/PromptDetail/data.job_template.json @@ -199,7 +199,6 @@ "become_enabled": true, "diff_mode": false, "allow_simultaneous": true, - "custom_virtualenv": null, "job_slice_count": 1, "webhook_service": "github", "webhook_credential": 8, diff --git a/awx/ui/src/components/PromptDetail/data.project.json b/awx/ui/src/components/PromptDetail/data.project.json index 371cc1d0..1b8c506c 100644 --- a/awx/ui/src/components/PromptDetail/data.project.json +++ b/awx/ui/src/components/PromptDetail/data.project.json @@ -108,7 +108,6 @@ "scm_update_on_launch":true, "scm_update_cache_timeout":3, "allow_override":true, - "custom_virtualenv": "mock virtual env", "last_update_failed":false, "last_updated":"2020-03-11T20:18:14Z", "default_environment": 1 diff --git a/awx/ui/src/components/TemplateList/TemplateListItem.js b/awx/ui/src/components/TemplateList/TemplateListItem.js index 186ac47b..66215365 100644 --- a/awx/ui/src/components/TemplateList/TemplateListItem.js +++ b/awx/ui/src/components/TemplateList/TemplateListItem.js @@ -5,21 +5,18 @@ import 'styled-components/macro'; import React, { useState, useCallback } from 'react'; import { Link } from 'react-router-dom'; -import { Button, Popover, Tooltip, Chip } from '@patternfly/react-core'; +import { Button, Tooltip, Chip } from '@patternfly/react-core'; import { Tr, Td, ExpandableRowContent } from '@patternfly/react-table'; -import { Trans, useLingui } from '@lingui/react/macro'; +import { useLingui } from '@lingui/react/macro'; import { ExclamationTriangleIcon, PencilAltIcon, ProjectDiagramIcon, RocketIcon, } from '@patternfly/react-icons'; -import styled from 'styled-components'; import { timeOfDay, formatDateString } from 'util/dates'; import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from 'api'; import { toTitleCase } from 'util/strings'; -import getDocsBaseUrl from 'util/getDocsBaseUrl'; -import { useConfig } from 'contexts/Config'; import { ActionsTd, ActionItem, TdBreakWord } from '../PaginatedTable'; import { DetailList, Detail, DeletedDetail } from '../DetailList'; import ChipGroup from '../ChipGroup'; @@ -29,14 +26,6 @@ import { LaunchButton } from '../LaunchButton'; import Sparkline from '../Sparkline'; import CopyButton from '../CopyButton'; -const ExclamationTriangleIconWarning = styled(ExclamationTriangleIcon)` - color: var(--pf-global--warning-color--100); - margin-left: 18px; - cursor: pointer; -`; - -ExclamationTriangleIconWarning.displayName = 'ExclamationTriangleIconWarning'; - function TemplateListItem({ isExpanded, onExpand, @@ -49,14 +38,9 @@ function TemplateListItem({ rowIndex, }) { const { t } = useLingui(); - const config = useConfig(); const [isDisabled, setIsDisabled] = useState(false); const labelId = `check-action-${template.id}`; - const docsLink = `${getDocsBaseUrl( - config - )}/html/upgrade-migration-guide/upgrade_to_ees.html`; - const copyTemplate = useCallback(async () => { let response; if (template.type === 'job_template') { @@ -92,11 +76,6 @@ function TemplateListItem({ (!summaryFields.project || (!summaryFields.inventory && !askInventoryOnLaunch)); - const missingExecutionEnvironment = - template.type === 'job_template' && - template.custom_virtualenv && - !template.execution_environment; - const inventoryValue = (kind, id) => { const inventorykind = kind === 'smart' ? 'smart_inventory' : 'inventory'; @@ -158,35 +137,6 @@ function TemplateListItem({ )} - {missingExecutionEnvironment && ( - - {t`Execution Environment Missing`} - } - bodyContent={ -
- - Custom virtual environment {template.custom_virtualenv}{' '} - must be replaced by an execution environment. For more - information about migrating to execution environments see{' '} - - the documentation. - - -
- } - position="right" - > - -
-
- )} {summaryFields.recent_jobs ? ( @@ -316,7 +266,6 @@ function TemplateListItem({ )} {template.type === 'job_template' && ( )} diff --git a/awx/ui/src/components/TemplateList/TemplateListItem.test.js b/awx/ui/src/components/TemplateList/TemplateListItem.test.js index 6785d3f0..7b2d7b26 100644 --- a/awx/ui/src/components/TemplateList/TemplateListItem.test.js +++ b/awx/ui/src/components/TemplateList/TemplateListItem.test.js @@ -367,60 +367,6 @@ describe('', () => { expect(wrapper.find('ProjectDiagramIcon').length).toBe(0); }); - test('should render warning about missing execution environment', () => { - const wrapper = mountWithContexts( - - - - -
- ); - - expect(wrapper.find('ExclamationTriangleIconWarning').length).toBe(1); - }); - test('should render expected details in expanded section', async () => { const wrapper = mountWithContexts( diff --git a/awx/ui/src/components/TemplateList/data.job_template.json b/awx/ui/src/components/TemplateList/data.job_template.json index 8e1a41b4..a92103ac 100644 --- a/awx/ui/src/components/TemplateList/data.job_template.json +++ b/awx/ui/src/components/TemplateList/data.job_template.json @@ -184,7 +184,6 @@ "become_enabled": false, "diff_mode": false, "allow_simultaneous": false, - "custom_virtualenv": null, "execution_environment": 1, "job_slice_count": 1, "webhook_credential": 1, diff --git a/awx/ui/src/screens/Dashboard/shared/data.job_template.json b/awx/ui/src/screens/Dashboard/shared/data.job_template.json index e2841076..5282566b 100644 --- a/awx/ui/src/screens/Dashboard/shared/data.job_template.json +++ b/awx/ui/src/screens/Dashboard/shared/data.job_template.json @@ -173,7 +173,6 @@ "become_enabled": false, "diff_mode": false, "allow_simultaneous": false, - "custom_virtualenv": null, "job_slice_count": 1, "webhook_credential": 1, "webhook_key": "asertdyuhjkhgfd234567kjgfds", diff --git a/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js b/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js index 85f430f4..f1334bf9 100644 --- a/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js +++ b/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js @@ -56,7 +56,6 @@ function InventorySourceDetail({ inventorySource }) { const { created, - custom_virtualenv, description, id, modified, @@ -219,7 +218,6 @@ function InventorySourceDetail({ inventorySource }) { /> )} {source_project && ( diff --git a/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.js b/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.js index a351439f..9df8c2cd 100644 --- a/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.js +++ b/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.js @@ -4,10 +4,8 @@ import { useLingui } from '@lingui/react/macro'; import { Button, Tooltip } from '@patternfly/react-core'; import { Tr, Td } from '@patternfly/react-table'; import { - ExclamationTriangleIcon as PFExclamationTriangleIcon, PencilAltIcon, } from '@patternfly/react-icons'; -import styled from 'styled-components'; import { ActionsTd, ActionItem, TdBreakWord } from 'components/PaginatedTable'; import StatusLabel from 'components/StatusLabel'; @@ -16,11 +14,6 @@ import { formatDateString } from 'util/dates'; import { isJobRunning } from 'util/jobs'; import InventorySourceSyncButton from '../shared/InventorySourceSyncButton'; -const ExclamationTriangleIcon = styled(PFExclamationTriangleIcon)` - color: var(--pf-global--warning-color--100); - margin-left: 18px; -`; - function InventorySourceListItem({ source, isSelected, @@ -47,9 +40,6 @@ function InventorySourceListItem({ ); - const missingExecutionEnvironment = - source.custom_virtualenv && !source.execution_environment; - let job = null; if (source.summary_fields?.current_job) { @@ -73,17 +63,6 @@ function InventorySourceListItem({ {source.name} - {missingExecutionEnvironment && ( - - - - - - )}
{job && ( diff --git a/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.test.js b/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.test.js index c1bb8761..aac23321 100644 --- a/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.test.js +++ b/awx/ui/src/screens/Inventory/InventorySources/InventorySourceListItem.test.js @@ -153,31 +153,6 @@ describe('', () => { expect(wrapper.find('InventorySourceSyncButton').length).toBe(1); }); - test('should render warning about missing execution environment', () => { - const onSelect = jest.fn(); - wrapper = mountWithContexts( - - - - -
- ); - expect( - wrapper.find('.missing-execution-environment').prop('content') - ).toEqual( - 'Custom virtual environment /var/lib/awx/env must be replaced by an execution environment.' - ); - }); - test('should render cancel button while job is running', () => { const onSelect = jest.fn(); wrapper = mountWithContexts( @@ -194,7 +169,6 @@ describe('', () => { status: 'running', }, }, - custom_virtualenv: '/var/lib/awx/env', execution_environment: null, }} isSelected={false} diff --git a/awx/ui/src/screens/Inventory/shared/data.inventory_source.json b/awx/ui/src/screens/Inventory/shared/data.inventory_source.json index 7c829c56..1b2ba0af 100644 --- a/awx/ui/src/screens/Inventory/shared/data.inventory_source.json +++ b/awx/ui/src/screens/Inventory/shared/data.inventory_source.json @@ -104,7 +104,6 @@ "credential": 8, "overwrite":true, "overwrite_vars":true, - "custom_virtualenv":"/var/lib/awx/venv/custom", "timeout":0, "verbosity":2, "last_job_run":null, diff --git a/awx/ui/src/screens/Job/shared/data.job.json b/awx/ui/src/screens/Job/shared/data.job.json index f3c2f506..7108ad96 100644 --- a/awx/ui/src/screens/Job/shared/data.job.json +++ b/awx/ui/src/screens/Job/shared/data.job.json @@ -189,6 +189,5 @@ "play_count": 1, "task_count": 1 }, - "custom_virtualenv": "/var/lib/awx/venv/ansible", "execution_environment": 1 } diff --git a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js index cab67164..bc3e7042 100644 --- a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js +++ b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js @@ -25,7 +25,6 @@ function OrganizationDetail({ organization }) { const { name, description, - custom_virtualenv, max_hosts, created, modified, @@ -99,7 +98,6 @@ function OrganizationDetail({ organization }) { /> )} ', () => { id: 12, name: 'Foo', description: 'Bar', - custom_virtualenv: 'Fizz', max_hosts: '0', created: '2015-07-07T17:21:26.429745Z', modified: '2019-08-11T19:47:37.980466Z', diff --git a/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.js b/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.js index 86443d38..05634f93 100644 --- a/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.js +++ b/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.js @@ -1,23 +1,16 @@ import React from 'react'; import { string, bool, func } from 'prop-types'; import { useLingui } from '@lingui/react/macro'; -import { Button, Tooltip } from '@patternfly/react-core'; +import { Button } from '@patternfly/react-core'; import { Tr, Td } from '@patternfly/react-table'; import { Link } from 'react-router-dom'; -import styled from 'styled-components'; import { - ExclamationTriangleIcon as PFExclamationTriangleIcon, PencilAltIcon, } from '@patternfly/react-icons'; import { ActionsTd, ActionItem, TdBreakWord } from 'components/PaginatedTable'; import { Organization } from 'types'; -const ExclamationTriangleIcon = styled(PFExclamationTriangleIcon)` - color: var(--pf-global--warning-color--100); - margin-left: 18px; -`; - function OrganizationListItem({ organization, isSelected, @@ -28,9 +21,6 @@ function OrganizationListItem({ const { t } = useLingui(); const labelId = `check-action-${organization.id}`; - const missingExecutionEnvironment = - organization.custom_virtualenv && !organization.default_environment; - return (
{organization.name} - {missingExecutionEnvironment && ( - - - - - - )} {organization.summary_fields.related_field_counts.users} diff --git a/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.test.js b/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.test.js index c2c7de66..339f3619 100644 --- a/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.test.js +++ b/awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.test.js @@ -108,38 +108,4 @@ describe('', () => { ); expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy(); }); - - test('should render warning about missing execution environment', () => { - const wrapper = mountWithContexts( - - - {}} - /> - -
- ); - expect( - wrapper.find('.missing-execution-environment').prop('content') - ).toEqual( - 'Custom virtual environment /var/lib/awx/env must be replaced by an execution environment.' - ); - }); }); diff --git a/awx/ui/src/screens/Project/ProjectAdd/ProjectAdd.test.js b/awx/ui/src/screens/Project/ProjectAdd/ProjectAdd.test.js index 044f0232..b69d3880 100644 --- a/awx/ui/src/screens/Project/ProjectAdd/ProjectAdd.test.js +++ b/awx/ui/src/screens/Project/ProjectAdd/ProjectAdd.test.js @@ -26,7 +26,6 @@ describe('', () => { scm_update_on_launch: true, scm_update_cache_timeout: 3, allow_override: false, - custom_virtualenv: '/var/lib/awx/venv/custom-env', default_environment: { id: 1, name: 'Foo' }, }; diff --git a/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.js b/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.js index f9f98491..8b53bb20 100644 --- a/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.js +++ b/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.js @@ -44,7 +44,6 @@ function ProjectDetail({ project }) { const { allow_override, created, - custom_virtualenv, description, id, local_path, @@ -277,7 +276,6 @@ function ProjectDetail({ project }) { /> diff --git a/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.test.js b/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.test.js index 36875a87..e8a41728 100644 --- a/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.test.js +++ b/awx/ui/src/screens/Project/ProjectDetail/ProjectDetail.test.js @@ -89,7 +89,6 @@ describe('', () => { scm_update_on_launch: true, scm_update_cache_timeout: 5, allow_override: true, - custom_virtualenv: '/custom-venv', default_environment: 1, }; diff --git a/awx/ui/src/screens/Project/ProjectEdit/ProjectEdit.test.js b/awx/ui/src/screens/Project/ProjectEdit/ProjectEdit.test.js index 4b7193dc..1e9f7e27 100644 --- a/awx/ui/src/screens/Project/ProjectEdit/ProjectEdit.test.js +++ b/awx/ui/src/screens/Project/ProjectEdit/ProjectEdit.test.js @@ -27,7 +27,6 @@ describe('', () => { scm_update_on_launch: true, scm_update_cache_timeout: 3, allow_override: false, - custom_virtualenv: '/var/lib/awx/venv/custom-env', summary_fields: { credential: { id: 100, diff --git a/awx/ui/src/screens/Project/ProjectList/ProjectListItem.js b/awx/ui/src/screens/Project/ProjectList/ProjectListItem.js index 692ce756..2565905b 100644 --- a/awx/ui/src/screens/Project/ProjectList/ProjectListItem.js +++ b/awx/ui/src/screens/Project/ProjectList/ProjectListItem.js @@ -7,7 +7,6 @@ import { useLingui } from '@lingui/react/macro'; import { Link } from 'react-router-dom'; import { PencilAltIcon, - ExclamationTriangleIcon as PFExclamationTriangleIcon, UndoIcon, } from '@patternfly/react-icons'; import styled from 'styled-components'; @@ -28,11 +27,6 @@ const Label = styled.span` color: var(--pf-global--disabled-color--100); `; -const ExclamationTriangleIcon = styled(PFExclamationTriangleIcon)` - color: var(--pf-global--warning-color--100); - margin-left: 18px; -`; - function ProjectListItem({ isExpanded, onExpand, @@ -147,9 +141,6 @@ function ProjectListItem({ const labelId = `check-action-${project.id}`; - const missingExecutionEnvironment = - project.custom_virtualenv && !project.default_environment; - let job = null; if (project.summary_fields?.current_job) { @@ -183,17 +174,6 @@ function ProjectListItem({ {project.name} - {missingExecutionEnvironment && ( - - - - - - )}
{job ? ( @@ -301,7 +281,6 @@ function ProjectListItem({ )} ', () => { expect(wrapper.find('ProjectSyncButton').exists()).toBeTruthy(); }); - test('should render warning about missing execution environment', () => { - const wrapper = mountWithContexts( - - - {}} - project={{ - id: 1, - name: 'Project 1', - url: '/api/v2/projects/1', - type: 'project', - scm_type: 'git', - scm_revision: '7788f7erga0jijodfgsjisiodf98sdga9hg9a98gaf', - summary_fields: { - last_job: { - id: 9000, - status: 'successful', - }, - user_capabilities: { - start: true, - }, - }, - custom_virtualenv: '/var/lib/awx/env', - default_environment: null, - }} - /> - -
- ); - - expect(wrapper.find('ExclamationTrianglePopover').length).toBe(1); - }); - test('launch button hidden from users without start capabilities', () => { const wrapper = mountWithContexts( @@ -429,7 +394,6 @@ describe('', () => { image: 'mock.image', }, }, - custom_virtualenv: '/var/lib/awx/env', default_environment: 123, organization: 999, }} diff --git a/awx/ui/src/screens/Project/data.project.json b/awx/ui/src/screens/Project/data.project.json index 9f58e524..82b59c7f 100644 --- a/awx/ui/src/screens/Project/data.project.json +++ b/awx/ui/src/screens/Project/data.project.json @@ -116,7 +116,6 @@ "scm_update_on_launch": false, "scm_update_cache_timeout": 0, "allow_override": false, - "custom_virtualenv": null, "last_update_failed": false, "last_updated": "2019-09-30T18:06:34.713654Z", "execution_environment": 1 diff --git a/awx/ui/src/screens/Project/shared/ProjectForm.test.js b/awx/ui/src/screens/Project/shared/ProjectForm.test.js index b9ee3ed8..4ea4a0d5 100644 --- a/awx/ui/src/screens/Project/shared/ProjectForm.test.js +++ b/awx/ui/src/screens/Project/shared/ProjectForm.test.js @@ -24,7 +24,6 @@ describe('', () => { scm_update_on_launch: true, scm_update_cache_timeout: 3, allow_override: false, - custom_virtualenv: '/var/lib/awx/venv/custom-env', summary_fields: { credential: { id: 100, diff --git a/awx/ui/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.js b/awx/ui/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.js index b456090a..4cd0473f 100644 --- a/awx/ui/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.js +++ b/awx/ui/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.js @@ -33,7 +33,6 @@ describe('', () => { LICENSE: null, INSTALL_UUID: 'db39b9ec-0c6e-4554-987d-42aw9c732ed8', DEFAULT_EXECUTION_ENVIRONMENT: 1, - CUSTOM_VENV_PATHS: [], AUTOMATION_ANALYTICS_LAST_ENTRIES: '{"foo": "2021-11-24R06:35:15.179Z"}', }, diff --git a/awx/ui/src/screens/Setting/shared/data.allSettingOptions.json b/awx/ui/src/screens/Setting/shared/data.allSettingOptions.json index 4cdd9e08..cb6580b1 100644 --- a/awx/ui/src/screens/Setting/shared/data.allSettingOptions.json +++ b/awx/ui/src/screens/Setting/shared/data.allSettingOptions.json @@ -101,20 +101,6 @@ "category_slug": "system", "default": null }, - "CUSTOM_VENV_PATHS": { - "type": "list", - "required": false, - "label": "Custom virtual environment paths", - "help_text": "Paths where Tower will look for custom virtual environments (in addition to /var/lib/awx/venv/). Enter one path per line.", - "category": "System", - "category_slug": "system", - "default": [], - "child": { - "type": "string", - "required": true, - "read_only": false - } - }, "AD_HOC_COMMANDS": { "type": "list", "required": false, @@ -4576,17 +4562,6 @@ "category_slug": "system", "defined_in_file": false }, - "CUSTOM_VENV_PATHS": { - "type": "list", - "label": "Custom virtual environment paths", - "help_text": "Paths where Tower will look for custom virtual environments (in addition to /var/lib/awx/venv/). Enter one path per line.", - "category": "System", - "category_slug": "system", - "defined_in_file": false, - "child": { - "type": "string" - } - }, "AD_HOC_COMMANDS": { "type": "list", "label": "Ansible Modules Allowed for Ad Hoc Jobs", diff --git a/awx/ui/src/screens/Setting/shared/data.allSettings.json b/awx/ui/src/screens/Setting/shared/data.allSettings.json index 9dbc0c29..98afa7c8 100644 --- a/awx/ui/src/screens/Setting/shared/data.allSettings.json +++ b/awx/ui/src/screens/Setting/shared/data.allSettings.json @@ -15,7 +15,6 @@ "DEFAULT_CONTROL_PLANE_QUEUE_NAME": "controlplane", "DEFAULT_EXECUTION_QUEUE_NAME": "default", "DEFAULT_EXECUTION_ENVIRONMENT": null, - "CUSTOM_VENV_PATHS": [], "AD_HOC_COMMANDS": [ "command" ], diff --git a/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js b/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js index c0eb55bf..45fda0e2 100644 --- a/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js +++ b/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js @@ -65,7 +65,6 @@ function JobTemplateDetail({ template }) { related: { webhook_receiver }, webhook_key, prevent_instance_group_fallback, - custom_virtualenv, } = template; const { id: templateId } = useParams(); const history = useHistory(); @@ -241,7 +240,6 @@ function JobTemplateDetail({ template }) { )} '/config/', @@ -122,7 +121,6 @@ export function mountWithContexts(node, options = {}) { const childContextTypes = { config: shape({ ansible_version: string, - custom_virtualenvs: arrayOf(string), version: string, }), router: shape({ diff --git a/awx/ui/testUtils/enzymeHelpers.test.js b/awx/ui/testUtils/enzymeHelpers.test.js index 3e7b66a0..21b6a773 100644 --- a/awx/ui/testUtils/enzymeHelpers.test.js +++ b/awx/ui/testUtils/enzymeHelpers.test.js @@ -68,7 +68,6 @@ describe('mountWithContexts', () => { {value => (
- {value.custom_virtualenvs[0]} {value.version}
)} @@ -80,14 +79,12 @@ describe('mountWithContexts', () => { it('should mount and render with custom Config value', () => { const config = { - custom_virtualenvs: ['Fizz', 'Buzz'], version: '1.1', }; const Foo = () => ( {value => (
- {value.custom_virtualenvs[0]} {value.version}
)} diff --git a/awx_collection/plugins/modules/inventory_source.py b/awx_collection/plugins/modules/inventory_source.py index 5f6c1781..a5607ba0 100644 --- a/awx_collection/plugins/modules/inventory_source.py +++ b/awx_collection/plugins/modules/inventory_source.py @@ -76,12 +76,6 @@ description: - Execution Environment name, ID, or named URL to use for the source. type: str - custom_virtualenv: - description: - - Local absolute file path containing a custom Python virtualenv to use. - - Only compatible with older versions of AWX/Controller - - Deprecated, will be removed in the future - type: str overwrite: description: - Delete child groups and hosts not found in source. @@ -179,7 +173,6 @@ def main(): limit=dict(), credential=dict(), execution_environment=dict(), - custom_virtualenv=dict(), organization=dict(), overwrite=dict(type='bool'), overwrite_vars=dict(type='bool'), @@ -276,7 +269,6 @@ def main(): 'source_vars', 'overwrite', 'overwrite_vars', - 'custom_virtualenv', 'timeout', 'verbosity', 'update_on_launch', diff --git a/awx_collection/plugins/modules/job_template.py b/awx_collection/plugins/modules/job_template.py index 81fe4951..a635dc3f 100644 --- a/awx_collection/plugins/modules/job_template.py +++ b/awx_collection/plugins/modules/job_template.py @@ -86,12 +86,6 @@ description: - Execution Environment name, ID, or named URL to use for the job template. type: str - custom_virtualenv: - description: - - Local absolute file path containing a custom Python virtualenv to use. - - Only compatible with older versions of AWX/Tower - - Deprecated, will be removed in the future - type: str instance_groups: description: - list of Instance Group names, IDs, or named URLs for this Organization to run on. @@ -400,7 +394,6 @@ def main(): vault_credential=dict(), credentials=dict(type='list', elements='str'), execution_environment=dict(), - custom_virtualenv=dict(), instance_groups=dict(type="list", elements='str'), forks=dict(type='int'), limit=dict(), @@ -538,7 +531,6 @@ def main(): 'become_enabled', 'diff_mode', 'allow_simultaneous', - 'custom_virtualenv', 'job_slice_count', 'webhook_service', 'prevent_instance_group_fallback', diff --git a/awx_collection/plugins/modules/organization.py b/awx_collection/plugins/modules/organization.py index 6fc406b9..3a40a891 100644 --- a/awx_collection/plugins/modules/organization.py +++ b/awx_collection/plugins/modules/organization.py @@ -38,12 +38,6 @@ description: - Default Execution Environment name, ID, or named URL to use for jobs owned by the Organization. type: str - custom_virtualenv: - description: - - Local absolute file path containing a custom Python virtualenv to use. - - Only compatible with older versions of AWX/Tower - - Deprecated, will be removed in the future - type: str max_hosts: description: - The max hosts allowed in this organizations @@ -122,7 +116,6 @@ def main(): new_name=dict(), description=dict(), default_environment=dict(), - custom_virtualenv=dict(), max_hosts=dict(type='int'), instance_groups=dict(type="list", elements='str'), notification_templates_started=dict(type="list", elements='str'), @@ -141,7 +134,6 @@ def main(): new_name = module.params.get("new_name") description = module.params.get('description') default_ee = module.params.get('default_environment') - custom_virtualenv = module.params.get('custom_virtualenv') max_hosts = module.params.get('max_hosts') state = module.params.get('state') @@ -198,8 +190,6 @@ def main(): org_fields['description'] = description if default_ee is not None: org_fields['default_environment'] = module.resolve_name_to_id('execution_environments', default_ee) - if custom_virtualenv is not None: - org_fields['custom_virtualenv'] = custom_virtualenv if max_hosts is not None: org_fields['max_hosts'] = max_hosts diff --git a/awx_collection/plugins/modules/project.py b/awx_collection/plugins/modules/project.py index 2621e57a..e8d2fbd4 100644 --- a/awx_collection/plugins/modules/project.py +++ b/awx_collection/plugins/modules/project.py @@ -108,12 +108,6 @@ description: - Default Execution Environment name, ID, or named URL to use for jobs relating to the project. type: str - custom_virtualenv: - description: - - Local absolute file path containing a custom Python virtualenv to use. - - Only compatible with older versions of AWX/Tower - - Deprecated, will be removed in the future - type: str organization: description: - Name, ID, or named URL of organization for the project. @@ -267,7 +261,6 @@ def main(): allow_override=dict(type='bool', aliases=['scm_allow_override']), timeout=dict(type='int', aliases=['job_timeout']), default_environment=dict(), - custom_virtualenv=dict(), organization=dict(), notification_templates_started=dict(type="list", elements='str'), notification_templates_success=dict(type="list", elements='str'), @@ -368,8 +361,6 @@ def main(): 'scm_update_on_launch', 'scm_update_cache_timeout', 'timeout', - 'scm_update_cache_timeout', - 'custom_virtualenv', 'description', 'allow_override', ): diff --git a/docs/docsite/rst/userguide/notification_parameters_supported.rst b/docs/docsite/rst/userguide/notification_parameters_supported.rst index 5bc5dc18..44f5042b 100644 --- a/docs/docsite/rst/userguide/notification_parameters_supported.rst +++ b/docs/docsite/rst/userguide/notification_parameters_supported.rst @@ -13,7 +13,6 @@ This section describes the list of supported job attributes and the proper synta - ``allow_simultaneous`` - (boolean) indicates if multiple jobs can run simultaneously from the JT associated with this job - ``awx_node`` - (string) the instance that managed the isolated execution environment - ``created`` - (datetime) timestamp when this job was created -- ``custom_virtualenv`` - (string) custom virtual environment used to execute job - ``description`` - (string) optional description of the job - ``diff_mode`` - (boolean) if enabled, textual changes made to any templated files on the host are shown in the standard output - ``elapsed`` - (decimal) elapsed time in seconds that the job ran diff --git a/docs/execution_environments.md b/docs/execution_environments.md index 8056b953..c6dfa71d 100644 --- a/docs/execution_environments.md +++ b/docs/execution_environments.md @@ -47,18 +47,3 @@ Jobs will use the first available execution environment in this list: 7. Any other global EE If more than one EE fits a criteria (applies for 6 and 7), then the most recently created one will be used. - -## Migrating from Custom Virtual Environments - -If you have installed dependencies inside of custom virtual environments in -a prior release, then have a look at this series of commands for help migrating -dependencies out of the venvs and into EEs. - - - `awx-manage list_custom_venvs` - - `awx-manage custom_venv_associations` - - `awx-manage export_custom_venv` - -Follow those in order, and read the help text to see what arguments are necessary. - -Output from the `awx-manage export_custom_venv -q ..` command can -be a starting point for writing an `ansible-builder` definition file.