diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 71948e7d6..3490876c3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,13 +6,15 @@ Have questions about this document or anything not covered here? Please file a n ## Table of contents -* [Things to know prior to submitting code](#things-to-know-prior-to-submitting-code) -* [Submmiting your Work](#submitting-your-work) -* [Testing](#testing) - * [Testing in Docker](#testing-in-docker) - * [Testing in Minikube](#testing-in-minikube) -* [Generating a bundle](#generating-a-bundle) -* [Reporting Issues](#reporting-issues) +- [AWX-Operator Contributing Guidelines](#awx-operator-contributing-guidelines) + - [Table of contents](#table-of-contents) + - [Things to know prior to submitting code](#things-to-know-prior-to-submitting-code) + - [Submmiting your work](#submmiting-your-work) + - [Testing](#testing) + - [Testing in Kind](#testing-in-kind) + - [Testing in Minikube](#testing-in-minikube) + - [Generating a bundle](#generating-a-bundle) + - [Reporting Issues](#reporting-issues) ## Things to know prior to submitting code @@ -44,12 +46,12 @@ Have questions about this document or anything not covered here? Please file a n ## Testing -This Operator includes a [Molecule](https://molecule.readthedocs.io/en/stable/)-based test environment, which can be executed standalone in Docker (e.g. in CI or in a single Docker container anywhere), or inside any kind of Kubernetes cluster (e.g. Minikube). +This Operator includes a [Molecule](https://ansible.readthedocs.io/projects/molecule/)-based test environment, which can be executed standalone in Docker (e.g. in CI or in a single Docker container anywhere), or inside any kind of Kubernetes cluster (e.g. Minikube). You need to make sure you have Molecule installed before running the following commands. You can install Molecule with: ```sh -#> pip install 'molecule[docker]' +#> python -m pip install molecule-plugins[docker] ``` Running `molecule test` sets up a clean environment, builds the operator, runs all configured tests on an example operator instance, then tears down the environment (at least in the case of Docker). diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 995c877c8..0f2dccf3d 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,9 +5,9 @@ generatorOptions: disableNameSuffixHash: true configMapGenerator: -- name: awx-manager-config - files: +- files: - controller_manager_config.yaml + name: awx-manager-config apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization diff --git a/docs/user-guide/database-configuration.md b/docs/user-guide/database-configuration.md index af4ee74a2..901d56b15 100644 --- a/docs/user-guide/database-configuration.md +++ b/docs/user-guide/database-configuration.md @@ -56,15 +56,15 @@ If you don't have access to an external PostgreSQL service, the AWX operator can The following variables are customizable for the managed PostgreSQL service -| Name | Description | Default | -| --------------------------------------------- | --------------------------------------------- | ---------------------------------- | -| postgres_image | Path of the image to pull | postgres:15 | -| postgres_init_container_resource_requirements | Database init container resource requirements | requests: {cpu: 10m, memory: 64Mi} | -| postgres_resource_requirements | PostgreSQL container resource requirements | requests: {cpu: 10m, memory: 64Mi} | -| postgres_storage_requirements | PostgreSQL container storage requirements | requests: {storage: 8Gi} | -| postgres_storage_class | PostgreSQL PV storage class | Empty string | -| postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` | -| postgres_priority_class | Priority class used for PostgreSQL pod | Empty string | +| Name | Description | Default | +| --------------------------------------------- | --------------------------------------------- | --------------------------------------- | +| postgres_image | Path of the image to pull | quay.io/sclorg/postgresql-15-c9s:latest | +| postgres_init_container_resource_requirements | Database init container resource requirements | requests: {cpu: 10m, memory: 64Mi} | +| postgres_resource_requirements | PostgreSQL container resource requirements | requests: {cpu: 10m, memory: 64Mi} | +| postgres_storage_requirements | PostgreSQL container storage requirements | requests: {storage: 8Gi} | +| postgres_storage_class | PostgreSQL PV storage class | Empty string | +| postgres_data_path | PostgreSQL data path | `/var/lib/postgresql/data/pgdata` | +| postgres_priority_class | Priority class used for PostgreSQL pod | Empty string | Example of customization could be: diff --git a/molecule/default/tasks/awx_replicas_test.yml b/molecule/default/tasks/awx_replicas_test.yml index 3c12c9bc8..8455211b5 100644 --- a/molecule/default/tasks/awx_replicas_test.yml +++ b/molecule/default/tasks/awx_replicas_test.yml @@ -61,4 +61,4 @@ expected_web_replicas: 3 expected_task_replicas: 3 tags: - - replicas + - replicas diff --git a/roles/installer/tasks/database_configuration.yml b/roles/installer/tasks/database_configuration.yml index 0ab8bcbbb..48bad24ab 100644 --- a/roles/installer/tasks/database_configuration.yml +++ b/roles/installer/tasks/database_configuration.yml @@ -106,14 +106,38 @@ set_fact: managed_database: "{{ pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed' }}" -- name: Get the old postgres pod information +# It is possible that N-2 postgres pods may still be present in the namespace from previous upgrades. +# So we have to take that into account and preferentially set the most recent one. +- name: Get the old postgres pod (N-1) k8s_info: kind: Pod namespace: "{{ ansible_operator_meta.namespace }}" - name: "{{ ansible_operator_meta.name }}-postgres-0" field_selectors: - status.phase=Running - register: old_postgres_pod + register: _running_pods + +- block: + - name: Filter pods by name + set_fact: + filtered_old_postgres_pods: "{{ _running_pods.resources | + selectattr('metadata.name', 'match', ansible_operator_meta.name + '-postgres.*-0') | + rejectattr('metadata.name', 'search', '-' + supported_pg_version | string + '-0') | + list }}" + + # Sort pods by name in reverse order (most recent PG version first) and set + - name: Set info for previous postgres pod + set_fact: + sorted_old_postgres_pods: "{{ filtered_old_postgres_pods | + sort(attribute='metadata.name') | + reverse }}" + when: filtered_old_postgres_pods | length + + + - name: Set info for previous postgres pod + set_fact: + old_postgres_pod: "{{ sorted_old_postgres_pods | first }}" + when: filtered_old_postgres_pods | length + when: _running_pods.resources | length - name: Look up details for this deployment k8s_info: @@ -123,6 +147,13 @@ namespace: "{{ ansible_operator_meta.namespace }}" register: this_awx +# If this deployment has been upgraded before or if upgrade has already been started, set this var +- name: Set previous PG version var + set_fact: + _previous_upgraded_pg_version: "{{ this_awx['resources'][0]['status']['upgradedPostgresVersion'] | default(false) }}" + when: + - "'upgradedPostgresVersion' in this_awx['resources'][0]['status']" + - name: Check if postgres pod is running an older version block: - name: Set path to PG_VERSION file for given container image @@ -132,22 +163,24 @@ - name: Get old PostgreSQL version k8s_exec: namespace: "{{ ansible_operator_meta.namespace }}" - pod: "{{ ansible_operator_meta.name }}-postgres-0" + pod: "{{ old_postgres_pod['metadata']['name'] }}" command: | bash -c """ cat {{ path_to_pg_version }} """ register: _old_pg_version + - debug: + msg: "--- Upgrading from {{ old_postgres_pod['metadata']['name'] | default('NONE')}} Pod ---" + - name: Upgrade data dir from old Postgres to {{ supported_pg_version }} if applicable include_tasks: upgrade_postgres.yml when: - - _old_pg_version.stdout | default('0') | trim < supported_pg_version + - (_old_pg_version.stdout | default(0) | int ) < supported_pg_version when: - managed_database - - "'upgradedPostgresVersion' is in this_awx['resources'][0]['status']" - - (this_awx['resources'][0]['status']['upgradedPostgresVersion'] | default(false)) | ternary (this_awx['resources'][0]['status']['upgradedPostgresVersion'] < supported_pg_version, false) - - old_postgres_pod['resources'] | length # upgrade is complete and old pg pod has been removed + - (_previous_upgraded_pg_version | default(false)) | ternary(_previous_upgraded_pg_version < supported_pg_version, true) + - old_postgres_pod | length # If empty, then old pg pod has been removed and we can assume the upgrade is complete - block: - name: Create Database if no database is specified diff --git a/roles/installer/tasks/update_status.yml b/roles/installer/tasks/update_status.yml index 9f59b3644..a693ae528 100644 --- a/roles/installer/tasks/update_status.yml +++ b/roles/installer/tasks/update_status.yml @@ -111,5 +111,5 @@ name: "{{ ansible_operator_meta.name }}" namespace: "{{ ansible_operator_meta.namespace }}" status: - upgradedPostgresVersion: "{{ upgraded_postgres_version }}" + upgradedPostgresVersion: "{{ upgraded_postgres_version | string }}" when: upgraded_postgres_version is defined diff --git a/roles/installer/tasks/upgrade_postgres.yml b/roles/installer/tasks/upgrade_postgres.yml index c536c46b2..383e49d33 100644 --- a/roles/installer/tasks/upgrade_postgres.yml +++ b/roles/installer/tasks/upgrade_postgres.yml @@ -62,9 +62,19 @@ set_fact: postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}" +- name: Get the name of the service for the old postgres pod + k8s_info: + kind: Service + namespace: "{{ ansible_operator_meta.namespace }}" + label_selectors: + - "app.kubernetes.io/component=database" + - "app.kubernetes.io/instance={{ old_postgres_pod.metadata.labels['app.kubernetes.io/instance'] }}" + - "app.kubernetes.io/managed-by=awx-operator" + register: old_postgres_svc + - name: Set full resolvable host name for postgres pod set_fact: - resolvable_db_host: "{{ ansible_operator_meta.name }}-postgres.{{ ansible_operator_meta.namespace }}.svc" # yamllint disable-line rule:line-length + resolvable_db_host: "{{ old_postgres_svc['resources'][0]['metadata']['name'] }}.{{ ansible_operator_meta.namespace }}.svc" # yamllint disable-line rule:line-length no_log: "{{ no_log }}" - name: Set pg_dump command @@ -110,23 +120,32 @@ kind: StatefulSet api_version: v1 namespace: "{{ ansible_operator_meta.namespace }}" - name: "{{ ansible_operator_meta.name }}-postgres" + name: "{{ item }}" state: absent wait: true + loop: + - "{{ ansible_operator_meta.name }}-postgres" + - "{{ ansible_operator_meta.name }}-postgres-13" - name: Remove old Postgres Service k8s: kind: Service api_version: v1 namespace: "{{ ansible_operator_meta.namespace }}" - name: "{{ ansible_operator_meta.name }}-postgres" + name: "{{ item }}" state: absent + loop: + - "{{ ansible_operator_meta.name }}-postgres" + - "{{ ansible_operator_meta.name }}-postgres-13" - name: Remove old persistent volume claim k8s: kind: PersistentVolumeClaim api_version: v1 namespace: "{{ ansible_operator_meta.namespace }}" - name: "postgres-{{ ansible_operator_meta.name }}-postgres-0" + name: "{{ item }}" state: absent + loop: + - "postgres-{{ ansible_operator_meta.name }}-postgres-0" + - "postgres-{{ ansible_operator_meta.name }}-postgres-13-0" when: postgres_keep_pvc_after_upgrade diff --git a/roles/installer/vars/main.yml b/roles/installer/vars/main.yml index 16c332c27..01fc74833 100644 --- a/roles/installer/vars/main.yml +++ b/roles/installer/vars/main.yml @@ -5,3 +5,5 @@ ldap_cacert_ca_crt: '' bundle_ca_crt: '' projects_existing_claim: '' supported_pg_version: 15 +_previous_upgraded_pg_version: 0 +old_postgres_pod: []