From 067beb90c991ee60783f074e08352ca12e739edb Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Tue, 29 Aug 2017 16:14:28 -0400 Subject: [PATCH] Add support for standalone docker install --- installer/image_build/files/nginx.conf | 2 +- installer/image_build/files/settings.py | 37 ++- installer/install.yml | 5 +- installer/inventory | 7 + installer/local_docker/tasks/main.yml | 210 ++++++++++++++++++ installer/openshift/tasks/main.yml | 20 +- .../openshift/templates/configmap.yml.j2 | 7 + 7 files changed, 281 insertions(+), 7 deletions(-) create mode 100644 installer/local_docker/tasks/main.yml diff --git a/installer/image_build/files/nginx.conf b/installer/image_build/files/nginx.conf index ddc41d0f94..f96b4a9316 100644 --- a/installer/image_build/files/nginx.conf +++ b/installer/image_build/files/nginx.conf @@ -1,4 +1,4 @@ -user awx; +#user awx; worker_processes 1; diff --git a/installer/image_build/files/settings.py b/installer/image_build/files/settings.py index 06d2dbcb1e..45454fcba2 100644 --- a/installer/image_build/files/settings.py +++ b/installer/image_build/files/settings.py @@ -2,6 +2,13 @@ import os + +def get_secret(): + if os.path.exists("/etc/tower/SECRET_KEY"): + return file('/etc/tower/SECRET_KEY', 'rb').read().strip() + return os.getenv("SECRET_KEY", "privateawx"), + + ADMINS = () STATIC_ROOT = '/var/lib/awx/public/static' @@ -10,14 +17,25 @@ PROJECTS_ROOT = '/var/lib/awx/projects' JOBOUTPUT_ROOT = '/var/lib/awx/job_status' -SECRET_KEY = file('/etc/tower/SECRET_KEY', 'rb').read().strip() +SECRET_KEY = get_secret() ALLOWED_HOSTS = ['*'] -INTERNAL_API_URL = 'http://127.0.0.1:80' +INTERNAL_API_URL = 'http://awxweb:8052' AWX_TASK_ENV['HOME'] = '/var/lib/awx' +# Container environments don't like chroots +AWX_PROOT_ENABLED = False + + +CLUSTER_HOST_ID = "awx" +SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' +CELERY_QUEUES += (Queue(CLUSTER_HOST_ID, Exchange(CLUSTER_HOST_ID), routing_key=CLUSTER_HOST_ID),) +CELERY_ROUTES['awx.main.tasks.cluster_node_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID} +CELERY_ROUTES['awx.main.tasks.purge_old_stdout_files'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID} + + ############################################################################### # EMAIL SETTINGS ############################################################################### @@ -32,6 +50,12 @@ 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'] @@ -39,11 +63,18 @@ LOGGING['loggers']['awx.main.commands.run_callback_receiver']['handlers'] = ['co 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']['awx.main.commands.run_fact_cache_receiver']['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': { diff --git a/installer/install.yml b/installer/install.yml index 0102cd98e7..0be29fc951 100644 --- a/installer/install.yml +++ b/installer/install.yml @@ -3,5 +3,6 @@ - hosts: all gather_facts: false roles: - - role: image_build - - role: openshift + - { role: image_build } + - { role: openshift, when: "openshift_host is defined" } + - { role: local_docker, when: "openshift_host is not defined" } diff --git a/installer/inventory b/installer/inventory index d9334a8d38..62d7a1e9d0 100644 --- a/installer/inventory +++ b/installer/inventory @@ -1,6 +1,9 @@ localhost ansible_connection=local [all:vars] + +awx_official=false + # Local Openshift # Will need to set -e openshift_password=developer -e docker_registry_password=$(oc whoami -t) # @@ -12,6 +15,10 @@ localhost ansible_connection=local # docker_registry_username=developer # awx_node_port=30083 +# Standalone Docker Install +# postgres_data_dir=/tmp/pgdocker +# host_port=80 + # Set this if you have an external postgres you are pointing at # otherwise a new ephemeral awx postgres service will be created # pg_hostname=postgresql diff --git a/installer/local_docker/tasks/main.yml b/installer/local_docker/tasks/main.yml new file mode 100644 index 0000000000..efe9750bdc --- /dev/null +++ b/installer/local_docker/tasks/main.yml @@ -0,0 +1,210 @@ +--- + +- name: Export Docker web image if it isnt local and there isnt a registry defined + docker_image: + name: "{{ awx_web_image }}" + tag: "{{ awx_version }}" + archive_path: "{{ awx_local_base_config_path|default('/tmp') }}/{{ awx_web_image }}_{{ awx_version }}.tar" + when: ansible_connection != "local" and docker_registry is not defined + delegate_to: localhost + +- name: Export Docker task image if it isnt local and there isnt a registry defined + docker_image: + name: "{{ awx_task_image }}" + tag: "{{ awx_version }}" + archive_path: "{{ awx_local_base_config_path|default('/tmp') }}/{{ awx_task_image }}_{{ awx_version }}.tar" + when: ansible_connection != "local" and docker_registry is not defined + delegate_to: localhost + +- name: Authenticate with Docker registry if registry password given + docker_login: + registry: "{{ docker_registry }}" + username: "{{ docker_registry_username }}" + password: "{{ docker_registry_password }}" + reauthorize: yes + when: docker_registry is defined and docker_registry_password is defined + delegate_to: localhost + +- name: Set docker base path + set_fact: + docker_deploy_base_path: "{{ awx_base_path|default('/tmp') }}/docker_deploy" + when: ansible_connection != "local" and docker_registry is not defined + +- name: Ensure directory exists + file: + path: "{{ docker_deploy_base_path }}" + state: directory + when: ansible_connection != "local" and docker_registry is not defined + +- name: Copy web image to docker execution + copy: + src: "{{ awx_local_base_config_path|default('/tmp') }}/{{ awx_web_image }}_{{ awx_version }}.tar" + dest: "{{ docker_deploy_base_path }}/{{ awx_web_image }}_{{ awx_version }}.tar" + when: ansible_connection != "local" and docker_registry is not defined + +- name: Copy task image to docker execution + copy: + src: "{{ awx_local_base_config_path|default('/tmp') }}/{{ awx_task_image }}_{{ awx_version }}.tar" + dest: "{{ docker_deploy_base_path }}" + when: ansible_connection != "local" and docker_registry is not defined + +- name: Load web image + docker_image: + name: "{{ awx_web_image }}" + tag: "{{ awx_version }}" + load_path: "{{ docker_deploy_base_path }}/{{ awx_web_image }}_{{ awx_version }}.tar" + when: ansible_connection != "local" and docker_registry is not defined + +- name: Load task image + docker_image: + name: "{{ awx_task_image }}" + tag: "{{ awx_version }}" + load_path: "{{ docker_deploy_base_path }}/{{ awx_task_image }}_{{ awx_version }}.tar" + when: ansible_connection != "local" and docker_registry is not defined + +- name: Tag and push web image to registry + docker_image: + name: "{{ awx_web_image }}" + repository: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ awx_web_image }}" + tag: "{{ awx_version }}" + push: yes + when: docker_registry is defined + delegate_to: localhost + +- name: Tag and push task image to registry + docker_image: + name: "{{ awx_task_image }}" + repository: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ awx_task_image }}" + tag: "{{ awx_version }}" + push: yes + when: docker_registry is defined + delegate_to: localhost + +- name: Set full image path for Registry + set_fact: + awx_web_docker_actual_image: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ awx_web_image }}" + awx_task_docker_actual_image: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ awx_task_image }}" + when: docker_registry is defined + +- name: Set full image path for local install + set_fact: + awx_web_docker_actual_image: "{{ awx_web_image }}" + awx_task_docker_actual_image: "{{ awx_task_image }}" + when: docker_registry is not defined + +## Docker-compose instead? + +- name: Activate postgres container + docker_container: + name: postgres + state: started + image: postgres:9.6 + volumes: + - "{{ postgres_data_dir }}:/var/lib/postgresql/data" + env: + POSTGRES_USER: "{{ pg_username }}" + POSTGRES_PASSWORD: "{{ pg_password }}" + POSTGRES_DB: "{{ pg_database }}" + when: pg_hostname is not defined or pg_hostname == '' + +- name: Activate rabbitmq container + docker_container: + name: rabbitmq + state: started + image: rabbitmq:3 + env: + RABBITMQ_DEFAULT_VHOST: "awx" + +- name: Activate memcached container + docker_container: + name: memcached + state: started + image: memcached:alpine + +- name: Wait for postgres and rabbitmq to activate + pause: + seconds: 15 + +- name: Set properties without postgres for awx_web + set_fact: + pg_hostname_actual: "{{ pg_hostname }}" + awx_web_container_links: + - rabbitmq + - memcached + when: pg_hostname is defined + +- name: Set properties with postgres for awx_web + set_fact: + pg_hostname_actual: postgres + awx_web_container_links: + - rabbitmq + - memcached + - postgres + when: pg_hostname is not defined or pg_hostname == '' + +- name: Set properties without postgres for awx_task + set_fact: + pg_hostname_actual: "{{ pg_hostname }}" + awx_task_container_links: + - rabbitmq + - memcached + - awx_web + when: pg_hostname is defined + +- name: Set properties with postgres for awx_web + set_fact: + pg_hostname_actual: postgres + awx_task_container_links: + - rabbitmq + - memcached + - awx_web + - postgres + when: pg_hostname is not defined or pg_hostname == '' + +- name: Activate AWX Web Container + docker_container: + name: awx_web + state: started + image: "{{ awx_web_docker_actual_image }}:{{ awx_version }}" + user: root + ports: + - "{{ host_port }}:8052" + links: "{{ awx_web_container_links|list }}" + hostname: awxweb + env: + SECRET_KEY: "{{ awx_secret_key }}" + DATABASE_NAME: "{{ pg_database }}" + DATABASE_USER: "{{ pg_username }}" + DATABASE_PASSWORD: "{{ pg_password }}" + DATABASE_PORT: "{{ pg_port }}" + DATABASE_HOST: "{{ pg_hostname_actual }}" + RABBITMQ_USER: "guest" + RABBITMQ_PASSWORD: "guest" + RABBITMQ_HOST: "rabbitmq" + RABBITMQ_PORT: "5672" + RABBITMQ_VHOST: "awx" + MEMCACHED_HOST: "memcached" + MEMCACHED_PORT: "11211" + +- name: Activate AWX Task Container + docker_container: + name: awx_task + state: started + image: "{{ awx_task_docker_actual_image }}:{{ awx_version }}" + links: "{{ awx_task_container_links|list }}" + user: root + hostname: awx + env: + SECRET_KEY: "{{ awx_secret_key }}" + DATABASE_NAME: "{{ pg_database }}" + DATABASE_USER: "{{ pg_username }}" + DATABASE_PASSWORD: "{{ pg_password }}" + DATABASE_HOST: "{{ pg_hostname_actual }}" + DATABASE_PORT: "{{ pg_port }}" + RABBITMQ_USER: "guest" + RABBITMQ_PASSWORD: "guest" + RABBITMQ_HOST: "rabbitmq" + RABBITMQ_PORT: "5672" + RABBITMQ_VHOST: "awx" + MEMCACHED_HOST: "memcached" + MEMCACHED_PORT: "11211" diff --git a/installer/openshift/tasks/main.yml b/installer/openshift/tasks/main.yml index 2e9eeac442..e7b063f8c9 100644 --- a/installer/openshift/tasks/main.yml +++ b/installer/openshift/tasks/main.yml @@ -21,15 +21,29 @@ - name: Mark Openshift User as Admin shell: "oc adm policy add-role-to-user admin {{ openshift_user }} -n {{ awx_openshift_project }}" +- name: Get docker registry password from oc if needed + block: + - name: Set docker registry password + shell: oc whoami -t + register: docker_registry_password_shell + - name: Set docker registry password + set_fact: + docker_registry_password: "{{ docker_registry_password_shell.stdout }}" + when: docker_registry_password is not defined + - name: Authenticate with Docker registry docker_login: registry: "{{ docker_registry }}" username: "{{ docker_registry_username }}" password: "{{ docker_registry_password }}" reauthorize: yes - when: docker_registry is defined + when: docker_registry is defined and docker_registry_password is defined delegate_to: localhost +- name: Wait for Openshift + pause: + seconds: 30 + - name: Tag and push web image to registry docker_image: name: "{{ awx_web_image }}" @@ -39,6 +53,10 @@ when: docker_registry is defined delegate_to: localhost +- name: Wait for openshift + pause: + seconds: 10 + - name: Tag and push task image to registry docker_image: name: "{{ awx_task_image }}" diff --git a/installer/openshift/templates/configmap.yml.j2 b/installer/openshift/templates/configmap.yml.j2 index da91d9e706..0ef1fd3008 100644 --- a/installer/openshift/templates/configmap.yml.j2 +++ b/installer/openshift/templates/configmap.yml.j2 @@ -35,6 +35,13 @@ data: 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']