From 81ace824fa152293d3bd2038498325d708d931c2 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 08:27:31 +0200 Subject: [PATCH 01/17] PMM-13928: Patroni setup --- pmm_qa/__init__.py | 0 .../data/etcd-primary.conf.yaml.j2 | 9 + .../data/etcd-replica.conf.yaml.j2 | 9 + .../data/etcd.conf.yaml.j2 | 12 + .../data/patroni.yml.j2 | 81 ++++++ .../data/pg_hba.conf.j2 | 3 + .../data/pg_hba_replica.conf.j2 | 3 + .../data/postgres-replica.conf | 14 + .../data/postgresql-primary.conf | 16 ++ .../percona-distribution-postgres-setup.yml | 36 +++ .../tasks/install_pg_stat-monitor.yml | 49 ++++ ...na-distribution-postgres-patroni-setup.yml | 129 +++++++++ ...istribution-postgres-replication-setup.yml | 234 ++++++++++++++++ .../tasks/prepare_etcd.yml | 27 ++ .../percona_server/percona-server-setup.yml | 9 +- ...up.yml => percona-server-setup-single.yml} | 0 pmm_qa/pmm-framework.py | 235 +++++----------- pmm_qa/postgresql/data/pg_hba.conf.j2 | 3 + pmm_qa/postgresql/data/postgres-replica.conf | 6 + .../postgresql/data/postgresql-primary.conf | 10 + pmm_qa/postgresql/postgresql-setup.yml | 233 ++++++++++++++++ pmm_qa/postgresql/tasks/run_load_pgsql.yml | 57 ++++ pmm_qa/scripts/__init__.py | 0 pmm_qa/scripts/database_options.py | 77 +++++ pmm_qa/scripts/get_env_value.py | 20 ++ pmm_qa/scripts/run_ansible_playbook.py | 32 +++ pmm_qa/tasks/add_mysql_to_pmm_server.yml | 2 +- pmm_qa/tasks/install_pmm_client.yml | 263 ++++++++++++++++++ pmm_qa/tasks/install_pmm_client_centos.yml | 29 -- 29 files changed, 1403 insertions(+), 195 deletions(-) create mode 100644 pmm_qa/__init__.py create mode 100644 pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 create mode 100644 pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 create mode 100644 pmm_qa/percona-distribution-postgresql/data/etcd.conf.yaml.j2 create mode 100644 pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 create mode 100644 pmm_qa/percona-distribution-postgresql/data/pg_hba.conf.j2 create mode 100644 pmm_qa/percona-distribution-postgresql/data/pg_hba_replica.conf.j2 create mode 100644 pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf create mode 100644 pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf create mode 100644 pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml create mode 100644 pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml create mode 100644 pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml create mode 100644 pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml create mode 100644 pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml rename pmm_qa/percona_server/tasks/{percona-server-setup.yml => percona-server-setup-single.yml} (100%) create mode 100644 pmm_qa/postgresql/data/pg_hba.conf.j2 create mode 100644 pmm_qa/postgresql/data/postgres-replica.conf create mode 100644 pmm_qa/postgresql/data/postgresql-primary.conf create mode 100644 pmm_qa/postgresql/postgresql-setup.yml create mode 100644 pmm_qa/postgresql/tasks/run_load_pgsql.yml create mode 100644 pmm_qa/scripts/__init__.py create mode 100644 pmm_qa/scripts/database_options.py create mode 100644 pmm_qa/scripts/get_env_value.py create mode 100644 pmm_qa/scripts/run_ansible_playbook.py create mode 100644 pmm_qa/tasks/install_pmm_client.yml delete mode 100644 pmm_qa/tasks/install_pmm_client_centos.yml diff --git a/pmm_qa/__init__.py b/pmm_qa/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 new file mode 100644 index 00000000..114ead42 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 @@ -0,0 +1,9 @@ +name: 'node1' +initial-cluster-token: PostgreSQL_HA_Cluster_1 +initial-cluster-state: new +initial-cluster: node1=http://pdpgsql_pmm_{{ pg_version }}_1:2380,node2=http://pdpgsql_pmm_{{ pg_version }}_2:2380,node3=http://pdpgsql_pmm_{{ pg_version }}_3:2380 +data-dir: /var/lib/etcd +initial-advertise-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2380 +listen-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2380 +advertise-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 +listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 new file mode 100644 index 00000000..8b6d5c21 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 @@ -0,0 +1,9 @@ +name: 'node {{ item }}' +initial-cluster-token: PostgreSQL_HA_Cluster_1 +initial-cluster-state: new +initial-cluster: node1=http://pdpgsql_pmm_{{ pg_version }}_1:2380,node2=http://pdpgsql_pmm_{{ pg_version }}_2:2380,node3=http://pdpgsql_pmm_{{ pg_version }}_3:2380 +data-dir: /var/lib/etcd +initial-advertise-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2380 +listen-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2380 +advertise-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 +listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd.conf.yaml.j2 new file mode 100644 index 00000000..6ecb4235 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/etcd.conf.yaml.j2 @@ -0,0 +1,12 @@ +name: 'node{{item}}' +data-dir: /var/lib/etcd +initial-cluster-token: PostgreSQL_HA_Cluster_1 +initial-cluster-state: new + +listen-peer-urls: http://0.0.0.0:2380 +initial-advertise-peer-urls: http://pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}:2380 + +listen-client-urls: http://0.0.0.0:2379 +advertise-client-urls: http://pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}:2379 + +initial-cluster: node1=http://pdpgsql_pmm_patroni_{{ pg_version }}_1:2380,node2=http://pdpgsql_pmm_patroni_{{ pg_version }}_2:2380,node3=http://pdpgsql_pmm_patroni_{{ pg_version }}_3:2380 diff --git a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 new file mode 100644 index 00000000..71bcb414 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 @@ -0,0 +1,81 @@ +scope: patroni_cls +namespace: /var/lib/pgsql/config/ +name: pg_node_{{ item }} + +restapi: + listen: 0.0.0.0:8008 + connect_address: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}:8008" + +etcd3: + host: "pdpgsql_pmm_patroni_{{ pg_version }}_1:2379" + +bootstrap: + dcs: + ttl: 30 + loop_wait: 10 + retry_timeout: 10 + maximum_lag_on_failover: 1048576 + + postgresql: + use_pg_rewind: true + use_slots: true + parameters: + wal_level: replica + hot_standby: "on" + wal_keep_size: 128MB + max_wal_senders: 10 + max_replication_slots: 10 + wal_log_hints: "on" + archive_mode: "on" + archive_timeout: 600s + archive_command: "cp -f %p /home/postgres/archived/%f" + pg_hba: + - host replication replicator 127.0.0.1/32 md5 + - host replication replicator 172.18.0.0/16 md5 + - host all all 0.0.0.0/0 md5 + + initdb: + - encoding: UTF8 + - data-checksums + - waldir: /pg_wal + - wal-segsize=512 + + users: + admin: + password: admin + options: + - createrole + - createdb + +postgresql: + listen: 0.0.0.0:5432 + connect_address: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}:5432" + data_dir: /var/lib/pgsql/{{ pg_version}}/data + bin_dir: /usr/pgsql-{{ pg_version }}/bin + pgpass: /tmp/pgpass + + authentication: + replication: + username: replicator + password: replPasswd + superuser: + username: postgres + password: pg1234 + + create_replica_methods: + - pgbackrest + - basebackup + + pgbackrest: + command: pgbackrest --stanza=patroni_backup restore --type=none + keep_data: true + no_params: true + + basebackup: + checkpoint: fast + +tags: + nofailover: false + noloadbalance: false + clonefrom: false + nosync: false \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/data/pg_hba.conf.j2 b/pmm_qa/percona-distribution-postgresql/data/pg_hba.conf.j2 new file mode 100644 index 00000000..8488d8cc --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/pg_hba.conf.j2 @@ -0,0 +1,3 @@ +host replication {{ replication_user }} 0.0.0.0/0 md5 +host all all 0.0.0.0/0 md5 +local all postgres trust diff --git a/pmm_qa/percona-distribution-postgresql/data/pg_hba_replica.conf.j2 b/pmm_qa/percona-distribution-postgresql/data/pg_hba_replica.conf.j2 new file mode 100644 index 00000000..8488d8cc --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/pg_hba_replica.conf.j2 @@ -0,0 +1,3 @@ +host replication {{ replication_user }} 0.0.0.0/0 md5 +host all all 0.0.0.0/0 md5 +local all postgres trust diff --git a/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf b/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf new file mode 100644 index 00000000..b6a3d6ba --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf @@ -0,0 +1,14 @@ +hba_file = '/etc/postgresql/pg_hba.conf' +shared_preload_libraries = 'pg_stat_monitor' +track_activity_query_size=2048 +track_io_timing=ON +max_connections=1000 +listen_addresses = '*' +pg_stat_monitor.pgsm_enable_query_plan = 'yes' +pg_stat_monitor.pgsm_query_max_len = 2048 +pg_stat_monitor.pgsm_normalized_query=1 +pg_stat_monitor.pgsm_enable_query_plan=1 +log_connections = on +log_disconnections = on +log_replication_commands = on +log_statement = 'all' \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf b/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf new file mode 100644 index 00000000..65b7a68f --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf @@ -0,0 +1,16 @@ +wal_level = replica +max_wal_senders = 10 +wal_keep_size = 64MB +hot_standby = on +listen_addresses = '*' +hba_file = '/etc/postgresql/pg_hba.conf' +shared_preload_libraries = 'pg_stat_monitor' +track_activity_query_size=2048 +track_io_timing=ON +max_connections=1000 +listen_addresses = '*' +pg_stat_monitor.pgsm_enable_query_plan = 'yes' +log_connections = on +log_disconnections = on +log_replication_commands = on +log_statement = 'all' \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml b/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml new file mode 100644 index 00000000..aacb622c --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml @@ -0,0 +1,36 @@ +--- +# Percona Distribution Postgresql Replication +- name: Setup Postgresql replication + hosts: localhost + connection: local + gather_facts: yes + vars: + pg_version: "{{ lookup('env', 'PGSQL_VERSION') | default('17', true) }}" + replication_user: "repl_user" + replication_password: "GRgrO9301RuF" + root_password: "GRgrO9301RuF" + pdpgsql_port: 5432 + nodes_count: "{{ (lookup('env', 'NODES_COUNT') | default('2', true)) | int }}" + network_name: "pmm-qa" + data_dir: "{{ lookup('env', 'HOME') }}/pgsql_cluster_data" + pmm_server_ip: "{{ lookup('vars', 'extra_pmm_server_ip', default=lookup('env','PMM_SERVER_IP') | default('127.0.0.1', true) ) }}" + client_version: "{{ lookup('vars', 'extra_client_version', default=lookup('env','CLIENT_VERSION') | default('3-dev-latest', true) ) }}" + admin_password: "{{ lookup('vars', 'extra_admin_password', default=lookup('env','ADMIN_PASSWORD') | default('admin', true) ) }}" + query_source: "{{ lookup('env', 'QUERY_SOURCE') | default('pgstatements', true) }}" + metrics_mode: "auto" + setup_type: "{{ lookup('env', 'SETUP_TYPE') }}" + random_service_name_value: "" + docker_repo: "percona/percona-distribution-postgresql" + + tasks: + - name: Display binary log status for primary + debug: + msg: "{{ setup_type }}" + + - name: Install Percona Distribution for Postgres with Replication + include_tasks: tasks/percona-distribution-postgres-replication-setup.yml + when: setup_type == "replication" + + - name: Install Percona Distribution for Postgres with Patroni replication + include_tasks: tasks/percona-distribution-postgres-patroni-setup.yml + when: setup_type == "patroni" \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml b/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml new file mode 100644 index 00000000..85a6d57f --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml @@ -0,0 +1,49 @@ +- name: Detect OS inside the container + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + command: cat /etc/os-release + register: container_os_info + +- name: Set distro family (debian/rhel) + set_fact: + distro_family: >- + {{ + ( + 'debian' if 'debian' in container_os_info.stdout | lower else + 'rhel' if 'rhel' in container_os_info.stdout | lower or 'centos' in container_os_info.stdout | lower or 'fedora' in container_os_info.stdout | lower + else 'unknown' + ) | trim + }} + +- name: Install dependencies inside Debian-family container + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + command: > + sh -c ' + apt-get update && + apt-get install percona-pg-stat-monitor{{ pg_version }} + ' + user: "root" + when: distro_family == "debian" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Install dependencies inside RHEL-family container + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + command: > + sh -c ' + microdnf install percona-pg-stat-monitor{{ pg_version }} + ' + user: "root" + when: distro_family == "rhel" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Create pg_stat_statements extension + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + psql -U postgres -d 'postgres' -c " + CREATE EXTENSION IF NOT EXISTS pg_stat_monitor; + SELECT pg_stat_monitor_version(); + " diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml new file mode 100644 index 00000000..629f8830 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -0,0 +1,129 @@ +- name: Set correct nodes count for patroni setup + set_fact: + nodes_count: 3 + when: nodes_count | int < 3 + +- name: Remove old data folders + shell: 'rm -fr {{ data_dir }}' + +- name: Create data directories + file: + path: "{{ data_dir }}/node{{ item }}/data" + state: directory + mode: '0755' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Fix permissions on data directory + become: true + file: + path: "{{ data_dir }}/node{{ item }}/data" + owner: 1001 + group: 1001 + recurse: yes + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Generate etcd configuration + template: + src: data/etcd.conf.yaml.j2 + dest: "{{ data_dir }}/node{{ item }}/etcd.conf.yaml" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Generate patroni configuration + template: + src: data/patroni.yml.j2 + dest: "{{ data_dir }}/node{{ item }}/patroni.yml" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Create Docker network + community.docker.docker_network: + name: "{{ network_name }}" + state: present + ignore_errors: yes + +- name: Start PostgreSQL containers + community.docker.docker_container: + name: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + image: oraclelinux:9 + state: started + restart_policy: always + command: sleep infinity + networks: + - name: "{{ network_name }}" + volumes: + - "{{ data_dir }}/node{{ item }}/data:/data/db" + - "{{ data_dir }}/node{{ item }}/etcd.conf.yaml:/etcd.conf.yaml:ro" + - "{{ data_dir }}/node{{ item }}/patroni.yml:/etc/patroni/patroni.yml:ro" + ports: + - "{{ pdpgsql_port + item - 1 }}:5432" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Install required packages in Oracle Linux container + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + user: root + command: > + /bin/sh -c ' + dnf config-manager --set-enabled ol9_codeready_builder + dnf install perl-IPC-Run -y + dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + dnf config-manager --set-enabled crb + dnf install -y python3-pip python3-devel binutils python3-click + ' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Install Percona Distribution for PostgresSQL + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + user: root + command: > + /bin/sh -c ' + dnf module disable postgresql + dnf install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm + percona-release enable ppg-{{ pg_version }} + dnf install -y percona-postgresql{{ pg_version }}-server percona-patroni etcd python3-python-etcd percona-pgbackrest + patroni --version + ' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Start etcd service + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + user: root + command: > + /bin/sh -c ' + rm -rf /var/lib/pgsql/{{ pg_version }}/data/* + ps aux | grep postgres + rm -f /data/db/postmaster.pid + mkdir -p /data/db/logs + mkdir /pg_wal + touch /dev/watchdog + nohup etcd --config-file /etcd.conf.yaml > /data/db/logs/etcd.log 2>&1 & + chown -R postgres:postgres /data/db/logs + chown -R postgres:postgres /dev/watchdog + chown -R postgres:postgres /pg_wal + ' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + + +- name: Wait 5 seconds to etcd to start + pause: + seconds: 5 + +- name: Start patroni service + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + user: postgres + command: > + /bin/sh -c ' + nohup patroni /etc/patroni/patroni.yml > /data/db/logs/patroni.log 2>&1 & + ' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Log Patroni cluster + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_1" + command: > + /bin/sh -c ' + sleep 15 + patronictl -c /etc/patroni/patroni.yml list + ' \ No newline at end of file diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml new file mode 100644 index 00000000..70a58f91 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml @@ -0,0 +1,234 @@ +- name: Create Docker network + community.docker.docker_network: + name: "{{ network_name }}" + state: present + ignore_errors: yes + +- name: Remove old data folders + shell: 'rm -fr {{ data_dir }}' + +- name: Create data directories + file: + path: "{{ data_dir }}/node{{ item }}/data" + state: directory + mode: '0755' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Generate pg_hba.conf for primary node + template: + src: data/pg_hba.conf.j2 + dest: "{{ data_dir }}/node1/pg_hba.conf" + +- name: Generate pg_hba.conf for replica node + template: + src: data/pg_hba_replica.conf.j2 + dest: "{{ data_dir }}/node{{ item }}/pg_hba.conf" + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Fix permissions on data directory + become: true + file: + path: "{{ data_dir }}/node{{ item }}/data" + owner: 1001 + group: 1001 + recurse: yes + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Remove old PostgreSQL primary container + community.docker.docker_container: + name: "pdpgsql_pmm_{{ pg_version }}_1" + image: "{{ docker_repo }}:{{ pg_version }}" + restart_policy: always + state: absent + ignore_errors: yes + +- name: Start PostgreSQL primary container + community.docker.docker_container: + name: "pdpgsql_pmm_{{ pg_version }}_1" + image: "{{ docker_repo }}:{{ pg_version }}" + restart_policy: always + state: started + recreate: true + networks: + - name: "{{ network_name }}" + env: + POSTGRES_PASSWORD: "{{ root_password }}" + volumes: + - "{{ data_dir }}/node1/data:/data/db" + - "./data/postgresql-primary.conf:/etc/postgresql/postgresql.conf:ro" + - "{{ data_dir }}/node1/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro" + command: -c config_file=/etc/postgresql/postgresql.conf + ports: + - "{{ pdpgsql_port }}:5432" + +- name: Wait for PgSQL to be available + wait_for: + host: localhost + port: "{{ pdpgsql_port }}" + delay: 10 + timeout: 300 + +- name: Create replication user + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + psql -c " + CREATE ROLE {{ replication_user }} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '{{ replication_password }}'; + " + +- name: Stop and remove replica if exists + community.docker.docker_container: + name: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + state: absent + loop: "{{ range(2, nodes_count | int + 1) | list }}" + ignore_errors: yes + +- name: Start Percona Distribution PostgreSQL replica container + community.docker.docker_container: + name: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + image: "{{ docker_repo }}:{{ pg_version }}" + restart_policy: "no" + state: started + command: sleep infinity + networks: + - name: "{{ network_name }}" + env: + POSTGRES_INITDB_SKIP: "yes" + POSTGRES_PASSWORD: "{{ root_password }}" + volumes: + - "{{ data_dir }}/node{{ item }}/data:/data/db" + - "./data/postgres-replica.conf:/etc/postgresql/postgresql.conf:ro" + - "{{ data_dir }}/node{{ item }}/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro" + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Wipe replica data directory before basebackup + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + user: root + command: rm -rf /data/db/* + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Create PostgreSQL user 'pmm' with password + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + bash -c ' + psql -U postgres -d {{ db_name | default("postgres") }} -c " + CREATE USER pmm WITH PASSWORD '\''pmm'\''; + GRANT pg_monitor TO pmm; + " + ' + +- name: Create custom database for pgbench + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + bash -c " + echo \" + CREATE DATABASE pgbench; + \\c pgbench + GRANT CONNECT ON DATABASE pgbench TO pmm; + GRANT USAGE ON SCHEMA public TO pmm; + GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO pmm; + ALTER DEFAULT PRIVILEGES IN SCHEMA public + GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO pmm; + \" | psql -U postgres -v ON_ERROR_STOP=1 + " + +- name: Run pg_basebackup from primary to replica + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + user: root + command: > + bash -c " + export PGPASSWORD='{{ replication_password }}' && \ + timeout 120s \ + pg_basebackup --pgdata=/data/db -R -v -Fp -Xs -P \ + --host=pdpgsql_pmm_{{ pg_version }}_1 --port=5432 -U {{ replication_user }} > /tmp/pg_basebackup.log 2>&1 + " + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Remove temporary backup container + docker_container: + name: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + state: absent + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Fix permissions on data directory + become: true + file: + path: "{{ data_dir }}/node{{ item }}/data" + owner: 1001 + group: 1001 + recurse: yes + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Restart Percona Distribution PostgreSQL container with custom command + community.docker.docker_container: + name: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + image: "{{ docker_repo }}:{{ pg_version }}" + restart: true + state: started + command: -c config_file=/etc/postgresql/postgresql.conf + networks: + - name: "{{ network_name }}" + env: + POSTGRES_PASSWORD: "{{ root_password }}" + volumes: + - "{{ data_dir }}/node{{ item }}/data:/data/db" + - "./data/postgres-replica.conf:/etc/postgresql/postgresql.conf:ro" + - "{{ data_dir }}/node1/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro" + ports: + - "{{ pdpgsql_port + item - 1}}:5432" + loop: "{{ range(2, nodes_count | int + 1) | list }}" + +- name: Install pg stat monitor. + include_tasks: ./tasks/install_pg_stat-monitor.yml + +- name: Install and add pmm client. + include_tasks: ../tasks/install_pmm_client.yml + vars: + container_name: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Get already connected services to pmm server + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + command: > + sh -c 'curl --location --insecure -u"admin:{{ admin_password }}" -s --request GET "http://{{ pmm_server_ip }}:{{ '80' if pmm_server_ip is ansible.utils.ipv4 else '8080' }}/v1/management/services" | jq -r ".services[].service_name"' + register: pmm_server_services + +- name: Display already connected services to pmm server + debug: + msg: "{{ pmm_server_services.stdout | split('\n') }}" + +- name: Find out if service is already connected to pmm server + block: + - name: Loop through percona servers + set_fact: + random_service_name_value: "_{{ 9999 | random + 1 }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + when: "('pdpgsql_pmm_' ~ pg_version ~ '_' ~ item) in pmm_server_services.stdout" + +- name: Add service to pmm server + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + command: pmm-admin add postgresql --username=pmm --password=pmm --query-source=pgstatmonitor pdpgsql_pmm_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Run load on primary node. + include_tasks: ../postgresql/tasks/run_load_pgsql.yml + vars: + node_name: "pdpgsql_pmm_{{ pg_version }}_1" + pgbench_clients: 10 + pgbench_time: 120 + pgbench_scale: 1000 + +- name: Check replication status on primary + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + user: postgres + command: psql -c "SELECT * FROM pg_stat_replication;" diff --git a/pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml b/pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml new file mode 100644 index 00000000..5e3b8128 --- /dev/null +++ b/pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml @@ -0,0 +1,27 @@ +- name: Start etcd container + community.docker.docker_container: + name: "{{ etcd_container_name }}" + image: oraclelinux:9 + state: started + restart_policy: always + command: sleep infinity + +- name: Install required packages in Oracle Linux container + community.docker.docker_container_exec: + container: "{{ etcd_container_name }}" + command: > + /bin/sh -c ' + DOWNLOAD_URL=$(curl -s https://api.github.com/repos/etcd-io/etcd/releases/latest | grep "browser_download_url" | grep "linux-amd64.tar.gz" | sed -E "s/.*\"browser_download_url\": *\"(.*)\"/\1/") && + echo "URLS is: $DOWNLOAD_URL" && + FILENAME=$(basename "$DOWNLOAD_URL" .tar.gz) && + echo "Filename is: $FILENAME" && + curl -L -o etcd-latest.tar.gz https://github.com/etcd-io/etcd/releases/download/v3.6.1/etcd-v3.6.1-linux-amd64.tar.gz && + mkdir -p /etcd-latest + tar -xzf etcd-latest.tar.gz && + ls && + ls /$FILENAME && + cd $FILENAME && + mv etcd etcdctl /usr/local/bin/ && + etcd --version && + etcdctl version + ' \ No newline at end of file diff --git a/pmm_qa/percona_server/percona-server-setup.yml b/pmm_qa/percona_server/percona-server-setup.yml index 4af81dcd..35227759 100644 --- a/pmm_qa/percona_server/percona-server-setup.yml +++ b/pmm_qa/percona_server/percona-server-setup.yml @@ -21,6 +21,7 @@ client_version: "{{ lookup('vars', 'extra_client_version', default=lookup('env','CLIENT_VERSION') | default('3-dev-latest', true) ) }}" admin_password: "{{ lookup('vars', 'extra_admin_password', default=lookup('env','ADMIN_PASSWORD') | default('admin', true) ) }}" query_source: "{{ lookup('env', 'QUERY_SOURCE') | default('perfschema', true) }}" + metrics_mode: "{{ lookup('env', 'metrics_mode') }}" setup_type: "{{ lookup('env', 'SETUP_TYPE') }}" random_service_name_value: "" @@ -40,7 +41,7 @@ name: "{{ network_name }}" state: present - - name: "Remove old data folders" + - name: Remove old data folders shell: 'rm -fr {{ data_dir }}' loop: "{{ range(1, nodes_count | int + 1) | list }}" @@ -73,7 +74,7 @@ when: setup_type == "replication" - name: Setup Percona Server - include_tasks: ./tasks/percona-server-setup.yml + include_tasks: tasks/percona-server-setup-single.yml when: setup_type != "gr" and setup_type != "replication" - name: Create slowlog configuration for mysql nodes @@ -90,7 +91,7 @@ when: query_source == "slowlog" - name: Install and add pmm client. - include_tasks: ../tasks/install_pmm_client_centos.yml + include_tasks: ../tasks/install_pmm_client.yml vars: container_name: "ps_pmm_{{ ps_version }}_{{ item }}" loop: "{{ range(1, nodes_count | int + 1) | list }}" @@ -230,6 +231,6 @@ --tables=10 --table-size=100000 --threads=16 - --time=60 + --time=60 run loop: "{{ range(1, nodes_count | int + 1) | list }}" diff --git a/pmm_qa/percona_server/tasks/percona-server-setup.yml b/pmm_qa/percona_server/tasks/percona-server-setup-single.yml similarity index 100% rename from pmm_qa/percona_server/tasks/percona-server-setup.yml rename to pmm_qa/percona_server/tasks/percona-server-setup-single.yml diff --git a/pmm_qa/pmm-framework.py b/pmm_qa/pmm-framework.py index 5538e53b..5e797eae 100755 --- a/pmm_qa/pmm-framework.py +++ b/pmm_qa/pmm-framework.py @@ -2,119 +2,11 @@ import argparse import os import sys -import ansible_runner import requests import re - -# Database configurations -database_configs = { - "PSMDB": { - "versions": ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "COMPOSE_PROFILES": "classic", - "TARBALL": ""} - }, - "MLAUNCH_PSMDB": { - "versions": ["4.4", "5.0", "6.0", "7.0", "8.0"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "TARBALL": ""} - }, - "MLAUNCH_MODB": { - "versions": ["4.4", "5.0", "6.0", "7.0", "8.0"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "TARBALL": ""} - }, - "SSL_MLAUNCH": { - "versions": ["4.4", "5.0", "6.0", "7.0", "8.0"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "COMPOSE_PROFILES": "classic", - "TARBALL": ""} - }, - "SSL_PSMDB": { - "versions": ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "COMPOSE_PROFILES": "classic", - "TARBALL": ""} - }, - "MYSQL": { - "versions": ["8.4", "8.0"], - "configurations": {"QUERY_SOURCE": "perfschema", "SETUP_TYPE": "", "CLIENT_VERSION": "3-dev-latest", - "TARBALL": ""} - }, - "PS": { - "versions": ["5.7", "8.4", "8.0"], - "configurations": {"QUERY_SOURCE": "perfschema", "SETUP_TYPE": "", "CLIENT_VERSION": "3-dev-latest", - "TARBALL": "", "NODES_COUNT": 1} - }, - "SSL_MYSQL": { - "versions": ["5.7", "8.4", "8.0"], - "configurations": {"QUERY_SOURCE": "perfschema", "SETUP_TYPE": "", "CLIENT_VERSION": "3-dev-latest", - "TARBALL": ""} - }, - "PGSQL": { - "versions": ["11", "12", "13", "14", "15", "16", "17"], - "configurations": {"QUERY_SOURCE": "pgstatements", "CLIENT_VERSION": "3-dev-latest", "USE_SOCKET": ""} - }, - "PDPGSQL": { - "versions": ["11", "12", "13", "14", "15", "16", "17"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "USE_SOCKET": ""} - }, - "SSL_PDPGSQL": { - "versions": ["11", "12", "13", "14", "15", "16", "17"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "USE_SOCKET": ""} - }, - "PXC": { - "versions": ["5.7", "8.0"], - "configurations": {"CLIENT_VERSION": "3-dev-latest", "QUERY_SOURCE": "perfschema", "TARBALL": ""} - }, - "PROXYSQL": { - "versions": ["2"], - "configurations": {"PACKAGE": ""} - }, - "HAPROXY": { - "versions": [""], - "configurations": {"CLIENT_VERSION": "3-dev-latest"} - }, - "EXTERNAL": { - "REDIS": { - "versions": ["1.14.0", "1.58.0"], - }, - "NODEPROCESS": { - "versions": ["0.7.5", "0.7.10"], - }, - "configurations": {"CLIENT_VERSION": "3-dev-latest"} - }, - "DOCKERCLIENTS": { - "configurations": {} # Empty dictionary for consistency - }, -} - - -def run_ansible_playbook(playbook_filename, env_vars, args): - # Get Script Dir - script_path = os.path.abspath(sys.argv[0]) - script_dir = os.path.dirname(script_path) - playbook_path = script_dir + "/" + playbook_filename - verbosity_level = 1 - - - - if args.verbosity_level is not None: - verbosity_level = int(args.verbosity_level) - - if args.verbose: - print(f'Options set after considering Defaults: {env_vars}') - - r = ansible_runner.run( - private_data_dir=script_dir, - playbook=playbook_path, - inventory='127.0.0.1', - cmdline='-l localhost, --connection=local', - envvars=env_vars, - suppress_env_files=True, - verbosity=verbosity_level, - ) - - print(f'{playbook_filename} playbook execution {r.status}') - - if r.rc != 0: - exit(1) - +from scripts.get_env_value import get_value +from scripts.database_options import database_options as database_configs +from scripts.run_ansible_playbook import run_ansible_playbook def get_running_container_name(): container_image_name = "pmm-server" @@ -151,26 +43,6 @@ def get_running_container_name(): return None - -def get_value(key, db_type, args, db_config): - # Check if the variable exists in the environment - env_value = os.environ.get(key) - if env_value is not None: - return env_value - - # Only for client_version we accept global command line argument - if key == "CLIENT_VERSION" and args.client_version is not None: - return args.client_version - - # Check if the variable exists in the args config - config_value = db_config.get(key) - if config_value is not None: - return config_value - - # Fall back to default configs value or empty '' - return database_configs[db_type]["configurations"].get(key, '') - - def setup_ps(db_type, db_version=None, db_config=None, args=None): # Check if PMM server is running container_name = get_running_container_name() @@ -236,6 +108,7 @@ def setup_mysql(db_type, db_version=None, db_config=None, args=None): # Gather Version details ms_version = os.getenv('MS_VERSION') or db_version or database_configs[db_type]["versions"][-1] + ms_version_int = int(ms_version.replace(".", "")) # Check Setup Types setup_type = '' @@ -268,7 +141,6 @@ def setup_mysql(db_type, db_version=None, db_config=None, args=None): # Call the function to run the Ansible playbook run_ansible_playbook(playbook_filename, env_vars, args) - def setup_ssl_mysql(db_type, db_version=None, db_config=None, args=None): # Check if PMM server is running container_name = get_running_container_name() @@ -309,23 +181,44 @@ def setup_pdpgsql(db_type, db_version=None, db_config=None, args=None): # Gather Version details pdpgsql_version = os.getenv('PDPGSQL_VERSION') or db_version or database_configs[db_type]["versions"][-1] + setup_type_value = get_value('SETUP_TYPE', db_type, args, db_config).lower() + print(f"Setup type is {setup_type_value}") - # Define environment variables for playbook - env_vars = { - 'PGSTAT_MONITOR_BRANCH': 'main', - 'PDPGSQL_VERSION': pdpgsql_version, - 'PMM_SERVER_IP': args.pmm_server_ip or container_name or '127.0.0.1', - 'PDPGSQL_PGSM_CONTAINER': 'pdpgsql_pgsm_pmm_' + str(pdpgsql_version), - 'CLIENT_VERSION': get_value('CLIENT_VERSION', db_type, args, db_config), - 'USE_SOCKET': get_value('USE_SOCKET', db_type, args, db_config), - 'ADMIN_PASSWORD': os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin', - 'PDPGSQL_PGSM_PORT': 5447, - 'DISTRIBUTION': '', - 'PMM_QA_GIT_BRANCH': os.getenv('PMM_QA_GIT_BRANCH') or 'v3' - } + if setup_type_value in ("replication", "replica", "patroni"): + # Define environment variables for playbook + env_vars = { + 'PGSTAT_MONITOR_BRANCH': 'main', + 'PDPGSQL_VERSION': pdpgsql_version, + 'PMM_SERVER_IP': args.pmm_server_ip or container_name or '127.0.0.1', + 'PDPGSQL_PGSM_CONTAINER': 'pdpgsql_pgsm_pmm_' + str(pdpgsql_version), + 'CLIENT_VERSION': get_value('CLIENT_VERSION', db_type, args, db_config), + 'USE_SOCKET': get_value('USE_SOCKET', db_type, args, db_config), + 'ADMIN_PASSWORD': os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin', + 'PDPGSQL_PGSM_PORT': 5447, + 'DISTRIBUTION': '', + 'PMM_QA_GIT_BRANCH': os.getenv('PMM_QA_GIT_BRANCH') or 'v3', + 'SETUP_TYPE': setup_type_value + } - # Ansible playbook filename - playbook_filename = 'pdpgsql_pgsm_setup.yml' + # Ansible playbook filename + playbook_filename = 'percona-distribution-postgresql/percona-distribution-postgres-setup.yml' + else: + # Define environment variables for playbook + env_vars = { + 'PGSTAT_MONITOR_BRANCH': 'main', + 'PDPGSQL_VERSION': pdpgsql_version, + 'PMM_SERVER_IP': args.pmm_server_ip or container_name or '127.0.0.1', + 'PDPGSQL_PGSM_CONTAINER': 'pdpgsql_pgsm_pmm_' + str(pdpgsql_version), + 'CLIENT_VERSION': get_value('CLIENT_VERSION', db_type, args, db_config), + 'USE_SOCKET': get_value('USE_SOCKET', db_type, args, db_config), + 'ADMIN_PASSWORD': os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin', + 'PDPGSQL_PGSM_PORT': 5447, + 'DISTRIBUTION': '', + 'PMM_QA_GIT_BRANCH': os.getenv('PMM_QA_GIT_BRANCH') or 'v3' + } + + # Ansible playbook filename + playbook_filename = 'pdpgsql_pgsm_setup.yml' # Call the function to run the Ansible playbook run_ansible_playbook(playbook_filename, env_vars, args) @@ -369,21 +262,41 @@ def setup_pgsql(db_type, db_version=None, db_config=None, args=None): # Gather Version details pgsql_version = os.getenv('PGSQL_VERSION') or db_version or database_configs[db_type]["versions"][-1] + setup_type_value = get_value('SETUP_TYPE', db_type, args, db_config).lower() - # Define environment variables for playbook - env_vars = { - 'PGSQL_VERSION': pgsql_version, - 'PMM_SERVER_IP': args.pmm_server_ip or container_name or '127.0.0.1', - 'PGSQL_PGSS_CONTAINER': 'pgsql_pgss_pmm_' + str(pgsql_version), - 'CLIENT_VERSION': get_value('CLIENT_VERSION', db_type, args, db_config), - 'USE_SOCKET': get_value('USE_SOCKET', db_type, args, db_config), - 'ADMIN_PASSWORD': os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin', - 'PGSQL_PGSS_PORT': 5448, - 'PMM_QA_GIT_BRANCH': os.getenv('PMM_QA_GIT_BRANCH') or 'v3' - } + print(f"Setup type is {setup_type_value}") - # Ansible playbook filename - playbook_filename = 'pgsql_pgss_setup.yml' + if setup_type_value in ("replication", "replica"): + # Define environment variables for playbook + env_vars = { + 'PGSQL_VERSION': pgsql_version, + 'PMM_SERVER_IP': args.pmm_server_ip or container_name or '127.0.0.1', + 'PGSQL_PGSS_CONTAINER': 'pgsql_pgss_pmm_' + str(pgsql_version), + 'CLIENT_VERSION': get_value('CLIENT_VERSION', db_type, args, db_config), + 'USE_SOCKET': get_value('USE_SOCKET', db_type, args, db_config), + 'ADMIN_PASSWORD': os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin', + 'PGSQL_PGSS_PORT': 5448, + 'PMM_QA_GIT_BRANCH': os.getenv('PMM_QA_GIT_BRANCH') or 'v3', + 'SETUP_TYPE': setup_type_value + } + + # Ansible playbook filename + playbook_filename = 'postgresql/postgresql-setup.yml' + else: + # Define environment variables for playbook + env_vars = { + 'PGSQL_VERSION': pgsql_version, + 'PMM_SERVER_IP': args.pmm_server_ip or container_name or '127.0.0.1', + 'PGSQL_PGSS_CONTAINER': 'pgsql_pgss_pmm_' + str(pgsql_version), + 'CLIENT_VERSION': get_value('CLIENT_VERSION', db_type, args, db_config), + 'USE_SOCKET': get_value('USE_SOCKET', db_type, args, db_config), + 'ADMIN_PASSWORD': os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin', + 'PGSQL_PGSS_PORT': 5448, + 'PMM_QA_GIT_BRANCH': os.getenv('PMM_QA_GIT_BRANCH') or 'v3' + } + + # Ansible playbook filename + playbook_filename = 'pgsql_pgss_setup.yml' # Call the function to run the Ansible playbook run_ansible_playbook(playbook_filename, env_vars, args) @@ -690,7 +603,7 @@ def mongo_ssl_setup(script_filename, args): ['cp', f'{scripts_path}docker-compose-pmm-psmdb.yml', f'{compose_file_path}']) admin_password = os.getenv('ADMIN_PASSWORD') or args.pmm_server_password or 'admin' subprocess.run(['sed', '-i', f's/PMM_AGENT_SERVER_PASSWORD=admin/PMM_AGENT_SERVER_PASSWORD={admin_password}/g', f'{compose_file_path}']) - subprocess.run(['sed', '-i', '/container_name/a\ networks:\\\n \\- pmm-qa', f'{compose_file_path}']) + subprocess.run(['sed', '-i', '/container_name/a\\ networks:\\\\n \\\\- pmm-qa', f'{compose_file_path}']) subprocess.run(['sed', '-i', '$a\\\nnetworks:\\\n pmm-qa:\\\n name: pmm-qa\\\n external: true', f'{compose_file_path}']) subprocess.run(['sed', '-i', diff --git a/pmm_qa/postgresql/data/pg_hba.conf.j2 b/pmm_qa/postgresql/data/pg_hba.conf.j2 new file mode 100644 index 00000000..43a9816a --- /dev/null +++ b/pmm_qa/postgresql/data/pg_hba.conf.j2 @@ -0,0 +1,3 @@ +host replication {{ replication_user }} 0.0.0.0/0 md5 +host all all 0.0.0.0/0 md5 +local all postgres trust diff --git a/pmm_qa/postgresql/data/postgres-replica.conf b/pmm_qa/postgresql/data/postgres-replica.conf new file mode 100644 index 00000000..9005fb12 --- /dev/null +++ b/pmm_qa/postgresql/data/postgres-replica.conf @@ -0,0 +1,6 @@ +hba_file = '/etc/postgresql/pg_hba.conf' +shared_preload_libraries = 'pg_stat_statements' +pg_stat_statements.track=all +track_io_timing=ON +track_activity_query_size=2048 +listen_addresses = '*' diff --git a/pmm_qa/postgresql/data/postgresql-primary.conf b/pmm_qa/postgresql/data/postgresql-primary.conf new file mode 100644 index 00000000..4ca543a8 --- /dev/null +++ b/pmm_qa/postgresql/data/postgresql-primary.conf @@ -0,0 +1,10 @@ +wal_level = replica +max_wal_senders = 10 +wal_keep_size = 64MB +hot_standby = on +listen_addresses = '*' +hba_file = '/etc/postgresql/pg_hba.conf' +shared_preload_libraries = 'pg_stat_statements' +pg_stat_statements.track=all +track_io_timing=ON +track_activity_query_size=2048 diff --git a/pmm_qa/postgresql/postgresql-setup.yml b/pmm_qa/postgresql/postgresql-setup.yml new file mode 100644 index 00000000..d451bd52 --- /dev/null +++ b/pmm_qa/postgresql/postgresql-setup.yml @@ -0,0 +1,233 @@ +--- +# Postgresql Replication +- name: Setup Postgresql replication + hosts: localhost + connection: local + gather_facts: yes + vars: + pg_version: "{{ lookup('env', 'PGSQL_VERSION') | default('17', true) }}" + replication_user: "repl_user" + replication_password: "GRgrO9301RuF" + root_password: "GRgrO9301RuF" + pgsql_port: 6432 + nodes_count: "{{ (lookup('env', 'NODES_COUNT') | default('2', true)) | int }}" + network_name: "pmm-qa" + data_dir: "{{ lookup('env', 'HOME') }}/pgsql_cluster_data" + pmm_server_ip: "{{ lookup('vars', 'extra_pmm_server_ip', default=lookup('env','PMM_SERVER_IP') | default('127.0.0.1', true) ) }}" + client_version: "{{ lookup('vars', 'extra_client_version', default=lookup('env','CLIENT_VERSION') | default('3-dev-latest', true) ) }}" + admin_password: "{{ lookup('vars', 'extra_admin_password', default=lookup('env','ADMIN_PASSWORD') | default('admin', true) ) }}" + query_source: "{{ lookup('env', 'QUERY_SOURCE') | default('pgstatements', true) }}" + metrics_mode: "auto" + setup_type: "{{ lookup('env', 'SETUP_TYPE') }}" + random_service_name_value: "" + + tasks: + - name: Create Docker network + community.docker.docker_network: + name: "{{ network_name }}" + state: present + ignore_errors: yes + + - name: Remove old data folders + shell: 'rm -fr {{ data_dir }}' + + - name: Create data directories + file: + path: "{{ data_dir }}/node{{ item }}/data" + state: directory + mode: '0755' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + + - name: Generate pg_hba.conf for primary node + template: + src: data/pg_hba.conf.j2 + dest: "{{ data_dir }}/node1/pg_hba.conf" + + - name: Remove old PostgreSQL primary container + community.docker.docker_container: + name: "pgsql_pmm_{{ pg_version }}_1" + image: "postgres:{{ pg_version }}-bookworm" + restart_policy: always + state: absent + ignore_errors: yes + + - name: Start PostgreSQL primary container + community.docker.docker_container: + name: "pgsql_pmm_{{ pg_version }}_1" + image: "postgres:{{ pg_version }}-bookworm" + restart_policy: always + state: started + recreate: true + networks: + - name: "{{ network_name }}" + env: + POSTGRES_PASSWORD: "{{ root_password }}" + volumes: + - "{{ data_dir }}/node1/data:/var/lib/postgresql/data" + - "./data/postgresql-primary.conf:/etc/postgresql/postgresql.conf:ro" + - "{{ data_dir }}/node1/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro" + command: -c config_file=/etc/postgresql/postgresql.conf + ports: + - "{{ pgsql_port }}:5432" + + - name: Wait for PgSQL to be available + wait_for: + host: localhost + port: "{{ pgsql_port }}" + delay: 10 + timeout: 300 + + - name: Create replication user + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + psql -c " + CREATE ROLE {{ replication_user }} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '{{ replication_password }}'; + " + + - name: Stop and remove replica if exists + community.docker.docker_container: + name: "pgsql_pmm_{{ pg_version }}_{{ item }}" + state: absent + loop: "{{ range(2, nodes_count | int + 1) | list }}" + ignore_errors: yes + + - name: Start PostgreSQL replica container + community.docker.docker_container: + name: "pgsql_pmm_{{ pg_version }}_{{ item }}" + image: "postgres:{{ pg_version }}-bookworm" + restart_policy: "no" + state: started + command: sleep infinity + networks: + - name: "{{ network_name }}" + env: + POSTGRES_PASSWORD: "{{ root_password }}" + volumes: + - "{{ data_dir }}/node{{ item }}/data:/var/lib/postgresql/data" + - "./data/postgresql-replica.conf:/etc/postgresql/postgresql.conf:ro" + - "{{ data_dir }}/node1/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro" + loop: "{{ range(2, nodes_count | int + 1) | list }}" + + - name: Wipe replica data directory before basebackup + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_{{ item }}" + user: root + command: rm -rf /var/lib/postgresql/data/* + loop: "{{ range(2, nodes_count | int + 1) | list }}" + + - name: Create PostgreSQL user 'pmm' with password + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + bash -c ' + psql -U postgres -d {{ db_name | default("postgres") }} -c " + CREATE USER pmm WITH PASSWORD '\''pmm'\''; + GRANT pg_monitor TO pmm; + " + ' + + - name: Create custom database for pgbench + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + bash -c " + echo \" + CREATE DATABASE pgbench; + \\c pgbench + GRANT CONNECT ON DATABASE pgbench TO pmm; + GRANT USAGE ON SCHEMA public TO pmm; + GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO pmm; + ALTER DEFAULT PRIVILEGES IN SCHEMA public + GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO pmm; + \" | psql -U postgres -v ON_ERROR_STOP=1 + " + + - name: Run pg_basebackup from primary to replica + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_{{ item }}" + user: root + command: > + bash -c " + export PGPASSWORD='{{ replication_password }}' && \ + timeout 120s \ + pg_basebackup --pgdata=/var/lib/postgresql/data -R -v -Fp -Xs -P \ + --host=pgsql_pmm_{{ pg_version }}_1 --port=5432 -U {{ replication_user }} + " + loop: "{{ range(2, nodes_count | int + 1) | list }}" + + - name: Restart PostgreSQL container with custom command + community.docker.docker_container: + name: "pgsql_pmm_{{ pg_version }}_{{ item }}" + image: "postgres:{{ pg_version }}-bookworm" + restart: true + state: started + command: -c config_file=/etc/postgresql/postgresql.conf + networks: + - name: "{{ network_name }}" + env: + POSTGRES_PASSWORD: "{{ root_password }}" + volumes: + - "{{ data_dir }}/node{{ item }}/data:/var/lib/postgresql/data" + - "./data/postgres-replica.conf:/etc/postgresql/postgresql.conf:ro" + - "{{ data_dir }}/node1/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro" + ports: + - "{{ pgsql_port + item - 1 }}:5432" + loop: "{{ range(2, nodes_count | int + 1) | list }}" + + - name: Create pg_stat_statements extension + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + psql -U postgres -d 'postgres' -c " + CREATE EXTENSION IF NOT EXISTS pg_stat_statements; + " + + - name: Install and add pmm client. + include_tasks: ../tasks/install_pmm_client.yml + vars: + container_name: "pgsql_pmm_{{ pg_version }}_{{ item }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + + - name: Get already connected services to pmm server + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_1" + command: > + sh -c 'curl --location --insecure -u"admin:{{ admin_password }}" -s --request GET "http://{{ pmm_server_ip }}:{{ '80' if pmm_server_ip is ansible.utils.ipv4 else '8080' }}/v1/management/services" | jq -r ".services[].service_name"' + register: pmm_server_services + + - name: Display already connected services to pmm server + debug: + msg: "{{ pmm_server_services.stdout | split('\n') }}" + + - name: Find out if service is already connected to pmm server + block: + - name: Loop through percona servers + set_fact: + random_service_name_value: "_{{ 9999 | random + 1 }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + when: "('pgsql_pmm_' ~ pg_version ~ '_' ~ item) in pmm_server_services.stdout" + + - name: Add service to pmm server + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_{{ item }}" + command: pmm-admin add postgresql --username=pmm --password=pmm --query-source=pgstatements pgsql_pmm_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 + loop: "{{ range(1, nodes_count | int + 1) | list }}" + + - name: Run load on primary node. + include_tasks: ./tasks/run_load_pgsql.yml + vars: + node_name: "pgsql_pmm_{{ pg_version }}_1" + pgbench_clients: 10 + pgbench_time: 120 + pgbench_scale: 1000 + + - name: Check replication status on primary + community.docker.docker_container_exec: + container: "pgsql_pmm_{{ pg_version }}_1" + user: postgres + command: psql -c "SELECT * FROM pg_stat_replication;" diff --git a/pmm_qa/postgresql/tasks/run_load_pgsql.yml b/pmm_qa/postgresql/tasks/run_load_pgsql.yml new file mode 100644 index 00000000..d1b46305 --- /dev/null +++ b/pmm_qa/postgresql/tasks/run_load_pgsql.yml @@ -0,0 +1,57 @@ +# This ansible file run load on docker container of pgsql with variable name node_name + +- name: Detect OS inside the container + community.docker.docker_container_exec: + container: "{{ node_name }}" + command: cat /etc/os-release + register: container_os_info + +- name: Set distro family (debian/rhel) + set_fact: + distro_family: >- + {{ + ( + 'debian' if 'debian' in container_os_info.stdout | lower else + 'rhel' if 'rhel' in container_os_info.stdout | lower or 'centos' in container_os_info.stdout | lower or 'fedora' in container_os_info.stdout | lower + else 'unknown' + ) | trim + }} + + + +- name: Ensure pgbench is installed (Debian-based container) + community.docker.docker_container_exec: + container: "{{ node_name }}" + user: root + command: > + /bin/sh -c " + apt-get update && + apt-get install -y postgresql-contrib + " + when: distro_family == "debian" + +- name: Ensure pgbench is installed (RHEL-based container) + community.docker.docker_container_exec: + container: "{{ node_name }}" + user: root + command: microdnf install -y postgresql-contrib + when: distro_family == "rhel" + +- name: Initialize pgbench database + community.docker.docker_container_exec: + container: "{{ node_name }}" + user: postgres + command: > + pgbench -i -s {{ pgbench_scale }} pgbench + +- name: Run pgbench benchmark + community.docker.docker_container_exec: + container: "{{ node_name }}" + user: postgres + command: > + pgbench -c {{ pgbench_clients }} -T {{ pgbench_time }} -j 4 pgbench + register: pgbench_result + +- name: Print pgbench results + debug: + var: pgbench_result.stdout_lines \ No newline at end of file diff --git a/pmm_qa/scripts/__init__.py b/pmm_qa/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pmm_qa/scripts/database_options.py b/pmm_qa/scripts/database_options.py new file mode 100644 index 00000000..7b76bdba --- /dev/null +++ b/pmm_qa/scripts/database_options.py @@ -0,0 +1,77 @@ +database_options = { + "PSMDB": { + "versions": ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "COMPOSE_PROFILES": "classic", + "TARBALL": ""} + }, + "MLAUNCH_PSMDB": { + "versions": ["4.4", "5.0", "6.0", "7.0", "8.0"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "TARBALL": ""} + }, + "MLAUNCH_MODB": { + "versions": ["4.4", "5.0", "6.0", "7.0", "8.0"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "TARBALL": ""} + }, + "SSL_MLAUNCH": { + "versions": ["4.4", "5.0", "6.0", "7.0", "8.0"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "COMPOSE_PROFILES": "classic", + "TARBALL": ""} + }, + "SSL_PSMDB": { + "versions": ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "SETUP_TYPE": "pss", "COMPOSE_PROFILES": "classic", + "TARBALL": ""} + }, + "MYSQL": { + "versions": ["8.0", "8.4"], + "configurations": {"QUERY_SOURCE": "perfschema", "SETUP_TYPE": "", "CLIENT_VERSION": "3-dev-latest", + "TARBALL": ""} + }, + "PS": { + "versions": ["5.7", "8.4", "8.0"], + "configurations": {"QUERY_SOURCE": "perfschema", "SETUP_TYPE": "", "CLIENT_VERSION": "3-dev-latest", + "TARBALL": "", "NODES_COUNT": 1} + }, + "SSL_MYSQL": { + "versions": ["5.7", "8.4", "8.0"], + "configurations": {"QUERY_SOURCE": "perfschema", "SETUP_TYPE": "", "CLIENT_VERSION": "3-dev-latest", + "TARBALL": ""} + }, + "PGSQL": { + "versions": ["11", "12", "13", "14", "15", "16", "17"], + "configurations": {"QUERY_SOURCE": "pgstatements", "CLIENT_VERSION": "3-dev-latest", "USE_SOCKET": "", + "SETUP_TYPE": ""} + }, + "PDPGSQL": { + "versions": ["11", "12", "13", "14", "15", "16", "17"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "USE_SOCKET": "", "SETUP_TYPE": ""} + }, + "SSL_PDPGSQL": { + "versions": ["11", "12", "13", "14", "15", "16", "17"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "USE_SOCKET": ""} + }, + "PXC": { + "versions": ["5.7", "8.0"], + "configurations": {"CLIENT_VERSION": "3-dev-latest", "QUERY_SOURCE": "perfschema", "TARBALL": ""} + }, + "PROXYSQL": { + "versions": ["2"], + "configurations": {"PACKAGE": ""} + }, + "HAPROXY": { + "versions": [""], + "configurations": {"CLIENT_VERSION": "3-dev-latest"} + }, + "EXTERNAL": { + "REDIS": { + "versions": ["1.14.0", "1.58.0"], + }, + "NODEPROCESS": { + "versions": ["0.7.5", "0.7.10"], + }, + "configurations": {"CLIENT_VERSION": "3-dev-latest"} + }, + "DOCKERCLIENTS": { + "configurations": {} # Empty dictionary for consistency + }, +} \ No newline at end of file diff --git a/pmm_qa/scripts/get_env_value.py b/pmm_qa/scripts/get_env_value.py new file mode 100644 index 00000000..74d65149 --- /dev/null +++ b/pmm_qa/scripts/get_env_value.py @@ -0,0 +1,20 @@ +import os +from .database_options import database_options + +def get_value(key, db_type, args, db_config): + # Check if the variable exists in the environment + env_value = os.environ.get(key) + if env_value is not None: + return env_value + + # Only for client_version we accept global command line argument + if key == "CLIENT_VERSION" and args.client_version is not None: + return args.client_version + + # Check if the variable exists in the args config + config_value = db_config.get(key) + if config_value is not None: + return config_value + + # Fall back to default configs value or empty '' + return database_options[db_type]["configurations"].get(key, '') diff --git a/pmm_qa/scripts/run_ansible_playbook.py b/pmm_qa/scripts/run_ansible_playbook.py new file mode 100644 index 00000000..66d1a334 --- /dev/null +++ b/pmm_qa/scripts/run_ansible_playbook.py @@ -0,0 +1,32 @@ +import os +import ansible_runner +import sys + +def run_ansible_playbook(playbook_filename, env_vars, args): + # Get Script Dir + script_path = os.path.abspath(sys.argv[0]) + script_dir = os.path.dirname(script_path) + playbook_path = script_dir + "/" + playbook_filename + verbosity_level = 1 + + if args.verbosity_level is not None: + verbosity_level = int(args.verbosity_level) + + if args.verbose: + print(f'Options set after considering Defaults: {env_vars}') + + r = ansible_runner.run( + private_data_dir=script_dir, + playbook=playbook_path, + inventory='127.0.0.1', + cmdline='-l localhost, --connection=local', + envvars=env_vars, + suppress_env_files=True, + verbosity=verbosity_level, + ) + + print(f'{playbook_filename} playbook execution {r.status}') + + if r.rc != 0: + exit(1) + diff --git a/pmm_qa/tasks/add_mysql_to_pmm_server.yml b/pmm_qa/tasks/add_mysql_to_pmm_server.yml index 1dd6b42d..55d54ebf 100644 --- a/pmm_qa/tasks/add_mysql_to_pmm_server.yml +++ b/pmm_qa/tasks/add_mysql_to_pmm_server.yml @@ -1,5 +1,5 @@ - name: Install and add pmm client - include_tasks: ./install_pmm_client_centos.yml + include_tasks: install_pmm_client.yml - name: Set unique service name include_tasks: ./set_unique_service_name.yml diff --git a/pmm_qa/tasks/install_pmm_client.yml b/pmm_qa/tasks/install_pmm_client.yml new file mode 100644 index 00000000..dda754e8 --- /dev/null +++ b/pmm_qa/tasks/install_pmm_client.yml @@ -0,0 +1,263 @@ +- name: Get PMM server address + shell: 'docker ps -f name=-server --format "{{ "{{" }}.Names{{ "}}" }}"' + register: pmm_server_ip_output + when: pmm_server_ip == "127.0.0.1" + +- name: Set correct pmm server address + set_fact: + pmm_server_ip: "{{ pmm_server_ip_output.stdout }}" + when: pmm_server_ip == "127.0.0.1" + +- name: Print pmm server address + debug: + var: pmm_server_ip + +- name: Copy a file into the container + community.docker.docker_container_copy_into: + container: "{{ container_name }}" + path: ../pmm3-client-setup-centos.sh + container_path: /pmm3-client-setup.sh + +- name: "PMM Server IP is" + debug: + msg: "{{ pmm_server_ip }} is pmm server IP" + +- name: Set correct pmm server port + set_fact: + pmm_server_port: 443 + when: pmm_server_ip is ansible.utils.ipv4 + +- name: Set correct pmm server port + set_fact: + pmm_server_port: 8443 + when: pmm_server_ip is not ansible.utils.ipv4 + +- name: Detect OS inside the container + community.docker.docker_container_exec: + container: "{{ container_name }}" + command: cat /etc/os-release + register: container_os_info + +- name: Set distro family (debian/rhel) + set_fact: + distro_family: >- + {{ + ( + 'debian' if 'debian' in container_os_info.stdout | lower else + 'rhel' if 'rhel' in container_os_info.stdout | lower or 'centos' in container_os_info.stdout | lower or 'fedora' in container_os_info.stdout | lower + else 'unknown' + ) | trim + }} + +- name: Install dependencies inside Debian-family container + community.docker.docker_container_exec: + container: "{{ container_name }}" + command: > + sh -c ' + apt-get update && + apt-get install -y wget gnupg2 jq lsb-base lsb-release curl + ' + user: "root" + when: distro_family == "debian" + +- name: Install dependencies on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + command: microdnf install -y wget gnupg2 jq + user: "root" + when: distro_family == "rhel" + +- name: Install curl on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + command: microdnf install -y curl-minimal + user: "root" + when: distro_family == "rhel" + ignore_errors: true + +- name: Get lsb_release + community.docker.docker_container_exec: + container: "{{ container_name }}" + command: > + bash -c "grep '^VERSION_CODENAME=' /etc/os-release | cut -d '=' -f2 | tr -d '\"'" + user: "root" + register: lsb_release + +- name: Set lsb_release + set_fact: + lsb_release: "{{ lsb_release.stdout }}" + +- name: Print expected client version + debug: + msg: "{{ metrics_mode }}" + +- name: Install percona release on Debian-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + wget -O /percona-release_latest.{{ lsb_release }}_all.deb https://repo.percona.com/apt/percona-release_latest.{{ lsb_release }}_all.deb && + dpkg -i /percona-release_latest.{{ lsb_release }}_all.deb + ' + when: + - distro_family == 'debian' + +- name: Install specific PMM client version on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + wget -O /percona-release-latest.noarch.rpm https://repo.percona.com/yum/percona-release-latest.noarch.rpm && + rpm -i /percona-release-latest.noarch.rpm + ' + when: + - distro_family == 'rhel' + ignore_errors: true + +- name: Install pmm client experimental on Debian-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + percona-release enable-only pmm3-client experimental && + apt-get update && + apt-get -y install pmm-client + ' + when: distro_family == "debian" and client_version == "3-dev-latest" + +- name: Install pmm client experimental on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + percona-release enable-only pmm3-client experimental && + microdnf install -y pmm-client + ' + when: distro_family == "rhel" and client_version == "3-dev-latest" + +- name: Install pmm client testing on Debian-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + percona-release enable-only pmm3-client testing && + apt-get update && + apt-get -y install pmm-client + ' + when: distro_family == "debian" and client_version == "pmm3-rc" + +- name: Install pmm client testing on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + percona-release enable-only pmm3-client testing && + microdnf install -y pmm-client + ' + when: distro_family == "rhel" and client_version == "pmm3-rc" + +- name: Install pmm client release on Debian-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + percona-release enable-only pmm3-client release && + apt-get update && + apt-get -y install pmm-client + ' + when: distro_family == "debian" and client_version == "pmm3-latest" + +- name: Install pmm client release on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + percona-release enable-only pmm3-client release && + microdnf install -y pmm-client + ' + when: distro_family == "rhel" and client_version == "pmm3-latest" + +- name: Install specific PMM client version on Debian-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + wget -O /pmm-client.deb https://repo.percona.com/pmm3-client/apt/pool/main/p/pmm-client/pmm-client_{{ client_version }}-7.$(lsb_release -sc)_amd64.deb && + dpkg -i /pmm-client.deb + ' + when: + - distro_family == 'debian' + - client_version is match('^3\\.[0-9]+\\.[0-9]+$') + +- name: Install specific PMM client version on RHEL-family containers + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + wget -O /pmm-client.rpm https://repo.percona.com/pmm3-client/yum/release/9/RPMS/x86_64/pmm-client-{{ client_version }}-7.el9.x86_64.rpm && + rpm -i /pmm-client.rpm + ' + when: + - distro_family == 'rhel' + - client_version is match('^3\\.[0-9]+\\.[0-9]+$') + +- name: Install tarball PMM client version + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c ' + wget -O /pmm-client.tar.gz "{{ client_version }}" && + tar -zxpf /pmm-client.tar.gz && + PMM_CLIENT=`ls -1td pmm-client* 2>/dev/null | grep -v ".tar" | grep -v ".sh" | head -n1` && + echo ${PMM_CLIENT} && + rm -rf pmm-client && + mv ${PMM_CLIENT} pmm-client && + rm -rf /usr/local/bin/pmm-client && + mv -f pmm-client /usr/local/bin && + bash -x /usr/local/bin/pmm-client/install_tarball && + ln -sf /usr/local/percona/pmm/bin/pmm-admin /usr/local/bin/pmm-admin && + ln -sf /usr/local/percona/pmm/bin/pmm-agent /usr/local/bin/pmm-agent && + pmm-admin --version + ' + when: + - client_version | regex_search('^https?://.*\\.tar\\.gz$') is not none + +- name: Connect pmm client to pmm server using metrics mode + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: pmm-agent setup --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml --server-address={{ pmm_server_ip }}:{{ pmm_server_port }} --server-insecure-tls --metrics-mode={{ metrics_mode }} --server-username=admin --server-password={{ admin_password }} {{ container_name }} + when: metrics_mode | length > 0 + +- name: Connect pmm client to pmm server using metrics mode + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: pmm-agent setup --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml --server-address={{ pmm_server_ip }}:{{ pmm_server_port }} --server-insecure-tls --server-username=admin --server-password={{ admin_password }} {{ container_name }} + when: metrics_mode | length == 0 + +- name: Wait 5 seconds for connection to complete + pause: + seconds: 5 + +- name: Start pmm client + community.docker.docker_container_exec: + container: "{{ container_name }}" + user: "root" + command: > + sh -c 'nohup pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml > /var/log/pmm-agent.log 2>&1 &' + +- name: Wait 5 seconds for start to complete + pause: + seconds: 5 \ No newline at end of file diff --git a/pmm_qa/tasks/install_pmm_client_centos.yml b/pmm_qa/tasks/install_pmm_client_centos.yml deleted file mode 100644 index ea8f9f38..00000000 --- a/pmm_qa/tasks/install_pmm_client_centos.yml +++ /dev/null @@ -1,29 +0,0 @@ -- name: Get PMM server address - shell: 'docker ps -f name=-server --format "{{ "{{" }}.Names{{ "}}" }}"' - register: pmm_server_ip_output - when: pmm_server_ip == "127.0.0.1" - -- name: Set correct pmm server address - set_fact: - pmm_server_ip: "{{ pmm_server_ip_output.stdout }}" - when: pmm_server_ip == "127.0.0.1" - -- name: Print pmm server address - debug: - var: pmm_server_ip - -- name: Copy a file into the container - community.docker.docker_container_copy_into: - container: "{{ container_name }}" - path: ../pmm3-client-setup-centos.sh - container_path: /pmm3-client-setup.sh - -- name: "PMM Server IP is" - debug: - msg: "{{ pmm_server_ip }} is pmm server IP" - -- name: Install pmm-client - community.docker.docker_container_exec: - container: "{{ container_name }}" - user: "root" - command: bash -x /pmm3-client-setup.sh --pmm_server_ip {{ pmm_server_ip }} --client_version {{ client_version }} --admin_password {{ admin_password }} --use_metrics_mode no From 01613bdacb5315a8d56fe9f6a7281847666c943e Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 08:33:44 +0200 Subject: [PATCH 02/17] PMM-13928: Code cleanup --- .../data/etcd-primary.conf.yaml.j2 | 2 +- .../data/etcd-replica.conf.yaml.j2 | 2 +- .../data/patroni.yml.j2 | 2 +- .../data/postgres-replica.conf | 2 +- .../data/postgresql-primary.conf | 2 +- ...na-distribution-postgres-patroni-setup.yml | 2 +- .../tasks/prepare_etcd.yml | 27 ------------------- pmm_qa/postgresql/tasks/run_load_pgsql.yml | 2 +- pmm_qa/scripts/database_options.py | 2 +- pmm_qa/tasks/install_pmm_client.yml | 2 +- 10 files changed, 9 insertions(+), 36 deletions(-) delete mode 100644 pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 index 114ead42..3e4f16f5 100644 --- a/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 +++ b/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 @@ -6,4 +6,4 @@ data-dir: /var/lib/etcd initial-advertise-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2380 listen-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2380 advertise-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 -listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 \ No newline at end of file +listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 index 8b6d5c21..7c5a4713 100644 --- a/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 +++ b/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 @@ -6,4 +6,4 @@ data-dir: /var/lib/etcd initial-advertise-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2380 listen-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2380 advertise-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 -listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 \ No newline at end of file +listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 diff --git a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 index 71bcb414..9d5fb485 100644 --- a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 +++ b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 @@ -78,4 +78,4 @@ tags: nofailover: false noloadbalance: false clonefrom: false - nosync: false \ No newline at end of file + nosync: false diff --git a/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf b/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf index b6a3d6ba..3336ed77 100644 --- a/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf +++ b/pmm_qa/percona-distribution-postgresql/data/postgres-replica.conf @@ -11,4 +11,4 @@ pg_stat_monitor.pgsm_enable_query_plan=1 log_connections = on log_disconnections = on log_replication_commands = on -log_statement = 'all' \ No newline at end of file +log_statement = 'all' diff --git a/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf b/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf index 65b7a68f..1bff8edd 100644 --- a/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf +++ b/pmm_qa/percona-distribution-postgresql/data/postgresql-primary.conf @@ -13,4 +13,4 @@ pg_stat_monitor.pgsm_enable_query_plan = 'yes' log_connections = on log_disconnections = on log_replication_commands = on -log_statement = 'all' \ No newline at end of file +log_statement = 'all' diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 629f8830..33591269 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -126,4 +126,4 @@ /bin/sh -c ' sleep 15 patronictl -c /etc/patroni/patroni.yml list - ' \ No newline at end of file + ' diff --git a/pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml b/pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml deleted file mode 100644 index 5e3b8128..00000000 --- a/pmm_qa/percona-distribution-postgresql/tasks/prepare_etcd.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: Start etcd container - community.docker.docker_container: - name: "{{ etcd_container_name }}" - image: oraclelinux:9 - state: started - restart_policy: always - command: sleep infinity - -- name: Install required packages in Oracle Linux container - community.docker.docker_container_exec: - container: "{{ etcd_container_name }}" - command: > - /bin/sh -c ' - DOWNLOAD_URL=$(curl -s https://api.github.com/repos/etcd-io/etcd/releases/latest | grep "browser_download_url" | grep "linux-amd64.tar.gz" | sed -E "s/.*\"browser_download_url\": *\"(.*)\"/\1/") && - echo "URLS is: $DOWNLOAD_URL" && - FILENAME=$(basename "$DOWNLOAD_URL" .tar.gz) && - echo "Filename is: $FILENAME" && - curl -L -o etcd-latest.tar.gz https://github.com/etcd-io/etcd/releases/download/v3.6.1/etcd-v3.6.1-linux-amd64.tar.gz && - mkdir -p /etcd-latest - tar -xzf etcd-latest.tar.gz && - ls && - ls /$FILENAME && - cd $FILENAME && - mv etcd etcdctl /usr/local/bin/ && - etcd --version && - etcdctl version - ' \ No newline at end of file diff --git a/pmm_qa/postgresql/tasks/run_load_pgsql.yml b/pmm_qa/postgresql/tasks/run_load_pgsql.yml index d1b46305..7e2cc3b0 100644 --- a/pmm_qa/postgresql/tasks/run_load_pgsql.yml +++ b/pmm_qa/postgresql/tasks/run_load_pgsql.yml @@ -54,4 +54,4 @@ - name: Print pgbench results debug: - var: pgbench_result.stdout_lines \ No newline at end of file + var: pgbench_result.stdout_lines diff --git a/pmm_qa/scripts/database_options.py b/pmm_qa/scripts/database_options.py index 7b76bdba..70c57b90 100644 --- a/pmm_qa/scripts/database_options.py +++ b/pmm_qa/scripts/database_options.py @@ -74,4 +74,4 @@ "DOCKERCLIENTS": { "configurations": {} # Empty dictionary for consistency }, -} \ No newline at end of file +} diff --git a/pmm_qa/tasks/install_pmm_client.yml b/pmm_qa/tasks/install_pmm_client.yml index dda754e8..f8298780 100644 --- a/pmm_qa/tasks/install_pmm_client.yml +++ b/pmm_qa/tasks/install_pmm_client.yml @@ -260,4 +260,4 @@ - name: Wait 5 seconds for start to complete pause: - seconds: 5 \ No newline at end of file + seconds: 5 From 3680a86fb4d055770335da3a96e2eab0e967d87a Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 08:39:50 +0200 Subject: [PATCH 03/17] PMM-13928: Install pmm client on patroni setup --- .../tasks/install_pg_stat-monitor.yml | 8 ++-- ...na-distribution-postgres-patroni-setup.yml | 38 ++++++++++++++++++- ...istribution-postgres-replication-setup.yml | 2 + 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml b/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml index 85a6d57f..c27ad010 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml @@ -1,6 +1,6 @@ - name: Detect OS inside the container community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_1" + container: "{{ container_name }}" command: cat /etc/os-release register: container_os_info @@ -17,7 +17,7 @@ - name: Install dependencies inside Debian-family container community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + container: "{{ container_name }}" command: > sh -c ' apt-get update && @@ -29,7 +29,7 @@ - name: Install dependencies inside RHEL-family container community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + container: "{{ container_name }}" command: > sh -c ' microdnf install percona-pg-stat-monitor{{ pg_version }} @@ -40,7 +40,7 @@ - name: Create pg_stat_statements extension community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_1" + container: "{{ container_name }}" user: postgres command: > psql -U postgres -d 'postgres' -c " diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 33591269..38246e49 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -119,11 +119,47 @@ ' loop: "{{ range(1, nodes_count | int + 1) | list }}" +- name: Install pg stat monitor. + include_tasks: ./tasks/install_pg_stat-monitor.yml + vars: + container_name: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Install and add pmm client. + include_tasks: ../tasks/install_pmm_client.yml + vars: + container_name: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + +- name: Get already connected services to pmm server + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + command: > + sh -c 'curl --location --insecure -u"admin:{{ admin_password }}" -s --request GET "http://{{ pmm_server_ip }}:{{ '80' if pmm_server_ip is ansible.utils.ipv4 else '8080' }}/v1/management/services" | jq -r ".services[].service_name"' + register: pmm_server_services + +- name: Display already connected services to pmm server + debug: + msg: "{{ pmm_server_services.stdout | split('\n') }}" + +- name: Find out if service is already connected to pmm server + block: + - name: Loop through percona servers + set_fact: + random_service_name_value: "_{{ 9999 | random + 1 }}" + loop: "{{ range(1, nodes_count | int + 1) | list }}" + when: "('pdpgsql_pmm_patroni_' ~ pg_version ~ '_' ~ item) in pmm_server_services.stdout" + +- name: Add service to pmm server + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + command: pmm-admin add postgresql --username=pmm --password=pmm --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 + loop: "{{ range(1, nodes_count | int + 1) | list }}" + - name: Log Patroni cluster community.docker.docker_container_exec: container: "pdpgsql_pmm_patroni_{{ pg_version }}_1" command: > /bin/sh -c ' - sleep 15 patronictl -c /etc/patroni/patroni.yml list ' diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml index 70a58f91..493f6505 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml @@ -187,6 +187,8 @@ - name: Install pg stat monitor. include_tasks: ./tasks/install_pg_stat-monitor.yml + vars: + container_name: "pdpgsql_pmm_{{ pg_version }}_1" - name: Install and add pmm client. include_tasks: ../tasks/install_pmm_client.yml From f5b54c912b42b25b37a344c3da13efde88eff317 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 08:50:42 +0200 Subject: [PATCH 04/17] PMM-13928: Install microdnf --- .../percona-distribution-postgres-patroni-setup.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 38246e49..cbf474fe 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -119,6 +119,16 @@ ' loop: "{{ range(1, nodes_count | int + 1) | list }}" +- name: Install microdnf + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + user: root + command: > + /bin/sh -c ' + dnf install -y microdnf + ' + loop: "{{ range(1, nodes_count | int + 1) | list }}" + - name: Install pg stat monitor. include_tasks: ./tasks/install_pg_stat-monitor.yml vars: From 49574f289a02a5baa6e161689d4e9f6e6d7ca261 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 09:00:08 +0200 Subject: [PATCH 05/17] PMM-13928: Code cleanup --- .../data/etcd-primary.conf.yaml.j2 | 9 --------- .../data/etcd-replica.conf.yaml.j2 | 9 --------- .../percona-distribution-postgres-setup.yml | 2 +- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 delete mode 100644 pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 deleted file mode 100644 index 3e4f16f5..00000000 --- a/pmm_qa/percona-distribution-postgresql/data/etcd-primary.conf.yaml.j2 +++ /dev/null @@ -1,9 +0,0 @@ -name: 'node1' -initial-cluster-token: PostgreSQL_HA_Cluster_1 -initial-cluster-state: new -initial-cluster: node1=http://pdpgsql_pmm_{{ pg_version }}_1:2380,node2=http://pdpgsql_pmm_{{ pg_version }}_2:2380,node3=http://pdpgsql_pmm_{{ pg_version }}_3:2380 -data-dir: /var/lib/etcd -initial-advertise-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2380 -listen-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2380 -advertise-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 -listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_1:2379 diff --git a/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 b/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 deleted file mode 100644 index 7c5a4713..00000000 --- a/pmm_qa/percona-distribution-postgresql/data/etcd-replica.conf.yaml.j2 +++ /dev/null @@ -1,9 +0,0 @@ -name: 'node {{ item }}' -initial-cluster-token: PostgreSQL_HA_Cluster_1 -initial-cluster-state: new -initial-cluster: node1=http://pdpgsql_pmm_{{ pg_version }}_1:2380,node2=http://pdpgsql_pmm_{{ pg_version }}_2:2380,node3=http://pdpgsql_pmm_{{ pg_version }}_3:2380 -data-dir: /var/lib/etcd -initial-advertise-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2380 -listen-peer-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2380 -advertise-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 -listen-client-urls: http://pdpgsql_pmm_{{ pg_version }}_2:2379 diff --git a/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml b/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml index aacb622c..ce64aed4 100644 --- a/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/percona-distribution-postgres-setup.yml @@ -33,4 +33,4 @@ - name: Install Percona Distribution for Postgres with Patroni replication include_tasks: tasks/percona-distribution-postgres-patroni-setup.yml - when: setup_type == "patroni" \ No newline at end of file + when: setup_type == "patroni" From e4fd6c751178bf560f3a7b593d0d70e5831b05a8 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 09:11:15 +0200 Subject: [PATCH 06/17] PMM-13928: Adds postgres to pg_hba.conf --- pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 index 9d5fb485..e3682116 100644 --- a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 +++ b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 @@ -33,6 +33,7 @@ bootstrap: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 172.18.0.0/16 md5 - host all all 0.0.0.0/0 md5 + - local all postgres trust initdb: - encoding: UTF8 From 422cb559099b0d2773bc1f0e397c89cfc83312ee Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 09:27:39 +0200 Subject: [PATCH 07/17] PMM-13928: Fix pgstatmonitor setup --- .../tasks/install_pg_stat-monitor.yml | 8 ++++---- .../tasks/percona-distribution-postgres-patroni-setup.yml | 3 +-- .../percona-distribution-postgres-replication-setup.yml | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml b/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml index c27ad010..146f17e7 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/install_pg_stat-monitor.yml @@ -1,6 +1,6 @@ - name: Detect OS inside the container community.docker.docker_container_exec: - container: "{{ container_name }}" + container: "{{ container_name }}_1" command: cat /etc/os-release register: container_os_info @@ -17,7 +17,7 @@ - name: Install dependencies inside Debian-family container community.docker.docker_container_exec: - container: "{{ container_name }}" + container: "{{ container_name }}_{{ item }}" command: > sh -c ' apt-get update && @@ -29,7 +29,7 @@ - name: Install dependencies inside RHEL-family container community.docker.docker_container_exec: - container: "{{ container_name }}" + container: "{{ container_name }}_{{ item }}" command: > sh -c ' microdnf install percona-pg-stat-monitor{{ pg_version }} @@ -40,7 +40,7 @@ - name: Create pg_stat_statements extension community.docker.docker_container_exec: - container: "{{ container_name }}" + container: "{{ container_name }}_1" user: postgres command: > psql -U postgres -d 'postgres' -c " diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index cbf474fe..b92038c1 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -132,8 +132,7 @@ - name: Install pg stat monitor. include_tasks: ./tasks/install_pg_stat-monitor.yml vars: - container_name: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" - loop: "{{ range(1, nodes_count | int + 1) | list }}" + container_name: "pdpgsql_pmm_patroni_{{ pg_version }}" - name: Install and add pmm client. include_tasks: ../tasks/install_pmm_client.yml diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml index 493f6505..242a984b 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-replication-setup.yml @@ -188,7 +188,7 @@ - name: Install pg stat monitor. include_tasks: ./tasks/install_pg_stat-monitor.yml vars: - container_name: "pdpgsql_pmm_{{ pg_version }}_1" + container_name: "pdpgsql_pmm_{{ pg_version }}" - name: Install and add pmm client. include_tasks: ../tasks/install_pmm_client.yml From 1938e317253c3f46ac2bf2b48b481327964d1bdd Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 09:48:19 +0200 Subject: [PATCH 08/17] PMM-13928: Fix pdpgsql container name --- .../tasks/percona-distribution-postgres-patroni-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index b92038c1..b0454b0f 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -142,7 +142,7 @@ - name: Get already connected services to pmm server community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_1" + container: "pdpgsql_pmm_patroni_{{ pg_version }}_1" command: > sh -c 'curl --location --insecure -u"admin:{{ admin_password }}" -s --request GET "http://{{ pmm_server_ip }}:{{ '80' if pmm_server_ip is ansible.utils.ipv4 else '8080' }}/v1/management/services" | jq -r ".services[].service_name"' register: pmm_server_services @@ -161,7 +161,7 @@ - name: Add service to pmm server community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_{{ item }}" + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" command: pmm-admin add postgresql --username=pmm --password=pmm --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 loop: "{{ range(1, nodes_count | int + 1) | list }}" From 9b11885ba6187f7b4820fe16cf7752d158bc03aa Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 10:28:38 +0200 Subject: [PATCH 09/17] PMM-13928: Fix pdpgsql username and password --- .../tasks/percona-distribution-postgres-patroni-setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index b0454b0f..21c2cd1a 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -162,7 +162,7 @@ - name: Add service to pmm server community.docker.docker_container_exec: container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" - command: pmm-admin add postgresql --username=pmm --password=pmm --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 + command: pmm-admin add postgresql --username=postgres --password=pg1234 --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 loop: "{{ range(1, nodes_count | int + 1) | list }}" - name: Log Patroni cluster From d580bdb881923c6e6175b5ebb026eacfdad5cda1 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 10:34:36 +0200 Subject: [PATCH 10/17] PMM-13928: Fix pdpgsql username and password --- pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 | 2 +- .../tasks/percona-distribution-postgres-patroni-setup.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 index e3682116..6be9524e 100644 --- a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 +++ b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 @@ -61,7 +61,7 @@ postgresql: password: replPasswd superuser: username: postgres - password: pg1234 + password: postgres create_replica_methods: - pgbackrest diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 21c2cd1a..6ea0aa46 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -162,7 +162,7 @@ - name: Add service to pmm server community.docker.docker_container_exec: container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" - command: pmm-admin add postgresql --username=postgres --password=pg1234 --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 + command: pmm-admin add postgresql --username=postgres --password=postgres --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 loop: "{{ range(1, nodes_count | int + 1) | list }}" - name: Log Patroni cluster From 17608d90feef6e0b7422c8383ee5f5f2e734a25d Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 11:08:40 +0200 Subject: [PATCH 11/17] PMM-13928: Grant pg_monitor to postgres user --- .../percona-distribution-postgres-patroni-setup.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 6ea0aa46..8f2faa6b 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -134,6 +134,17 @@ vars: container_name: "pdpgsql_pmm_patroni_{{ pg_version }}" +- name: Grant pg_monitor to postgres user + community.docker.docker_container_exec: + container: "pdpgsql_pmm_{{ pg_version }}_1" + user: postgres + command: > + bash -c ' + psql -U postgres -d {{ db_name | default("postgres") }} -c " + GRANT pg_monitor TO postgres; + " + ' + - name: Install and add pmm client. include_tasks: ../tasks/install_pmm_client.yml vars: From ba31f25709a6ba37b952a024437c92d6cc753602 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 11:26:40 +0200 Subject: [PATCH 12/17] PMM-7: Default value for bucket --- .../tasks/percona-distribution-postgres-patroni-setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 8f2faa6b..f85685a5 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -136,7 +136,7 @@ - name: Grant pg_monitor to postgres user community.docker.docker_container_exec: - container: "pdpgsql_pmm_{{ pg_version }}_1" + container: "pdpgsql_pmm_patroni_{{ pg_version }}_1" user: postgres command: > bash -c ' From 0cc8f9d9ed9c403e96fbf131157cf77643668dc6 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 12:37:29 +0200 Subject: [PATCH 13/17] PMM-13928: shared_preload_libraries --- pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 index 6be9524e..13ec02f5 100644 --- a/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 +++ b/pmm_qa/percona-distribution-postgresql/data/patroni.yml.j2 @@ -20,6 +20,7 @@ bootstrap: use_pg_rewind: true use_slots: true parameters: + shared_preload_libraries: 'pg_stat_monitor' wal_level: replica hot_standby: "on" wal_keep_size: 128MB From 403f1d7ca7a30b641a8047f5b4a6ff1550ff82e7 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 12:59:28 +0200 Subject: [PATCH 14/17] PMM-13928: Install percona-pg-stat-monitor --- .../tasks/percona-distribution-postgres-patroni-setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index f85685a5..8b7e5f86 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -67,7 +67,7 @@ dnf install perl-IPC-Run -y dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm dnf config-manager --set-enabled crb - dnf install -y python3-pip python3-devel binutils python3-click + dnf install -y python3-pip python3-devel binutils python3-click percona-pg-stat-monitor{{ pg_version }} ' loop: "{{ range(1, nodes_count | int + 1) | list }}" From a3fd201d8e73213d62501fa2a1949a16b01cf359 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 13:04:32 +0200 Subject: [PATCH 15/17] PMM-13928: Install percona-pg-stat-monitor --- .../tasks/percona-distribution-postgres-patroni-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 8b7e5f86..7f394b5b 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -67,7 +67,7 @@ dnf install perl-IPC-Run -y dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm dnf config-manager --set-enabled crb - dnf install -y python3-pip python3-devel binutils python3-click percona-pg-stat-monitor{{ pg_version }} + dnf install -y python3-pip python3-devel binutils python3-click ' loop: "{{ range(1, nodes_count | int + 1) | list }}" @@ -80,7 +80,7 @@ dnf module disable postgresql dnf install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm percona-release enable ppg-{{ pg_version }} - dnf install -y percona-postgresql{{ pg_version }}-server percona-patroni etcd python3-python-etcd percona-pgbackrest + dnf install -y percona-pg-stat-monitor{{ pg_version }} percona-postgresql{{ pg_version }}-server percona-patroni etcd python3-python-etcd percona-pgbackrest patroni --version ' loop: "{{ range(1, nodes_count | int + 1) | list }}" From e8e21522c3b31f965a8f864f4d22cbad036651e5 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 13:55:14 +0200 Subject: [PATCH 16/17] PMM-13928: Add external patroni service --- .../tasks/percona-distribution-postgres-patroni-setup.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml index 7f394b5b..4cab04b1 100644 --- a/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml +++ b/pmm_qa/percona-distribution-postgresql/tasks/percona-distribution-postgres-patroni-setup.yml @@ -176,6 +176,12 @@ command: pmm-admin add postgresql --username=postgres --password=postgres --query-source=pgstatmonitor pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:5432 loop: "{{ range(1, nodes_count | int + 1) | list }}" +- name: Add patroni service to pmm server + community.docker.docker_container_exec: + container: "pdpgsql_pmm_patroni_{{ pg_version }}_{{ item }}" + command: pmm-admin add external --listen-port=8008 --service-name=patroni_service_{{ item }}{{ random_service_name_value }} + loop: "{{ range(1, nodes_count | int + 1) | list }}" + - name: Log Patroni cluster community.docker.docker_container_exec: container: "pdpgsql_pmm_patroni_{{ pg_version }}_1" From 81c3cae005b3df84cbbca697161834b220c754b2 Mon Sep 17 00:00:00 2001 From: Peter Sirotnak Date: Tue, 10 Jun 2025 17:39:24 +0200 Subject: [PATCH 17/17] PMM-13928: Merge fixes --- pmm_qa/scripts/database_options.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pmm_qa/scripts/database_options.py b/pmm_qa/scripts/database_options.py index 70c57b90..54da1e17 100644 --- a/pmm_qa/scripts/database_options.py +++ b/pmm_qa/scripts/database_options.py @@ -74,4 +74,7 @@ "DOCKERCLIENTS": { "configurations": {} # Empty dictionary for consistency }, + "BUCKET": { + "configurations": {"BUCKET_NAMES": 'bcp'} + } }