diff --git a/config/crd/bases/awx.ansible.com_awxs.yaml b/config/crd/bases/awx.ansible.com_awxs.yaml index e3387b26ea..48d4b1fe48 100644 --- a/config/crd/bases/awx.ansible.com_awxs.yaml +++ b/config/crd/bases/awx.ansible.com_awxs.yaml @@ -1571,6 +1571,86 @@ spec: description: Number of task instance replicas type: integer format: int32 + web_liveness_initial_delay: + description: Initial delay before starting liveness checks on web pod + type: integer + default: 5 + format: int32 + task_liveness_initial_delay: + description: Initial delay before starting liveness checks on task pod + type: integer + default: 5 + format: int32 + web_liveness_period: + description: Time period in seconds between each liveness check for the web pod + type: integer + default: 0 + format: int32 + task_liveness_period: + description: Time period in seconds between each liveness check for the task pod + type: integer + default: 0 + format: int32 + web_liveness_failure_threshold: + description: Number of consecutive failure events to identify failure of web pod + type: integer + default: 3 + format: int32 + task_liveness_failure_threshold: + description: Number of consecutive failure events to identify failure of task pod + type: integer + default: 3 + format: int32 + web_liveness_timeout: + description: Number of seconds to wait for a probe response from web pod + type: integer + default: 1 + format: int32 + task_liveness_timeout: + description: Number of seconds to wait for a probe response from task pod + type: integer + default: 1 + format: int32 + web_readiness_initial_delay: + description: Initial delay before starting readiness checks on web pod + type: integer + default: 20 + format: int32 + task_readiness_initial_delay: + description: Initial delay before starting readiness checks on task pod + type: integer + default: 20 + format: int32 + web_readiness_period: + description: Time period in seconds between each readiness check for the web pod + type: integer + default: 0 + format: int32 + task_readiness_period: + description: Time period in seconds between each readiness check for the task pod + type: integer + default: 0 + format: int32 + web_readiness_failure_threshold: + description: Number of consecutive failure events to identify failure of web pod + type: integer + default: 3 + format: int32 + task_readiness_failure_threshold: + description: Number of consecutive failure events to identify failure of task pod + type: integer + default: 3 + format: int32 + web_readiness_timeout: + description: Number of seconds to wait for a probe response from web pod + type: integer + default: 1 + format: int32 + task_readiness_timeout: + description: Number of seconds to wait for a probe response from task pod + type: integer + default: 1 + format: int32 garbage_collect_secrets: description: Whether or not to remove secrets upon instance removal default: false diff --git a/docs/user-guide/advanced-configuration/container-probes.md b/docs/user-guide/advanced-configuration/container-probes.md new file mode 100644 index 0000000000..338e537737 --- /dev/null +++ b/docs/user-guide/advanced-configuration/container-probes.md @@ -0,0 +1,40 @@ +#### Container Probes +These parameters control the usage of liveness and readiness container probes for +the web and task containers. + +#### Web / Task Container Liveness Check + +The liveness probe queries the status of the supervisor daemon of the container. The probe will fail if it +detects one of the services in a state other than "RUNNING". + +| Name | Description | Default | +| web_liveness_period | Time period in seconds between each probe check. The value of 0 disables the probe. | 0 | +| web_liveness_initial_delay | Initial delay before starting probes in seconds | 5 | +| web_liveness_failure_threshold| Number of consecutive failure events to identify failure of container | 3 | +| web_liveness_timeout | Number of seconds to wait for a probe response from container | 1 | +| task_liveness_period | Time period in seconds between each probe check. The value of 0 disables the probe. | 0 | +| task_liveness_initial_delay | Initial delay before starting probes in seconds | 5 | +| task_liveness_failure_threshold| Number of consecutive failure events to identify failure of container | 3 | +| task_liveness_timeout | Number of seconds to wait for a probe response from container | 1 | + +#### Web Container Readiness Check + +This is a HTTP check against the status endpoint to confirm the system is still able to respond to web requests. + +| Name | Description | Default | +| -------------| ---------------------------------- | ------- | +| web_readiness_period | Time period in seconds between each probe check. The value of 0 disables the probe. | 0 | +| web_readiness_initial_delay | Initial delay before starting probes in seconds | 5 | +| web_readiness_failure_threshold| Number of consecutive failure events to identify failure of container | 3 | +| web_readiness_timeout | Number of seconds to wait for a probe response from container | 1 | + +#### Task Container Readiness Check + +This is a command probe using the builtin check command of the awx-manage utility. + +| Name | Description | Default | +| -------------| ---------------------------------- | ------- | +| task_readiness_period | Time period in seconds between each probe check. The value of 0 disables the probe. | 0 | +| task_readiness_initial_delay | Initial delay before starting probes in seconds | 5 | +| task_readiness_failure_threshold| Number of consecutive failure events to identify failure of container | 3 | +| task_readiness_timeout | Number of seconds to wait for a probe response from container | 1 | diff --git a/roles/installer/tasks/install.yml b/roles/installer/tasks/install.yml index 2398ebb4da..540e86e185 100644 --- a/roles/installer/tasks/install.yml +++ b/roles/installer/tasks/install.yml @@ -94,48 +94,6 @@ - name: Include resources configuration tasks include_tasks: resources_configuration.yml -- name: Check for pending migrations - k8s_exec: - namespace: "{{ ansible_operator_meta.namespace }}" - pod: "{{ awx_task_pod_name }}" - container: "{{ ansible_operator_meta.name }}-task" - command: >- - bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l" - changed_when: false - when: awx_task_pod_name != '' - register: database_check - -- name: Migrate the database if the K8s resources were updated # noqa 305 - k8s_exec: - namespace: "{{ ansible_operator_meta.namespace }}" - pod: "{{ awx_task_pod_name }}" - container: "{{ ansible_operator_meta.name }}-task" - command: | - bash -c " - function end_keepalive { - rc=$? - rm -f \"$1\" - kill $(cat /proc/$2/task/$2/children 2>/dev/null) 2>/dev/null || true - wait $2 || true - exit $rc - } - keepalive_file=\"$(mktemp)\" - while [[ -f \"$keepalive_file\" ]]; do - echo 'Database schema migration in progress...' - sleep 60 - done & - keepalive_pid=$! - trap 'end_keepalive \"$keepalive_file\" \"$keepalive_pid\"' EXIT SIGINT SIGTERM - echo keepalive_pid: $keepalive_pid - awx-manage migrate --noinput - echo 'Successful' - " - register: migrate_result - when: - - awx_task_pod_name != '' - - database_check is defined - - (database_check.stdout|trim) != '0' - - name: Initialize Django include_tasks: initialize_django.yml when: awx_task_pod_name != '' diff --git a/roles/installer/tasks/migrate_schema.yml b/roles/installer/tasks/migrate_schema.yml new file mode 100644 index 0000000000..49fa416b97 --- /dev/null +++ b/roles/installer/tasks/migrate_schema.yml @@ -0,0 +1,330 @@ +--- + +- name: Get the current resource task pod information. + k8s_info: + api_version: v1 + kind: Pod + namespace: '{{ ansible_operator_meta.namespace }}' + label_selectors: + - "app.kubernetes.io/name={{ ansible_operator_meta.name }}-task" + - "app.kubernetes.io/managed-by={{ deployment_type }}-operator" + - "app.kubernetes.io/component={{ deployment_type }}" + field_selectors: + - status.phase=Running + register: awx_task_pod + +- name: Set the resource task pod as a variable. + set_fact: + awx_task_pod: >- + {{ awx_task_pod['resources'] + | rejectattr('metadata.deletionTimestamp', 'defined') + | sort(attribute='metadata.creationTimestamp') + | first | default({}) }} + +- name: Set the resource task pod name as a variable. + set_fact: + awx_task_pod_name: "{{ awx_task_pod['metadata']['name'] | default('') }}" + +- name: Set user provided control plane ee image + set_fact: + _custom_control_plane_ee_image: "{{ control_plane_ee_image }}" + when: + - control_plane_ee_image | default([]) | length + +- name: Set Control Plane EE image URL + set_fact: + _control_plane_ee_image: "{{ _custom_control_plane_ee_image | default(lookup('env', 'RELATED_IMAGE_CONTROL_PLANE_EE')) | default(_control_plane_ee_image, true) }}" + +- name: Check for Receptor CA Secret + k8s_info: + kind: Secret + namespace: '{{ ansible_operator_meta.namespace }}' + name: '{{ ansible_operator_meta.name }}-receptor-ca' + register: receptor_ca + no_log: "{{ no_log }}" + +- name: Migrate Receptor CA Secret + when: + - receptor_ca['resources'] | default([]) | length + - receptor_ca['resources'][0]['type'] != "kubernetes.io/tls" + block: + - name: Delete old Receptor CA Secret + k8s: + state: absent + kind: Secret + namespace: '{{ ansible_operator_meta.namespace }}' + name: '{{ ansible_operator_meta.name }}-receptor-ca' + - name: Create tempfile for receptor-ca.key + tempfile: + state: file + suffix: .key + register: _receptor_ca_key_file + - name: Copy Receptor CA key from old secret to tempfile + copy: + content: "{{ receptor_ca['resources'][0]['data']['receptor-ca.key'] | b64decode }}" + dest: "{{ _receptor_ca_key_file.path }}" + no_log: "{{ no_log }}" + - name: Create tempfile for receptor-ca.crt + tempfile: + state: file + suffix: .crt + register: _receptor_ca_crt_file + - name: Copy Receptor CA cert from old secret to tempfile + copy: + content: "{{ receptor_ca['resources'][0]['data']['receptor-ca.crt'] | b64decode }}" + dest: "{{ _receptor_ca_crt_file.path }}" + no_log: "{{ no_log }}" + - name: Create New Receptor CA secret + k8s: + apply: true + definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}" + no_log: "{{ no_log }}" + - name: Read New Receptor CA Secret + k8s_info: + kind: Secret + namespace: '{{ ansible_operator_meta.namespace }}' + name: '{{ ansible_operator_meta.name }}-receptor-ca' + register: _receptor_ca + no_log: "{{ no_log }}" + - name: Set receptor_ca variable + set_fact: + receptor_ca: '{{ _receptor_ca }}' + no_log: "{{ no_log }}" + - name: Remove tempfiles + file: + path: "{{ item }}" + state: absent + loop: + - "{{ _receptor_ca_key_file.path }}" + - "{{ _receptor_ca_crt_file.path }}" + +- name: Create Receptor Mesh CA + block: + - name: Create tempfile for receptor-ca.key + tempfile: + state: file + suffix: .key + register: _receptor_ca_key_file + - name: Generate Receptor CA key + command: | + openssl genrsa -out {{ _receptor_ca_key_file.path }} 4096 + no_log: "{{ no_log }}" + - name: Create tempfile for receptor-ca.crt + tempfile: + state: file + suffix: .crt + register: _receptor_ca_crt_file + - name: Generate Receptor CA cert + command: | + openssl req -x509 -new -nodes -key {{ _receptor_ca_key_file.path }} \ + -subj "/CN={{ ansible_operator_meta.name }} Receptor Root CA" \ + -sha256 -days 3650 -out {{ _receptor_ca_crt_file.path }} + no_log: "{{ no_log }}" + - name: Create Receptor CA secret + k8s: + apply: true + definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}" + no_log: "{{ no_log }}" + - name: Read Receptor CA secret + k8s_info: + kind: Secret + namespace: '{{ ansible_operator_meta.namespace }}' + name: '{{ ansible_operator_meta.name }}-receptor-ca' + register: _receptor_ca + no_log: "{{ no_log }}" + - name: Set receptor_ca variable + set_fact: + receptor_ca: '{{ _receptor_ca }}' + no_log: "{{ no_log }}" + - name: Remove tempfiles + file: + path: "{{ item }}" + state: absent + loop: + - "{{ _receptor_ca_key_file.path }}" + - "{{ _receptor_ca_crt_file.path }}" + when: not receptor_ca['resources'] | default([]) | length + +- name: Check for Receptor work signing Secret + k8s_info: + kind: Secret + namespace: '{{ ansible_operator_meta.namespace }}' + name: '{{ ansible_operator_meta.name }}-receptor-work-signing' + register: receptor_work_signing + no_log: "{{ no_log }}" + +- name: Generate Receptor work signing RSA key pair + block: + - name: Create tempfile for receptor work signing private key + tempfile: + state: file + suffix: .pem + register: _receptor_work_signing_private_key_file + - name: Generate Receptor work signing private key + command: | + openssl genrsa -out {{ _receptor_work_signing_private_key_file.path }} 4096 + no_log: "{{ no_log }}" + - name: Create tempfile for receptor work signing public key + tempfile: + state: file + suffix: .pem + register: _receptor_work_signing_public_key_file + - name: Generate Receptor work signing public key + command: | + openssl rsa \ + -in {{ _receptor_work_signing_private_key_file.path }} \ + -out {{ _receptor_work_signing_public_key_file.path }} \ + -outform PEM -pubout + no_log: "{{ no_log }}" + - name: Create Receptor work signing Secret + k8s: + apply: true + definition: "{{ lookup('template', 'secrets/receptor_work_signing_secret.yaml.j2') }}" + no_log: "{{ no_log }}" + - name: Read Receptor work signing Secret + k8s_info: + kind: Secret + namespace: '{{ ansible_operator_meta.namespace }}' + name: '{{ ansible_operator_meta.name }}-receptor-work-signing' + register: _receptor_work_signing + no_log: "{{ no_log }}" + - name: Set receptor_work_signing variable + set_fact: + receptor_work_signing: '{{ _receptor_work_signing }}' + no_log: "{{ no_log }}" + - name: Remove tempfiles + file: + path: "{{ item }}" + state: absent + loop: + - "{{ _receptor_work_signing_private_key_file.path }}" + - "{{ _receptor_work_signing_public_key_file.path }}" + when: not receptor_work_signing['resources'] | default([]) | length + +- name: Apply Resources + k8s: + apply: yes + definition: "{{ lookup('template', item + '.yaml.j2') }}" + wait: yes + loop: + - 'configmaps/config' + - 'configmaps/pre_stop_scripts' + - 'secrets/app_credentials' + - 'rbac/service_account' + - 'storage/persistent' + - 'networking/service' + - 'networking/ingress' + no_log: "{{ no_log }}" + +- name: Set default awx app image + set_fact: + _default_image: "{{ _image }}:{{ _image_version }}" + +- name: Set user provided awx app image + set_fact: + _custom_image: "{{ image }}:{{ image_version }}" + when: + - image | default([]) | length + - image_version is defined or image_version != '' + +- name: Set AWX app image URL + set_fact: + _image: "{{ _custom_image | default(lookup('env', 'RELATED_IMAGE_AWX')) | default(_default_image, true) }}" + +- name: Set default redis image + set_fact: + _default_redis_image: "{{ _redis_image }}:{{ _redis_image_version }}" + +- name: Set user provided redis image + set_fact: + _custom_redis_image: "{{ redis_image }}:{{ redis_image_version }}" + when: + - redis_image | default([]) | length + - redis_image_version is defined or redis_image_version != '' + +- name: Set Redis image URL + set_fact: + _redis_image: "{{ _custom_redis_image | default(lookup('env', 'RELATED_IMAGE_AWX_REDIS')) | default(_default_redis_image, true) }}" + +- name: Apply deployment resources + k8s: + apply: yes + definition: "{{ lookup('template', 'deployments/{{ item }}.yaml.j2') }}" + loop: + - task + - web + register: this_deployment_result + +- block: + - name: Get the new task pod information after updating resource. + k8s_info: + kind: Pod + namespace: '{{ ansible_operator_meta.namespace }}' + label_selectors: + - "app.kubernetes.io/name={{ ansible_operator_meta.name }}-task" + - "app.kubernetes.io/managed-by={{ deployment_type }}-operator" + - "app.kubernetes.io/component={{ deployment_type }}" + field_selectors: + - status.phase=Pending + register: _new_pod + + - name: Update new task pod as a variable. + set_fact: + awx_task_pod: >- + {{ _new_pod['resources'] + | rejectattr('metadata.deletionTimestamp', 'defined') + | sort(attribute='metadata.creationTimestamp') + | last | default({}) }} + + - name: Update new task pod name as a variable. + set_fact: + awx_task_pod_name: '{{ awx_task_pod["metadata"]["name"] | default("")}}' + + - name: Get the new web pod information after updating resource. + k8s_info: + kind: Pod + namespace: '{{ ansible_operator_meta.namespace }}' + label_selectors: + - "app.kubernetes.io/name={{ ansible_operator_meta.name }}-web" + - "app.kubernetes.io/managed-by={{ deployment_type }}-operator" + - "app.kubernetes.io/component={{ deployment_type }}" + field_selectors: + - status.phase=Running + register: _new_pod + + - name: Update new web pod as a variable. + set_fact: + awx_web_pod: >- + {{ _new_pod['resources'] + | rejectattr('metadata.deletionTimestamp', 'defined') + | sort(attribute='metadata.creationTimestamp') + | last | default({}) }} + + - name: Update new web pod name as a variable. + set_fact: + awx_web_pod_name: '{{ awx_web_pod["metadata"]["name"] | default("")}}' + + # The only purpose of this task is to delay the initial installation + # of AWX until the database is properly populated with tables. + # The web containers will show a migration screen during this time. + # We use the web pod instead of the task pod for monitoring in + # order to simplify error handling. + - name: Wait for any migrations to finish before finishing installation # noqa 305 + k8s_exec: + namespace: "{{ ansible_operator_meta.namespace }}" + pod: "{{ awx_web_pod_name }}" + container: "{{ ansible_operator_meta.name }}-web" + command: "/bin/sh -c 'wait-for-migrations'" + register: migrate_result + when: + - awx_web_pod_name != '' + + when: + - this_deployment_result.changed + +- name: Verify the resource pod name is populated. + assert: + that: + - awx_task_pod_name != '' + fail_msg: "Could not find the tower pod's name." + when: task_replicas | int > 0 or (task_replicas == '' and replicas > 0) diff --git a/roles/installer/tasks/resources_configuration.yml b/roles/installer/tasks/resources_configuration.yml index c811aeeb7e..3c56563abf 100644 --- a/roles/installer/tasks/resources_configuration.yml +++ b/roles/installer/tasks/resources_configuration.yml @@ -12,7 +12,7 @@ - status.phase=Running register: awx_task_pod -- name: Set the resource pod as a variable. +- name: Set the resource task pod as a variable. set_fact: awx_task_pod: >- {{ awx_task_pod['resources'] @@ -20,7 +20,7 @@ | sort(attribute='metadata.creationTimestamp') | first | default({}) }} -- name: Set the resource pod name as a variable. +- name: Set the resource task pod name as a variable. set_fact: awx_task_pod_name: "{{ awx_task_pod['metadata']['name'] | default('') }}" @@ -249,15 +249,13 @@ k8s: apply: yes definition: "{{ lookup('template', 'deployments/{{ item }}.yaml.j2') }}" - wait: yes - wait_timeout: "{{ (120 * replicas) or 120 }}" loop: - task - web register: this_deployment_result - block: - - name: Get the new resource pod information after updating resource. + - name: Get the new task pod information after updating resource. k8s_info: kind: Pod namespace: '{{ ansible_operator_meta.namespace }}' @@ -266,10 +264,10 @@ - "app.kubernetes.io/managed-by={{ deployment_type }}-operator" - "app.kubernetes.io/component={{ deployment_type }}" field_selectors: - - status.phase=Running + - status.phase=Pending register: _new_pod - - name: Update new resource pod as a variable. + - name: Update new task pod as a variable. set_fact: awx_task_pod: >- {{ _new_pod['resources'] @@ -277,9 +275,75 @@ | sort(attribute='metadata.creationTimestamp') | last | default({}) }} - - name: Update new resource pod name as a variable. + - name: Update new task pod name as a variable. set_fact: awx_task_pod_name: '{{ awx_task_pod["metadata"]["name"] | default("")}}' + + - name: Get the new web pod information after updating resource. + k8s_info: + kind: Pod + namespace: '{{ ansible_operator_meta.namespace }}' + label_selectors: + - "app.kubernetes.io/name={{ ansible_operator_meta.name }}-web" + - "app.kubernetes.io/managed-by={{ deployment_type }}-operator" + - "app.kubernetes.io/component={{ deployment_type }}" + field_selectors: + - status.phase=Running + register: _new_pod + + - name: Update new web pod as a variable. + set_fact: + awx_web_pod: >- + {{ _new_pod['resources'] + | rejectattr('metadata.deletionTimestamp', 'defined') + | sort(attribute='metadata.creationTimestamp') + | last | default({}) }} + + - name: Update new web pod name as a variable. + set_fact: + awx_web_pod_name: '{{ awx_web_pod["metadata"]["name"] | default("")}}' + + # We use the web pod to check for migrations because it should be in a running + # state. The task pod should be stuck in an init container loop waiting for + # the migrations to finish. + - name: Check for pending migrations + k8s_exec: + namespace: "{{ ansible_operator_meta.namespace }}" + pod: "{{ awx_web_pod_name }}" + container: "{{ ansible_operator_meta.name }}-web" + command: >- + bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l" + changed_when: false + when: awx_web_pod_name != '' + register: database_check + + # version: "{{ instance_version.stdout | trim }}" + - name: Get version of controller for tracking + k8s_exec: + namespace: "{{ ansible_operator_meta.namespace }}" + pod: "{{ awx_web_pod_name }}" + container: "{{ ansible_operator_meta.name }}-web" + command: >- + bash -c "awx-manage --version" + changed_when: false + register: version_check + when: + - database_check is defined + - (database_check.stdout|trim) != '0' + + - name: Update instance version + set_fact: + version: "{{ instance_check.stdout | trim }}" + + - name: Create a migration job + k8s: + apply: yes + definition: "{{ lookup('template', 'job/migration.yaml.j2') }}" + register: migrate_result + when: + - database_check is defined + - (database_check.stdout|trim) != '0' + when: - this_deployment_result.changed diff --git a/roles/installer/templates/deployments/task.yaml.j2 b/roles/installer/templates/deployments/task.yaml.j2 index cb57fbd133..af5c4b8484 100644 --- a/roles/installer/templates/deployments/task.yaml.j2 +++ b/roles/installer/templates/deployments/task.yaml.j2 @@ -74,7 +74,28 @@ spec: priorityClassName: '{{ control_plane_priority_class }}' {% endif %} initContainers: - - name: init + - name: init-database + image: '{{ _image }}' + imagePullPolicy: '{{ image_pull_policy }}' + resources: {{ init_container_resource_requirements }} + command: + - /bin/sh + - -c + - wait-for-migrations + volumeMounts: + - name: {{ ansible_operator_meta.name }}-application-credentials + mountPath: "/etc/tower/conf.d/credentials.py" + subPath: credentials.py + readOnly: true + - name: "{{ secret_key_secret_name }}" + mountPath: /etc/tower/SECRET_KEY + subPath: SECRET_KEY + readOnly: true + - name: {{ ansible_operator_meta.name }}-settings + mountPath: "/etc/tower/settings.py" + subPath: settings.py + readOnly: true + - name: init-receptor image: '{{ _init_container_image }}' imagePullPolicy: '{{ image_pull_policy }}' resources: {{ init_container_resource_requirements }} @@ -188,6 +209,30 @@ spec: {% endif %} {% if task_args %} args: {{ task_args }} +{% endif %} +{% if task_liveness_period|int > 0 %} + livenessProbe: + exec: + command: + - sh + - -c + - | + (exit $(/usr/bin/supervisorctl -c /etc/supervisord_task.conf status | grep -vc RUNNING)) + initialDelaySeconds: {{ task_liveness_initial_delay }} + periodSeconds: {{ task_liveness_period }} + failureThreshold: {{ task_liveness_failure_threshold }} + timeoutSeconds: {{ task_liveness_timeout }} +{% endif %} +{% if task_readiness_period|int > 0 %} + readinessProbe: + exec: + command: + - /usr/bin/awx-manage + - check + initialDelaySeconds: {{ task_readiness_initial_delay }} + periodSeconds: {{ task_readiness_period }} + failureThreshold: {{ task_readiness_failure_threshold }} + timeoutSeconds: {{ task_readiness_timeout }} {% endif %} volumeMounts: {% if bundle_ca_crt %} diff --git a/roles/installer/templates/deployments/web.yaml.j2 b/roles/installer/templates/deployments/web.yaml.j2 index 1a73183482..568a6d690e 100644 --- a/roles/installer/templates/deployments/web.yaml.j2 +++ b/roles/installer/templates/deployments/web.yaml.j2 @@ -162,6 +162,31 @@ spec: - containerPort: 8052 {% if ingress_type | lower == 'route' and route_tls_termination_mechanism | lower == 'passthrough' %} - containerPort: 8053 +{% endif %} +{% if web_liveness_period|int > 0 %} + livenessProbe: + exec: + command: + - sh + - -c + - | + (exit $(/usr/bin/supervisorctl -c /etc/supervisord_task.conf status | grep -vc RUNNING)) + initialDelaySeconds: {{ web_liveness_initial_delay }} + periodSeconds: {{ web_liveness_period }} + failureThreshold: {{ web_liveness_failure_threshold }} + timeoutSeconds: {{ web_liveness_timeout }} +{% endif %} +{% if web_readiness_period|int > 0 %} + readinessProbe: + exec: + httpGet: + path: /api/v2/ping/ + scheme: HTTP + port: 8052 + initialDelaySeconds: {{ web_readiness_initial_delay }} + periodSeconds: {{ web_readiness_period }} + failureThreshold: {{ web_readiness_failure_threshold }} + timeoutSeconds: {{ web_readiness_timeout }} {% endif %} volumeMounts: {% if bundle_ca_crt %} diff --git a/roles/installer/templates/job/migration.yaml.j2 b/roles/installer/templates/job/migration.yaml.j2 new file mode 100644 index 0000000000..3b4c3f5470 --- /dev/null +++ b/roles/installer/templates/job/migration.yaml.j2 @@ -0,0 +1,57 @@ +apiVersion: batch/v1 +kind: Job +metadata: +metadata: + name: '{{ ansible_operator_meta.name }}-migration-{{ version }}' + namespace: '{{ ansible_operator_meta.namespace }}' + labels: + {{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=4) | trim }} + {{ lookup("template", "../common/templates/labels/version.yaml.j2") | indent(width=4) | trim }} +spec: + template: + spec: + containers: + - image: '{{ _image }}' + command: + - /usr/bin/awx-manage + - migrate + - --noinput + volumeMounts: + - name: {{ ansible_operator_meta.name }}-application-credentials + mountPath: "/etc/tower/conf.d/credentials.py" + subPath: credentials.py + readOnly: true + - name: "{{ secret_key_secret_name }}" + mountPath: /etc/tower/SECRET_KEY + subPath: SECRET_KEY + readOnly: true + - name: {{ ansible_operator_meta.name }}-settings + mountPath: "/etc/tower/settings.py" + subPath: settings.py + readOnly: true + volumes: + - name: "{{ ansible_operator_meta.name }}-application-credentials" + secret: + secretName: "{{ ansible_operator_meta.name }}-app-credentials" + items: + - key: credentials.py + path: 'credentials.py' + - key: ldap.py + path: 'ldap.py' + - key: execution_environments.py + path: 'execution_environments.py' + - name: "{{ secret_key_secret_name }}" + secret: + secretName: '{{ secret_key_secret_name }}' + items: + - key: secret_key + path: SECRET_KEY + - name: {{ ansible_operator_meta.name }}-settings + configMap: + name: '{{ ansible_operator_meta.name }}-{{ deployment_type }}-configmap' + items: + - key: settings + path: settings.py + dnsPolicy: ClusterFirst + restartPolicy: Never + terminationGracePeriodSeconds: 30