diff --git a/awx/main/conf.py b/awx/main/conf.py index 7db0737acf..18f6e4026a 100644 --- a/awx/main/conf.py +++ b/awx/main/conf.py @@ -328,6 +328,16 @@ register( category_slug='jobs', ) +register( + 'AWX_COLLECTIONS_ENABLED', + field_class=fields.BooleanField, + default=True, + label=_('Enable Collection(s) Download'), + help_text=_('Allows collections to be dynamically downloaded from a requirements.yml file for SCM projects.'), + category=_('Jobs'), + category_slug='jobs', +) + register( 'STDOUT_MAX_BYTES_DISPLAY', field_class=fields.IntegerField, diff --git a/awx/main/tasks.py b/awx/main/tasks.py index bc47149dfb..b1308d8972 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -1475,6 +1475,8 @@ class RunJob(BaseTask): if authorize: env['ANSIBLE_NET_AUTH_PASS'] = network_cred.get_input('authorize_password', default='') + env['ANSIBLE_COLLECTIONS_PATHS'] = os.path.join(private_data_dir, 'requirements_collections') + return env def build_args(self, job, private_data_dir, passwords): @@ -1781,6 +1783,10 @@ class RunProjectUpdate(BaseTask): credential = project_update.credential if credential.has_input('ssh_key_data'): private_data['credentials'][credential] = credential.get_input('ssh_key_data', default='') + + # Create dir where collections will live for the job run + if project_update.job_type != 'check' and getattr(self, 'job_private_data_dir'): + os.mkdir(os.path.join(self.job_private_data_dir, 'requirements_collections'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC) return private_data def build_passwords(self, project_update, runtime_passwords): @@ -1893,8 +1899,11 @@ class RunProjectUpdate(BaseTask): 'scm_clean': project_update.scm_clean, 'scm_delete_on_update': project_update.scm_delete_on_update if project_update.job_type == 'check' else False, 'scm_full_checkout': True if project_update.job_type == 'run' else False, - 'roles_enabled': getattr(settings, 'AWX_ROLES_ENABLED', True) if project_update.job_type != 'check' else False + 'roles_enabled': getattr(settings, 'AWX_ROLES_ENABLED', True) if project_update.job_type != 'check' else False, + 'collections_enabled': getattr(settings, 'AWX_COLLECTIONS_ENABLED', True) if project_update.job_type != 'check' else False, }) + if project_update.job_type != 'check': + extra_vars['collections_destination'] = os.path.join(self.job_private_data_dir, 'requirements_collections') # apply custom refspec from user for PR refs and the like if project_update.scm_refspec: extra_vars['scm_refspec'] = project_update.scm_refspec diff --git a/awx/playbooks/project_update.yml b/awx/playbooks/project_update.yml index 8143955f96..9964fcc38a 100644 --- a/awx/playbooks/project_update.yml +++ b/awx/playbooks/project_update.yml @@ -135,3 +135,18 @@ when: roles_enabled|bool delegate_to: localhost + + - block: + # TODO: don't run this if ansible verison doens't support collections + - name: detect collections/requirements.yml + stat: path={{project_path|quote}}/collections/requirements.yml + register: doesCollectionRequirementsExist + + - name: fetch galaxy collections from collections/requirements.yml + command: ansible-galaxy collection install -r requirements.yml -p {{collections_destination|quote}} + args: + chdir: "{{project_path|quote}}/collections" + register: galaxy_collection_result + + when: collections_enabled|bool + delegate_to: localhost diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 0ea3dd6746..b9274c62f4 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -604,6 +604,11 @@ ALLOW_JINJA_IN_EXTRA_VARS = 'template' # Note: This setting may be overridden by database settings. AWX_ROLES_ENABLED = True +# Enable dynamically pulling collections from a requirement.yml file +# when updating SCM projects +# Note: This setting may be overridden by database settings. +AWX_COLLECTIONS_ENABLED = True + # Enable bubblewrap support for running jobs (playbook runs only). # Note: This setting may be overridden by database settings. AWX_PROOT_ENABLED = True