From 5c400cdf799642327b6795edabb90a29986de563 Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Tue, 12 Jun 2018 15:08:57 -0400 Subject: [PATCH] Add local minishift development tooling Based on mapping the local development tree through minishift hostfolder interface. --- tools/clusterdevel/bootstrap_minishift.sh | 36 +++++++ .../roles/minishift/tasks/main.yml | 85 +++++++++++++++ .../minishift/templates/configmap.yml.j2 | 102 ++++++++++++++++++ .../roles/minishift/templates/hostdev.yml.j2 | 78 ++++++++++++++ .../minishift/templates/hostfolderpvc.yml.j2 | 15 +++ .../minishift/templates/serviceacct.yml.j2 | 6 ++ .../minishift/templates/volumeclaim.yml.j2 | 15 +++ tools/clusterdevel/start_minishift_dev.yml | 11 ++ tools/docker-compose.yml | 2 +- 9 files changed, 349 insertions(+), 1 deletion(-) create mode 100755 tools/clusterdevel/bootstrap_minishift.sh create mode 100644 tools/clusterdevel/roles/minishift/tasks/main.yml create mode 100644 tools/clusterdevel/roles/minishift/templates/configmap.yml.j2 create mode 100644 tools/clusterdevel/roles/minishift/templates/hostdev.yml.j2 create mode 100644 tools/clusterdevel/roles/minishift/templates/hostfolderpvc.yml.j2 create mode 100644 tools/clusterdevel/roles/minishift/templates/serviceacct.yml.j2 create mode 100644 tools/clusterdevel/roles/minishift/templates/volumeclaim.yml.j2 create mode 100644 tools/clusterdevel/start_minishift_dev.yml diff --git a/tools/clusterdevel/bootstrap_minishift.sh b/tools/clusterdevel/bootstrap_minishift.sh new file mode 100755 index 0000000000..4b7265d852 --- /dev/null +++ b/tools/clusterdevel/bootstrap_minishift.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set +x + +# Wait for the databases to come up +ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=postgresql port=5432" all +ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=localhost port=11211" all +ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=localhost port=5672" all +ansible -i "127.0.0.1," -c local -v -m postgresql_db -U postgres -a "name=awx owner=awx login_user=awx login_password=awx login_host=postgresql" all + +# Move to the source directory so we can bootstrap +if [ -f "/awx_devel/manage.py" ]; then + cd /awx_devel +else + echo "Failed to find awx source tree, map your development tree volume" +fi + +#make awx-link +python setup.py develop +ln -s /awx_devel/tools/rdb.py /venv/awx/lib/python2.7/site-packages/rdb.py || true +yes | cp -rf /awx_devel/tools/docker-compose/supervisor.conf /supervisor.conf + +# AWX bootstrapping +make version_file +make migrate +make init + +mkdir -p /awx_devel/awx/public/static +mkdir -p /awx_devel/awx/ui/static + +cd /awx_devel +# Start the services +if [ -f "/awx_devel/tools/docker-compose/use_dev_supervisor.txt" ]; then + make supervisor +else + honcho start -f "tools/docker-compose/Procfile" +fi diff --git a/tools/clusterdevel/roles/minishift/tasks/main.yml b/tools/clusterdevel/roles/minishift/tasks/main.yml new file mode 100644 index 0000000000..70bca9b3c5 --- /dev/null +++ b/tools/clusterdevel/roles/minishift/tasks/main.yml @@ -0,0 +1,85 @@ +--- +- name: Apply admin user addon + shell: minishift addon apply admin-user + +- name: Attach AWX dev tree volume locally + shell: "minishift hostfolder add -t sshfs --source {{ devtree_directory }} --target /mnt/sda1/awx awx" + register: hostfolderadd + ignore_errors: yes + +- name: Fail if hostfolder add issue was something other than already attached + fail: msg="There was an issue attaching hostfolder '{{ hostfolderadd.stdout }}' '{{ hostfolderadd.stderr }}'" + when: hostfolderadd.rc != 0 and "there is already a host folder" not in hostfolderadd.stderr + +- name: Mount AWX dev volume + shell: minishift hostfolder mount awx + +- name: Authenticate with OpenShift via token + shell: "oc login -u admin -p admin" + +- name: Get Project Detail + shell: "oc get project {{ awx_dev_project }}" + register: project_details + ignore_errors: yes + +- name: Get Postgres Service Detail + shell: "oc describe svc postgresql -n {{ awx_dev_project }}" + register: postgres_svc_details + ignore_errors: yes + +- name: Create AWX Openshift Project + shell: "oc new-project {{ awx_dev_project }}" + when: project_details.rc != 0 + +- name: Stage serviceacct.yml + template: + src: serviceacct.yml.j2 + dest: /tmp/serviceacct.yml + +- name: Apply svc account + shell: "oc apply -f /tmp/serviceacct.yml ; rm -rf /tmp/serviceaccount.yml" + +- name: Stage hostfolderpvc.yml + template: + src: hostfolderpvc.yml.j2 + dest: /tmp/hostfolderpvc.yml + +- name: Create PV for host folder + shell: "oc apply -f /tmp/hostfolderpvc.yml ; rm -rf /tmp/hostfolderpvc.yml" + +- name: Stage volumeclaim.yml + template: + src: volumeclaim.yml.j2 + dest: /tmp/volumeclaim.yml + +- name: Create PV for host folder + shell: "oc apply -f /tmp/volumeclaim.yml ; rm -rf /tmp/volumeclaim.yml" + +- name: Create privileged user service account awx + shell: "oc adm policy add-scc-to-user privileged system:serviceaccount:{{ awx_dev_project }}:awx" + +- name: Deploy and Activate Postgres + shell: "oc new-app --template=postgresql-persistent -e MEMORY_LIMIT={{ pg_memory_limit|default('512') }}Mi -e NAMESPACE=openshift -e DATABASE_SERVICE_NAME=postgresql -e POSTGRESQL_USER={{ pg_username|default('awx') }} -e POSTGRESQL_PASSWORD={{ pg_password|default('awx') }} -e POSTGRESQL_DATABASE={{ pg_database|default('awx') }} -e VOLUME_CAPACITY={{ pg_volume_capacity|default('5')}}Gi -e POSTGRESQL_VERSION=9.5 -n {{ awx_dev_project }}" + when: postgres_svc_details is defined and postgres_svc_details.rc != 0 + register: openshift_pg_activate + +- name: Wait for Postgres to activate + pause: + seconds: 15 + when: openshift_pg_activate|changed + +- name: Template configmap + template: + src: configmap.yml.j2 + dest: "/tmp/configmap.yml" + +- name: Create configmap + shell: "oc apply -f /tmp/configmap.yml ; rm -rf /tmp/configmap.yml" + +- name: Template deployment + template: + src: hostdev.yml.j2 + dest: "/tmp/hostdev.yml" + +- name: Create deployment + shell: "oc apply -f /tmp/hostdev.yml ; rm -rf /tmp/hostdev.yml" diff --git a/tools/clusterdevel/roles/minishift/templates/configmap.yml.j2 b/tools/clusterdevel/roles/minishift/templates/configmap.yml.j2 new file mode 100644 index 0000000000..ce0c3c3866 --- /dev/null +++ b/tools/clusterdevel/roles/minishift/templates/configmap.yml.j2 @@ -0,0 +1,102 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: awx-dev-config + namespace: {{ awx_dev_project }} +data: + secret_key: isasekrit + awx_settings: | + import os + import socket + ADMINS = () + + # Container environments don't like chroots + AWX_PROOT_ENABLED = False + + # Automatically deprovision pods that go offline + AWX_AUTO_DEPROVISION_INSTANCES = True + + SYSTEM_TASK_ABS_CPU = {{ ((awx_task_cpu_request|int / 1000) * 4)|int }} + SYSTEM_TASK_ABS_MEM = {{ ((awx_task_mem_request|int * 1024) / 100)|int }} + + #Autoprovisioning should replace this + CLUSTER_HOST_ID = socket.gethostname() + SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' + + SESSION_COOKIE_SECURE = False + CSRF_COOKIE_SECURE = False + + REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR'] + + STATIC_ROOT = '/var/lib/awx/public/static' + PROJECTS_ROOT = '/var/lib/awx/projects' + JOBOUTPUT_ROOT = '/var/lib/awx/job_status' + SECRET_KEY = file('/etc/tower/SECRET_KEY', 'rb').read().strip() + ALLOWED_HOSTS = ['*'] + INTERNAL_API_URL = 'http://127.0.0.1:8052' + SERVER_EMAIL = 'root@localhost' + DEFAULT_FROM_EMAIL = 'webmaster@localhost' + EMAIL_SUBJECT_PREFIX = '[AWX] ' + EMAIL_HOST = 'localhost' + EMAIL_PORT = 25 + EMAIL_HOST_USER = '' + EMAIL_HOST_PASSWORD = '' + EMAIL_USE_TLS = False + + LOGGING['handlers']['console'] = { + '()': 'logging.StreamHandler', + 'level': 'DEBUG', + 'formatter': 'simple', + } + + LOGGING['loggers']['django.request']['handlers'] = ['console'] + LOGGING['loggers']['rest_framework.request']['handlers'] = ['console'] + LOGGING['loggers']['awx']['handlers'] = ['console'] + LOGGING['loggers']['awx.main.commands.run_callback_receiver']['handlers'] = ['console'] + LOGGING['loggers']['awx.main.commands.inventory_import']['handlers'] = ['console'] + LOGGING['loggers']['awx.main.tasks']['handlers'] = ['console'] + LOGGING['loggers']['awx.main.scheduler']['handlers'] = ['console'] + LOGGING['loggers']['django_auth_ldap']['handlers'] = ['console'] + LOGGING['loggers']['social']['handlers'] = ['console'] + LOGGING['loggers']['system_tracking_migrations']['handlers'] = ['console'] + LOGGING['loggers']['rbac_migrations']['handlers'] = ['console'] + LOGGING['loggers']['awx.isolated.manager.playbooks']['handlers'] = ['console'] + LOGGING['handlers']['callback_receiver'] = {'class': 'logging.NullHandler'} + LOGGING['handlers']['fact_receiver'] = {'class': 'logging.NullHandler'} + LOGGING['handlers']['task_system'] = {'class': 'logging.NullHandler'} + LOGGING['handlers']['tower_warnings'] = {'class': 'logging.NullHandler'} + LOGGING['handlers']['rbac_migrations'] = {'class': 'logging.NullHandler'} + LOGGING['handlers']['system_tracking_migrations'] = {'class': 'logging.NullHandler'} + LOGGING['handlers']['management_playbooks'] = {'class': 'logging.NullHandler'} + + DATABASES = { + 'default': { + 'ATOMIC_REQUESTS': True, + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': "awx", + 'USER': "awx", + 'PASSWORD': "awx", + 'HOST': "postgresql", + 'PORT': "5432", + } + } + BROKER_URL = 'amqp://{}:{}@{}:{}/{}'.format( + "awx", + "abcdefg", + "localhost", + "5672", + "awx") + CHANNEL_LAYERS = { + 'default': {'BACKEND': 'asgi_amqp.AMQPChannelLayer', + 'ROUTING': 'awx.main.routing.channel_routing', + 'CONFIG': {'url': BROKER_URL}} + } + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': '{}:{}'.format("localhost", "11211") + }, + 'ephemeral': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + }, + } diff --git a/tools/clusterdevel/roles/minishift/templates/hostdev.yml.j2 b/tools/clusterdevel/roles/minishift/templates/hostdev.yml.j2 new file mode 100644 index 0000000000..fdd4be936b --- /dev/null +++ b/tools/clusterdevel/roles/minishift/templates/hostdev.yml.j2 @@ -0,0 +1,78 @@ +--- +apiVersion: apps/v1beta1 # for versions before 1.9.0 use apps/v1beta2 +kind: Deployment +metadata: + name: awx + namespace: {{ awx_dev_project }} +spec: + replicas: 1 + template: + metadata: + labels: + name: awx + spec: + serviceAccountName: awx + containers: + - image: ansible/awx-dev:latest + name: awx + command: ["/awx_devel/tools/clusterdevel/bootstrap_minishift.sh"] + securityContext: + privileged: true + volumeMounts: + - name: localdev + mountPath: /awx_devel + - name: awx-application-config + mountPath: /etc/tower + - name: awx-rabbit + image: ansible/awx_rabbitmq:latest + imagePullPolicy: Always + env: + # For consupmption by rabbitmq-env.conf + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: RABBITMQ_USE_LONGNAME + value: "true" + - name: ERLANG_COOKIE + value: "test" + - name: RABBITMQ_ERLANG_COOKIE + value: "cookiemonster" + - name: RABBITMQ_NODENAME + value: "rabbit@$(MY_POD_IP)" + - name: AUTOCLUSTER_TYPE + value: "etcd" + - name: AUTOCLUSTER_DELAY + value: "60" + - name: ETCD_HOST + value: "etcd" + - name: AUTOCLUSTER_CLEANUP + value: "true" + - name: CLEANUP_WARN_ONLY + value: "false" + - name: CLEANUP_INTERVAL + value: "30" + - name: RABBITMQ_DEFAULT_USER + value: "awx" + - name: RABBITMQ_DEFAULT_PASS + value: "abcdefg" + - name: RABBITMQ_DEFAULT_VHOST + value: "awx" + - name: RABBITMQ_CONFIG_FILE + value: "/etc/rabbitmq/rabbitmq" + - name: awx-memcached + image: memcached + - name: postgres + image: postgres:9.6 + volumes: + - name: localdev + persistentVolumeClaim: + claimName: devtest + - name: awx-application-config + configMap: + name: awx-dev-config + items: + - key: awx_settings + path: settings.py + - key: secret_key + path: SECRET_KEY diff --git a/tools/clusterdevel/roles/minishift/templates/hostfolderpvc.yml.j2 b/tools/clusterdevel/roles/minishift/templates/hostfolderpvc.yml.j2 new file mode 100644 index 0000000000..2a04793717 --- /dev/null +++ b/tools/clusterdevel/roles/minishift/templates/hostfolderpvc.yml.j2 @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: projdata + namespace: {{ awx_dev_project }} + labels: + project: awx +spec: + capacity: + storage: 10Gi + accessModes: + - ReadWriteMany + persistentVolumeReclaimPolicy: Retain + hostPath: + path: /mnt/sda1/awx diff --git a/tools/clusterdevel/roles/minishift/templates/serviceacct.yml.j2 b/tools/clusterdevel/roles/minishift/templates/serviceacct.yml.j2 new file mode 100644 index 0000000000..7e335dd788 --- /dev/null +++ b/tools/clusterdevel/roles/minishift/templates/serviceacct.yml.j2 @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: awx + namespace: {{ awx_dev_project }} diff --git a/tools/clusterdevel/roles/minishift/templates/volumeclaim.yml.j2 b/tools/clusterdevel/roles/minishift/templates/volumeclaim.yml.j2 new file mode 100644 index 0000000000..a2fe3634f6 --- /dev/null +++ b/tools/clusterdevel/roles/minishift/templates/volumeclaim.yml.j2 @@ -0,0 +1,15 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: devtest + namespace: {{ awx_dev_project }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 10Gi + selector: + matchLabels: + project: awx diff --git a/tools/clusterdevel/start_minishift_dev.yml b/tools/clusterdevel/start_minishift_dev.yml new file mode 100644 index 0000000000..ae308a288e --- /dev/null +++ b/tools/clusterdevel/start_minishift_dev.yml @@ -0,0 +1,11 @@ +--- +- name: Setup minishift dev environment + hosts: localhost + gather_facts: false + vars: + - ansible_connection: local + - awx_dev_project: awx + - awx_task_cpu_request: 500 + - awx_task_mem_request: 512 + roles: + - { role: minishift } diff --git a/tools/docker-compose.yml b/tools/docker-compose.yml index 086507ce05..59adf5f0c6 100644 --- a/tools/docker-compose.yml +++ b/tools/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3' +version: '2' services: # Primary AWX Development Container awx: