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 7dafc59f..dc83d349 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..4d2eb7a1 100644 --- a/awx/api/templates/api/api_v2_config_view.md +++ b/awx/api/templates/api/api_v2_config_view.md @@ -11,8 +11,7 @@ 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 6a389b3c..e8a837d8 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', ] @@ -513,23 +510,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/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 b9f6ef7d..da27dfb3 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, @@ -4483,17 +4469,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 4c7bc00a..f5405e05 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_collection/plugins/modules/inventory_source.py b/awx_collection/plugins/modules/inventory_source.py index 5f6c1781..39713cb4 100644 --- a/awx_collection/plugins/modules/inventory_source.py +++ b/awx_collection/plugins/modules/inventory_source.py @@ -76,12 +76,7 @@ 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 +174,7 @@ 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 +271,7 @@ 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..fccb66b4 100644 --- a/awx_collection/plugins/modules/job_template.py +++ b/awx_collection/plugins/modules/job_template.py @@ -86,12 +86,7 @@ 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 +395,7 @@ 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 +533,7 @@ 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..3d4c343f 100644 --- a/awx_collection/plugins/modules/organization.py +++ b/awx_collection/plugins/modules/organization.py @@ -38,12 +38,7 @@ 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 +117,7 @@ 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 +136,7 @@ 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 +193,7 @@ 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..60c0129f 100644 --- a/awx_collection/plugins/modules/project.py +++ b/awx_collection/plugins/modules/project.py @@ -108,12 +108,7 @@ 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 +262,7 @@ 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'), @@ -369,7 +364,7 @@ def main(): 'scm_update_cache_timeout', 'timeout', 'scm_update_cache_timeout', - 'custom_virtualenv', + 'description', 'allow_override', ): 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.