From 89e41597a6774af250bbc1d69fb409d4965920ad Mon Sep 17 00:00:00 2001 From: Hao Liu Date: Thu, 23 Feb 2023 10:46:48 -0500 Subject: [PATCH 1/4] switch from head to tail from @relrod `head` will close the input fd when it no longer needs it (or exits). find will try to write to the closed fd and somewhere along the way, it will receive SIGPIPE as a result. This is why `yes | head -5 ` doesn't run forever. --- awx/playbooks/project_update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/playbooks/project_update.yml b/awx/playbooks/project_update.yml index 7334547f97..125b5ef312 100644 --- a/awx/playbooks/project_update.yml +++ b/awx/playbooks/project_update.yml @@ -26,7 +26,7 @@ name: Update source tree if necessary tasks: - name: Delete project directory before update - ansible.builtin.shell: set -o pipefail && find . -delete -print | head -2 # volume mounted, cannot delete folder itself + ansible.builtin.shell: set -o pipefail && find . -delete -print | tail -2 # volume mounted, cannot delete folder itself register: reg changed_when: reg.stdout_lines | length > 1 args: From 5e28f5dca162ec01d6fd32207404f66fa2276604 Mon Sep 17 00:00:00 2001 From: Alexander Pavlov Date: Tue, 17 May 2022 12:07:21 +0300 Subject: [PATCH 2/4] Remove trailing $ from websocket_urlpatterns to work with custom path to fix #12241 Signed-off-by: Alexander Pavlov --- awx/main/routing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/main/routing.py b/awx/main/routing.py index 100347f64e..c96505b7e1 100644 --- a/awx/main/routing.py +++ b/awx/main/routing.py @@ -27,8 +27,8 @@ class AWXProtocolTypeRouter(ProtocolTypeRouter): websocket_urlpatterns = [ - re_path(r'websocket/$', consumers.EventConsumer.as_asgi()), - re_path(r'websocket/broadcast/$', consumers.BroadcastConsumer.as_asgi()), + re_path(r'websocket/', consumers.EventConsumer.as_asgi()), + re_path(r'websocket/broadcast/', consumers.BroadcastConsumer.as_asgi()), ] application = AWXProtocolTypeRouter( From 2fca07ee4c4327fae715c6910d468d2834eb6b54 Mon Sep 17 00:00:00 2001 From: Shane McDonald Date: Thu, 23 Feb 2023 12:21:02 -0500 Subject: [PATCH 3/4] Allow serving app from non-root path in dev env Usage: $ EXTRA_SOURCES_ANSIBLE_OPTS='-e ingress_path=/awx' make docker-compose $ curl http://localhost:8013/awx/api/v2/ping/ --- Makefile | 14 +- .../roles/dockerfile/templates/Dockerfile.j2 | 5 +- .../dockerfile/templates/supervisor.conf.j2 | 2 +- .../ansible/roles/sources/defaults/main.yml | 1 + .../ansible/roles/sources/tasks/main.yml | 13 +- .../sources/templates/docker-compose.yml.j2 | 3 + .../local_settings.py.j2} | 2 + .../roles/sources/templates/nginx.conf.j2 | 108 +++++---------- .../sources/templates/nginx.locations.conf.j2 | 37 ++++++ tools/docker-compose/nginx.conf | 31 ----- tools/docker-compose/nginx.vh.default.conf | 124 ------------------ 11 files changed, 81 insertions(+), 259 deletions(-) rename tools/docker-compose/ansible/roles/sources/{files/local_settings.py => templates/local_settings.py.j2} (96%) create mode 100644 tools/docker-compose/ansible/roles/sources/templates/nginx.locations.conf.j2 delete mode 100644 tools/docker-compose/nginx.conf delete mode 100644 tools/docker-compose/nginx.vh.default.conf diff --git a/Makefile b/Makefile index 896dcf2c6c..4e402125b2 100644 --- a/Makefile +++ b/Makefile @@ -203,19 +203,7 @@ uwsgi: collectstatic @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/awx/bin/activate; \ fi; \ - uwsgi -b 32768 \ - --socket 127.0.0.1:8050 \ - --module=awx.wsgi:application \ - --home=/var/lib/awx/venv/awx \ - --chdir=/awx_devel/ \ - --vacuum \ - --processes=5 \ - --harakiri=120 --master \ - --no-orphans \ - --max-requests=1000 \ - --stats /tmp/stats.socket \ - --lazy-apps \ - --logformat "%(addr) %(method) %(uri) - %(proto) %(status)" + uwsgi /etc/tower/uwsgi.ini awx-autoreload: @/awx_devel/tools/docker-compose/awx-autoreload /awx_devel/awx "$(DEV_RELOAD_COMMAND)" diff --git a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 index 166f24b79f..e35234f622 100644 --- a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 +++ b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 @@ -199,11 +199,11 @@ ADD tools/ansible/roles/dockerfile/files/rsyslog.conf /var/lib/awx/rsyslog/rsysl ADD tools/ansible/roles/dockerfile/files/wait-for-migrations /usr/local/bin/wait-for-migrations ADD tools/ansible/roles/dockerfile/files/stop-supervisor /usr/local/bin/stop-supervisor +ADD tools/ansible/roles/dockerfile/files/uwsgi.ini /etc/tower/uwsgi.ini + ## File mappings {% if build_dev|bool %} ADD tools/docker-compose/launch_awx.sh /usr/bin/launch_awx.sh -ADD tools/docker-compose/nginx.conf /etc/nginx/nginx.conf -ADD tools/docker-compose/nginx.vh.default.conf /etc/nginx/conf.d/nginx.vh.default.conf ADD tools/docker-compose/start_tests.sh /start_tests.sh ADD tools/docker-compose/bootstrap_development.sh /usr/bin/bootstrap_development.sh ADD tools/docker-compose/entrypoint.sh /entrypoint.sh @@ -213,7 +213,6 @@ ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanima {% else %} ADD tools/ansible/roles/dockerfile/files/launch_awx.sh /usr/bin/launch_awx.sh ADD tools/ansible/roles/dockerfile/files/launch_awx_task.sh /usr/bin/launch_awx_task.sh -ADD tools/ansible/roles/dockerfile/files/uwsgi.ini /etc/tower/uwsgi.ini ADD {{ template_dest }}/supervisor.conf /etc/supervisord.conf ADD {{ template_dest }}/supervisor_task.conf /etc/supervisord_task.conf {% endif %} diff --git a/tools/ansible/roles/dockerfile/templates/supervisor.conf.j2 b/tools/ansible/roles/dockerfile/templates/supervisor.conf.j2 index e67b79fbe9..6cd821b9d0 100644 --- a/tools/ansible/roles/dockerfile/templates/supervisor.conf.j2 +++ b/tools/ansible/roles/dockerfile/templates/supervisor.conf.j2 @@ -30,8 +30,8 @@ environment = DEV_RELOAD_COMMAND='supervisorctl -c /etc/supervisord_task.conf restart all; supervisorctl restart tower-processes:daphne tower-processes:wsbroadcast' {% else %} command = /var/lib/awx/venv/awx/bin/uwsgi /etc/tower/uwsgi.ini -directory = /var/lib/awx {% endif %} +directory = /var/lib/awx autorestart = true startsecs = 30 stopasgroup=true diff --git a/tools/docker-compose/ansible/roles/sources/defaults/main.yml b/tools/docker-compose/ansible/roles/sources/defaults/main.yml index 9155cacfa9..cf5a65e0b6 100644 --- a/tools/docker-compose/ansible/roles/sources/defaults/main.yml +++ b/tools/docker-compose/ansible/roles/sources/defaults/main.yml @@ -9,6 +9,7 @@ control_plane_node_count: 1 minikube_container_group: false receptor_socket_file: /var/run/awx-receptor/receptor.sock receptor_image: quay.io/ansible/receptor:devel +ingress_path: / # Keys for signing work receptor_rsa_bits: 4096 diff --git a/tools/docker-compose/ansible/roles/sources/tasks/main.yml b/tools/docker-compose/ansible/roles/sources/tasks/main.yml index 5149364dd7..17ab4dc0c9 100644 --- a/tools/docker-compose/ansible/roles/sources/tasks/main.yml +++ b/tools/docker-compose/ansible/roles/sources/tasks/main.yml @@ -49,18 +49,11 @@ mode: '0600' with_items: - "database.py" + - "local_settings.py" - "websocket_secret.py" - "haproxy.cfg" - -- name: Delete old local_settings.py - file: - path: "{{ playbook_dir }}/../../../awx/settings/local_settings.py" - state: absent - -- name: Copy local_settings.py - copy: - src: "local_settings.py" - dest: "{{ sources_dest }}/local_settings.py" + - "nginx.conf" + - "nginx.locations.conf" - name: Get OS info for sdb shell: | diff --git a/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 b/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 index 60d5d44fb8..7badd37181 100644 --- a/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 +++ b/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 @@ -24,6 +24,7 @@ services: EXECUTION_NODE_COUNT: {{ execution_node_count|int }} AWX_LOGGING_MODE: stdout DJANGO_SUPERUSER_PASSWORD: {{ admin_password }} + UWSGI_MOUNT_PATH: {{ ingress_path }} {% if loop.index == 1 %} RUN_MIGRATIONS: 1 {% endif %} @@ -40,6 +41,8 @@ services: - "../../docker-compose/_sources/database.py:/etc/tower/conf.d/database.py" - "../../docker-compose/_sources/websocket_secret.py:/etc/tower/conf.d/websocket_secret.py" - "../../docker-compose/_sources/local_settings.py:/etc/tower/conf.d/local_settings.py" + - "../../docker-compose/_sources/nginx.conf:/etc/nginx/nginx.conf" + - "../../docker-compose/_sources/nginx.locations.conf:/etc/nginx/conf.d/nginx.locations.conf" - "../../docker-compose/_sources/SECRET_KEY:/etc/tower/SECRET_KEY" - "../../docker-compose/_sources/receptor/receptor-awx-{{ loop.index }}.conf:/etc/receptor/receptor.conf" - "../../docker-compose/_sources/receptor/receptor-awx-{{ loop.index }}.conf.lock:/etc/receptor/receptor.conf.lock" diff --git a/tools/docker-compose/ansible/roles/sources/files/local_settings.py b/tools/docker-compose/ansible/roles/sources/templates/local_settings.py.j2 similarity index 96% rename from tools/docker-compose/ansible/roles/sources/files/local_settings.py rename to tools/docker-compose/ansible/roles/sources/templates/local_settings.py.j2 index 552850e81c..0b4ffd0160 100644 --- a/tools/docker-compose/ansible/roles/sources/files/local_settings.py +++ b/tools/docker-compose/ansible/roles/sources/templates/local_settings.py.j2 @@ -46,3 +46,5 @@ SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' BROADCAST_WEBSOCKET_PORT = 8013 BROADCAST_WEBSOCKET_VERIFY_CERT = False BROADCAST_WEBSOCKET_PROTOCOL = 'http' + +STATIC_URL = '{{ (ingress_path + '/static/').replace('//', '/') }}' diff --git a/tools/docker-compose/ansible/roles/sources/templates/nginx.conf.j2 b/tools/docker-compose/ansible/roles/sources/templates/nginx.conf.j2 index 327b59a2fe..ff7e2ab386 100644 --- a/tools/docker-compose/ansible/roles/sources/templates/nginx.conf.j2 +++ b/tools/docker-compose/ansible/roles/sources/templates/nginx.conf.j2 @@ -1,8 +1,7 @@ -#user awx; - worker_processes 1; -pid /tmp/nginx.pid; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; events { worker_connections 1024; @@ -17,7 +16,7 @@ http { '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /dev/stdout main; + access_log /var/log/nginx/access.log main; map $http_upgrade $connection_upgrade { default upgrade; @@ -25,41 +24,17 @@ http { } sendfile on; - #tcp_nopush on; - #gzip on; upstream uwsgi { - server 127.0.0.1:8050; - } + server localhost:8050; + } upstream daphne { - server 127.0.0.1:8051; + server localhost:8051; } - {% if ssl_certificate is defined %} server { - listen 8052 default_server; - server_name _; - - # Redirect all HTTP links to the matching HTTPS page - return 301 https://$host$request_uri; - } - {%endif %} - - server { - {% if (ssl_certificate is defined) and (ssl_certificate_key is defined) %} - listen 8053 ssl; - - ssl_certificate /etc/nginx/awxweb.pem; - ssl_certificate_key /etc/nginx/awxweb_key.pem; - {% elif (ssl_certificate is defined) and (ssl_certificate_key is not defined) %} - listen 8053 ssl; - - ssl_certificate /etc/nginx/awxweb.pem; - ssl_certificate_key /etc/nginx/awxweb.pem; - {% else %} - listen 8052 default_server; - {% endif %} + listen 8013 default_server; # If you have a domain name, this is where to add it server_name _; @@ -67,56 +42,35 @@ http { # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; + add_header X-Content-Type-Options nosniff; - # Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009) - add_header X-Frame-Options "DENY"; + include /etc/nginx/conf.d/*.conf; + } - location /nginx_status { - stub_status on; - access_log off; - allow 127.0.0.1; - deny all; - } + server { + listen 8043 default_server ssl; - location /static/ { - alias /var/lib/awx/public/static/; - } + # If you have a domain name, this is where to add it + server_name _; + keepalive_timeout 65; - location /favicon.ico { alias /var/lib/awx/public/static/favicon.ico; } + ssl_certificate /etc/nginx/nginx.crt; + ssl_certificate_key /etc/nginx/nginx.key; - location /websocket { - # Pass request to the upstream alias - proxy_pass http://daphne; - # Require http version 1.1 to allow for upgrade requests - proxy_http_version 1.1; - # We want proxy_buffering off for proxying to websockets. - proxy_buffering off; - # http://en.wikipedia.org/wiki/X-Forwarded-For - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # enable this if you use HTTPS: - proxy_set_header X-Forwarded-Proto https; - # pass the Host: header from the client for the sake of redirects - proxy_set_header Host $http_host; - # We've set the Host header, so we don't need Nginx to muddle - # about with redirects - proxy_redirect off; - # Depending on the request value, set the Upgrade and - # connection headers - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:50m; + ssl_session_tickets off; - location / { - # Add trailing / if missing - rewrite ^(.*)$http_host(.*[^/])$ $1$http_host$2/ permanent; - uwsgi_read_timeout 120s; - uwsgi_pass uwsgi; - include /etc/nginx/uwsgi_params; - {%- if extra_nginx_include is defined %} - include {{ extra_nginx_include }}; - {%- endif %} - proxy_set_header X-Forwarded-Port 443; - uwsgi_param HTTP_X_FORWARDED_PORT 443; - } + # intermediate configuration. tweak to your needs. + ssl_protocols TLSv1.2; + ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; + ssl_prefer_server_ciphers on; + + # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) + add_header Strict-Transport-Security max-age=15768000; + add_header X-Content-Type-Options nosniff; + + + include /etc/nginx/conf.d/*.conf; } } diff --git a/tools/docker-compose/ansible/roles/sources/templates/nginx.locations.conf.j2 b/tools/docker-compose/ansible/roles/sources/templates/nginx.locations.conf.j2 new file mode 100644 index 0000000000..5d1d24b2b1 --- /dev/null +++ b/tools/docker-compose/ansible/roles/sources/templates/nginx.locations.conf.j2 @@ -0,0 +1,37 @@ +location {{ (ingress_path + '/static').replace('//', '/') }} { + alias /var/lib/awx/public/static/; +} + +location {{ (ingress_path + '/favicon.ico').replace('//', '/') }} { + alias /awx_devel/awx/public/static/favicon.ico; +} + +location {{ (ingress_path + '/websocket').replace('//', '/') }} { + # Pass request to the upstream alias + proxy_pass http://daphne; + # Require http version 1.1 to allow for upgrade requests + proxy_http_version 1.1; + # We want proxy_buffering off for proxying to websockets. + proxy_buffering off; + # http://en.wikipedia.org/wiki/X-Forwarded-For + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # enable this if you use HTTPS: + proxy_set_header X-Forwarded-Proto https; + # pass the Host: header from the client for the sake of redirects + proxy_set_header Host $http_host; + # We've set the Host header, so we don't need Nginx to muddle + # about with redirects + proxy_redirect off; + # Depending on the request value, set the Upgrade and + # connection headers + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; +} + +location {{ ingress_path }} { + # Add trailing / if missing + rewrite ^(.*[^/])$ $1/ permanent; + uwsgi_read_timeout 120s; + uwsgi_pass uwsgi; + include /etc/nginx/uwsgi_params; +} diff --git a/tools/docker-compose/nginx.conf b/tools/docker-compose/nginx.conf deleted file mode 100644 index 348f93b727..0000000000 --- a/tools/docker-compose/nginx.conf +++ /dev/null @@ -1,31 +0,0 @@ -worker_processes 1; - -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; - -events { - worker_connections 1024; -} - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - server_tokens off; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - map $http_upgrade $connection_upgrade { - default upgrade; - '' close; - } - - sendfile on; - #tcp_nopush on; - #gzip on; - - include /etc/nginx/conf.d/*.conf; -} diff --git a/tools/docker-compose/nginx.vh.default.conf b/tools/docker-compose/nginx.vh.default.conf deleted file mode 100644 index 649575af34..0000000000 --- a/tools/docker-compose/nginx.vh.default.conf +++ /dev/null @@ -1,124 +0,0 @@ -upstream uwsgi { - server localhost:8050; -} - -upstream daphne { - server localhost:8051; -} - -# server { -# listen 8013 default_server; -# listen [::]:8013 default_server; -# server_name _; -# return 301 https://$host:8043$request_uri; -# } - -server { - listen 8013 default_server; - - # If you have a domain name, this is where to add it - server_name _; - keepalive_timeout 65; - - # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) - add_header Strict-Transport-Security max-age=15768000; - add_header X-Content-Type-Options nosniff; - - location /static/ { - alias /var/lib/awx/public/static/; - } - - location /favicon.ico { alias /awx_devel/awx/public/static/favicon.ico; } - - location ~ ^/websocket { - # Pass request to the upstream alias - proxy_pass http://daphne; - # Require http version 1.1 to allow for upgrade requests - proxy_http_version 1.1; - # We want proxy_buffering off for proxying to websockets. - proxy_buffering off; - # http://en.wikipedia.org/wiki/X-Forwarded-For - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # enable this if you use HTTPS: - proxy_set_header X-Forwarded-Proto https; - # pass the Host: header from the client for the sake of redirects - proxy_set_header Host $http_host; - # We've set the Host header, so we don't need Nginx to muddle - # about with redirects - proxy_redirect off; - # Depending on the request value, set the Upgrade and - # connection headers - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - - location / { - # Add trailing / if missing - rewrite ^(.*[^/])$ $1/ permanent; - uwsgi_read_timeout 120s; - uwsgi_pass uwsgi; - include /etc/nginx/uwsgi_params; - } -} - -server { - listen 8043 default_server ssl; - - # If you have a domain name, this is where to add it - server_name _; - keepalive_timeout 65; - - ssl_certificate /etc/nginx/nginx.crt; - ssl_certificate_key /etc/nginx/nginx.key; - - ssl_session_timeout 1d; - ssl_session_cache shared:SSL:50m; - ssl_session_tickets off; - - # intermediate configuration. tweak to your needs. - ssl_protocols TLSv1.2; - ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; - ssl_prefer_server_ciphers on; - - # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) - add_header Strict-Transport-Security max-age=15768000; - add_header X-Content-Type-Options nosniff; - - location /static/ { - alias /var/lib/awx/public/static/; - access_log off; - sendfile off; - } - - location /favicon.ico { alias /awx_devel/awx/public/static/favicon.ico; } - - location ~ ^/websocket { - # Pass request to the upstream alias - proxy_pass http://daphne; - # Require http version 1.1 to allow for upgrade requests - proxy_http_version 1.1; - # We want proxy_buffering off for proxying to websockets. - proxy_buffering off; - # http://en.wikipedia.org/wiki/X-Forwarded-For - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # enable this if you use HTTPS: - proxy_set_header X-Forwarded-Proto https; - # pass the Host: header from the client for the sake of redirects - proxy_set_header Host $http_host; - # We've set the Host header, so we don't need Nginx to muddle - # about with redirects - proxy_redirect off; - # Depending on the request value, set the Upgrade and - # connection headers - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - - location / { - # Add trailing / if missing - rewrite ^(.*[^/])$ $1/ permanent; - uwsgi_read_timeout 120s; - uwsgi_pass uwsgi; - include /etc/nginx/uwsgi_params; - } -} From 9669b9dd2ff0cefddcfb9dbc3557a6f72fba5f42 Mon Sep 17 00:00:00 2001 From: Hao Liu Date: Mon, 27 Feb 2023 08:23:27 -0500 Subject: [PATCH 4/4] Revert project_update.yml Due to problem found in testing reverting https://github.com/ansible/awx/commit/019e6a52fe6699e4bf34c36931b739430c37b190 --- awx/playbooks/project_update.yml | 187 +++++++++++++++---------------- 1 file changed, 89 insertions(+), 98 deletions(-) diff --git a/awx/playbooks/project_update.yml b/awx/playbooks/project_update.yml index 125b5ef312..2067e76043 100644 --- a/awx/playbooks/project_update.yml +++ b/awx/playbooks/project_update.yml @@ -25,47 +25,42 @@ connection: local name: Update source tree if necessary tasks: - - name: Delete project directory before update - ansible.builtin.shell: set -o pipefail && find . -delete -print | tail -2 # volume mounted, cannot delete folder itself - register: reg - changed_when: reg.stdout_lines | length > 1 + + - name: delete project directory before update + command: "find -delete" # volume mounted, cannot delete folder itself args: chdir: "{{ project_path }}" tags: - delete - - name: Update project using git - tags: - - update_git - block: - - name: Update project using git - ansible.builtin.git: - dest: "{{ project_path | quote }}" - repo: "{{ scm_url }}" - version: "{{ scm_branch | quote }}" - refspec: "{{ scm_refspec | default(omit) }}" - force: "{{ scm_clean }}" - track_submodules: "{{ scm_track_submodules | default(omit) }}" - accept_hostkey: "{{ scm_accept_hostkey | default(omit) }}" + - block: + - name: update project using git + git: + dest: "{{project_path|quote}}" + repo: "{{scm_url}}" + version: "{{scm_branch|quote}}" + refspec: "{{scm_refspec|default(omit)}}" + force: "{{scm_clean}}" + track_submodules: "{{scm_track_submodules|default(omit)}}" + accept_hostkey: "{{scm_accept_hostkey|default(omit)}}" register: git_result - name: Set the git repository version - ansible.builtin.set_fact: + set_fact: scm_version: "{{ git_result['after'] }}" when: "'after' in git_result" - - - name: Update project using svn tags: - - update_svn - block: - - name: Update project using svn - ansible.builtin.subversion: - dest: "{{ project_path | quote }}" - repo: "{{ scm_url | quote }}" - revision: "{{ scm_branch | quote }}" - force: "{{ scm_clean }}" - username: "{{ scm_username | default(omit) }}" - password: "{{ scm_password | default(omit) }}" + - update_git + + - block: + - name: update project using svn + subversion: + dest: "{{project_path|quote}}" + repo: "{{scm_url|quote}}" + revision: "{{scm_branch|quote}}" + force: "{{scm_clean}}" + username: "{{scm_username|default(omit)}}" + password: "{{scm_password|default(omit)}}" # must be in_place because folder pre-existing, because it is mounted in_place: true environment: @@ -73,90 +68,85 @@ register: svn_result - name: Set the svn repository version - ansible.builtin.set_fact: + set_fact: scm_version: "{{ svn_result['after'] }}" when: "'after' in svn_result" - - name: Parse subversion version string properly - ansible.builtin.set_fact: - scm_version: "{{ scm_version | regex_replace('^.*Revision: ([0-9]+).*$', '\\1') }}" - - - - name: Project update for Insights + - name: parse subversion version string properly + set_fact: + scm_version: "{{scm_version|regex_replace('^.*Revision: ([0-9]+).*$', '\\1')}}" tags: - - update_insights - block: + - update_svn + + - block: - name: Ensure the project directory is present - ansible.builtin.file: - dest: "{{ project_path | quote }}" + file: + dest: "{{project_path|quote}}" state: directory - mode: '0755' - name: Fetch Insights Playbook(s) insights: - insights_url: "{{ insights_url }}" - username: "{{ scm_username }}" - password: "{{ scm_password }}" - project_path: "{{ project_path }}" - awx_license_type: "{{ awx_license_type }}" - awx_version: "{{ awx_version }}" + insights_url: "{{insights_url}}" + username: "{{scm_username}}" + password: "{{scm_password}}" + project_path: "{{project_path}}" + awx_license_type: "{{awx_license_type}}" + awx_version: "{{awx_version}}" register: results - name: Save Insights Version - ansible.builtin.set_fact: - scm_version: "{{ results.version }}" + set_fact: + scm_version: "{{results.version}}" when: results is defined - - - - name: Update project using archive tags: - - update_archive - block: + - update_insights + + - block: - name: Ensure the project archive directory is present - ansible.builtin.file: - dest: "{{ project_path | quote }}/.archive" + file: + dest: "{{ project_path|quote }}/.archive" state: directory - mode: '0755' - name: Get archive from url - ansible.builtin.get_url: - url: "{{ scm_url | quote }}" - dest: "{{ project_path | quote }}/.archive/" - url_username: "{{ scm_username | default(omit) }}" - url_password: "{{ scm_password | default(omit) }}" + get_url: + url: "{{ scm_url|quote }}" + dest: "{{ project_path|quote }}/.archive/" + url_username: "{{ scm_username|default(omit) }}" + url_password: "{{ scm_password|default(omit) }}" force_basic_auth: true - mode: '0755' register: get_archive - name: Unpack archive project_archive: src: "{{ get_archive.dest }}" - project_path: "{{ project_path | quote }}" + project_path: "{{ project_path|quote }}" force: "{{ scm_clean }}" when: get_archive.changed or scm_clean register: unarchived - name: Find previous archives - ansible.builtin.find: - paths: "{{ project_path | quote }}/.archive/" + find: + paths: "{{ project_path|quote }}/.archive/" excludes: - - "{{ get_archive.dest | basename }}" + - "{{ get_archive.dest|basename }}" when: unarchived.changed register: previous_archive - name: Remove previous archives - ansible.builtin.file: + file: path: "{{ item.path }}" state: absent loop: "{{ previous_archive.files }}" - when: previous_archive.files | default([]) + when: previous_archive.files|default([]) - name: Set scm_version to archive sha1 checksum - ansible.builtin.set_fact: + set_fact: scm_version: "{{ get_archive.checksum_src }}" + tags: + - update_archive - name: Repository Version - ansible.builtin.debug: + debug: msg: "Repository Version {{ scm_version }}" tags: - update_git @@ -193,59 +183,60 @@ additional_collections_env: # These environment variables are used for installing collections, in addition to galaxy_task_env # setting the collections paths silences warnings - ANSIBLE_COLLECTIONS_PATHS: "{{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_collections" + ANSIBLE_COLLECTIONS_PATHS: "{{projects_root}}/.__awx_cache/{{local_path}}/stage/requirements_collections" # Put the local tmp directory in same volume as collection destination # otherwise, files cannot be moved accross volumes and will cause error - ANSIBLE_LOCAL_TEMP: "{{ projects_root }}/.__awx_cache/{{ local_path }}/stage/tmp" + ANSIBLE_LOCAL_TEMP: "{{projects_root}}/.__awx_cache/{{local_path}}/stage/tmp" tasks: + - name: Check content sync settings - when: not roles_enabled | bool and not collections_enabled | bool - tags: - - install_roles - - install_collections block: - - name: Warn about disabled content sync - ansible.builtin.debug: + - debug: msg: > Collection and role syncing disabled. Check the AWX_ROLES_ENABLED and AWX_COLLECTIONS_ENABLED settings and Galaxy credentials on the project's organization. - - name: End play due to disabled content sync - ansible.builtin.meta: end_play - - name: Fetch galaxy roles from requirements.(yml/yaml) - ansible.builtin.command: > + - meta: end_play + + when: not roles_enabled|bool and not collections_enabled|bool + tags: + - install_roles + - install_collections + + - name: fetch galaxy roles from requirements.(yml/yaml) + command: > ansible-galaxy role install -r {{ item }} - --roles-path {{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_roles + --roles-path {{projects_root}}/.__awx_cache/{{local_path}}/stage/requirements_roles {{ ' -' + 'v' * ansible_verbosity if ansible_verbosity else '' }} args: - chdir: "{{ project_path | quote }}" + chdir: "{{project_path|quote}}" register: galaxy_result with_fileglob: - - "{{ project_path | quote }}/roles/requirements.yaml" - - "{{ project_path | quote }}/roles/requirements.yml" + - "{{project_path|quote}}/roles/requirements.yaml" + - "{{project_path|quote}}/roles/requirements.yml" changed_when: "'was installed successfully' in galaxy_result.stdout" environment: "{{ galaxy_task_env }}" - when: roles_enabled | bool + when: roles_enabled|bool tags: - install_roles - - name: Fetch galaxy collections from collections/requirements.(yml/yaml) - ansible.builtin.command: > + - name: fetch galaxy collections from collections/requirements.(yml/yaml) + command: > ansible-galaxy collection install -r {{ item }} - --collections-path {{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_collections + --collections-path {{projects_root}}/.__awx_cache/{{local_path}}/stage/requirements_collections {{ ' -' + 'v' * ansible_verbosity if ansible_verbosity else '' }} args: - chdir: "{{ project_path | quote }}" + chdir: "{{project_path|quote}}" register: galaxy_collection_result with_fileglob: - - "{{ project_path | quote }}/collections/requirements.yaml" - - "{{ project_path | quote }}/collections/requirements.yml" - - "{{ project_path | quote }}/requirements.yaml" - - "{{ project_path | quote }}/requirements.yml" + - "{{project_path|quote}}/collections/requirements.yaml" + - "{{project_path|quote}}/collections/requirements.yml" + - "{{project_path|quote}}/requirements.yaml" + - "{{project_path|quote}}/requirements.yml" changed_when: "'Installing ' in galaxy_collection_result.stdout" environment: "{{ additional_collections_env | combine(galaxy_task_env) }}" when: - "ansible_version.full is version_compare('2.9', '>=')" - - collections_enabled | bool + - collections_enabled|bool tags: - install_collections