From 036e1ad82edc0e01706b4e91978501bef7000c8c Mon Sep 17 00:00:00 2001 From: Ashley Nelson Date: Wed, 3 Jul 2019 09:35:11 -0500 Subject: [PATCH] Add dynamic custom venv setup Add support for python3 venvs --- docs/custom_virtualenvs.md | 74 +++++++++---------- installer/roles/kubernetes/defaults/main.yml | 3 + .../kubernetes/templates/deployment.yml.j2 | 41 ++++++++++ 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/docs/custom_virtualenvs.md b/docs/custom_virtualenvs.md index 32c946c8267d..f1dfb90932e6 100644 --- a/docs/custom_virtualenvs.md +++ b/docs/custom_virtualenvs.md @@ -98,48 +98,42 @@ Once the AWX API is available, update the `CUSTOM_VENV_PATHS` setting as describ Kubernetes Custom Virtualenvs ============================= +You can add custom virtual environments without modifying images by including +the following variables in your `install.yml` playbook run. Your variables file +must have a variable called `custom_venvs` with a list of your custom +virtualenvs containing the name, python interpreter, ansible version, and a list +of modules that should be installed in each one: + +```yaml +# venv_vars.yaml +--- +custom_venvs: + - name: dns_team + python: python3 # Defaults to python2 + python_ansible_version: 2.8.1 + python_modules: + - dnspython + - infoblox-client + - name: windows_team + python: python2 + python_ansible_version: 2.8.0 + python_modules: + - winrm + - name: vmware_team + python_ansible_version: 2.7.10 + python_modules: + - pyvmomi +``` -You can create custom virtualenvs without updating the awx images by using initContainers and a shared emptydir within Kubernetes. To start create an emptydir volume in the volumes stanza. - - volumes: - - emptyDir: {} - name: custom-venv - -Now create an initContainer stanza. You can subsititute your own custom images for this example we are using centos:7 as the base to build upon. The command stanza is where you will add the python modules you require in your virtualenv. - - initContainers: - - image: 'centos:7' - name: init-custom-venv - command: - - sh - - '-c' - - >- - yum install -y ansible python-pip curl python-setuptools epel-release openssl openssl-devel gcc python-devel && - curl 'https://bootstrap.pypa.io/get-pip.py' | python && - pip install virtualenv && - mkdir -p /opt/my-envs && - virtualenv /opt/my-envs/custom-venv && - source /opt/my-envs/custom-venv/bin/activate && - /opt/my-envs/custom-venv/bin/pip install psutil && - /opt/my-envs/custom-venv/bin/pip install -U "ansible == X.Y.Z" && - /opt/my-envs/custom-venv/bin/pip install -U custom-python-module - volumeMounts: - - mountPath: /opt/my-envs/custom-venv - name: custom-venv - -Finally in the awx-celery and awx-web containers stanza add the shared volume as a mount. - - volumeMounts: - - mountPath: /opt/my-envs/custom-venv - name: custom-venv - - mountPath: /etc/tower - name: awx-application-config - readOnly: true - - mountPath: /etc/tower/conf.d - name: awx-confd - readOnly: true +The virtualenvs will be created in `/opt/custom-venvs` by default, but you can +override that location by setting the variable `custom_venvs_path`. -Once the AWX API is available, update the `CUSTOM_VENV_PATHS` setting as described in `Preparing a New Custom Virtualenv`. +You can use the variables file like so: + + $ ansible-playbook install.yml --extra-vars "@venv_vars.yaml" + +Once the AWX API is available, you will need to update the `CUSTOM_VENV_PATHS` +setting as described in `Preparing a New Custom Virtualenv`. Assigning Custom Virtualenvs ============================ diff --git a/installer/roles/kubernetes/defaults/main.yml b/installer/roles/kubernetes/defaults/main.yml index b4467cc4bbd0..3961bf1622af 100644 --- a/installer/roles/kubernetes/defaults/main.yml +++ b/installer/roles/kubernetes/defaults/main.yml @@ -46,3 +46,6 @@ kubernetes_deployment_replica_size: 1 postgress_activate_wait: 60 insights_url_base: "https://example.org" + +custom_venvs_path: "/opt/custom-venvs" +custom_venvs_python: "python2" diff --git a/installer/roles/kubernetes/templates/deployment.yml.j2 b/installer/roles/kubernetes/templates/deployment.yml.j2 index 1fe50ca0ecd5..fb75bc9d149e 100644 --- a/installer/roles/kubernetes/templates/deployment.yml.j2 +++ b/installer/roles/kubernetes/templates/deployment.yml.j2 @@ -134,6 +134,35 @@ spec: spec: serviceAccountName: awx terminationGracePeriodSeconds: 10 +{% if custom_venvs is defined %} + initContainers: + - image: 'centos:7' + name: init-custom-venvs + command: + - sh + - '-c' + - >- + yum install -y ansible curl python-setuptools epel-release \ + openssl openssl-devel gcc python-devel && + yum install -y python-virtualenv python36 python36-devel && + mkdir -p {{ custom_venvs_path }} && +{% for custom_venv in custom_venvs %} + virtualenv -p {{ custom_venv.python | default(custom_venvs_python) }} \ + {{ custom_venvs_path }}/{{ custom_venv.name }} && + source {{ custom_venvs_path }}/{{ custom_venv.name }}/bin/activate && + {{ custom_venvs_path }}/{{ custom_venv.name }}/bin/pip install -U psutil \ + "ansible=={{ custom_venv.python_ansible_version }}" && +{% if custom_venv.python_modules is defined %} + {{ custom_venvs_path }}/{{ custom_venv.name }}/bin/pip install -U \ + {% for module in custom_venv.python_modules %}{{ module }} {% endfor %} && +{% endif %} + deactivate && +{% endfor %} + : + volumeMounts: + - name: custom-venvs + mountPath: {{ custom_venvs_path }} +{% endif %} containers: - name: {{ kubernetes_deployment_name }}-web image: "{{ kubernetes_web_image }}:{{ kubernetes_web_version }}" @@ -150,6 +179,10 @@ spec: - name: {{ kubernetes_deployment_name }}-project-data-dir mountPath: "/var/lib/awx/projects" readOnly: false +{% endif %} +{% if custom_venvs is defined %} + - name: custom-venvs + mountPath: {{ custom_venvs_path }} {% endif %} - name: {{ kubernetes_deployment_name }}-application-config mountPath: "/etc/tower/settings.py" @@ -190,6 +223,10 @@ spec: - name: {{ kubernetes_deployment_name }}-ca-trust-dir mountPath: "/etc/pki/ca-trust/source/anchors/" readOnly: true +{% endif %} +{% if custom_venvs is defined %} + - name: custom-venvs + mountPath: {{ custom_venvs_path }} {% endif %} - name: {{ kubernetes_deployment_name }}-application-config mountPath: "/etc/tower/settings.py" @@ -300,6 +337,10 @@ spec: hostPath: path: "{{ project_data_dir }}" type: Directory +{% endif %} +{% if custom_venvs is defined %} + - name: custom-venvs + emptyDir: {} {% endif %} - name: {{ kubernetes_deployment_name }}-application-config configMap: