From 0e92f8feffdd17f8c911dbdbdb8d1a13e3e2e19b Mon Sep 17 00:00:00 2001 From: Stefan Fercot Date: Fri, 20 Aug 2021 11:11:10 +0200 Subject: [PATCH] Add basic support for pgbackrest multi-repo feature (#22) * add basic support for pgbackrest multi-repo feature * new test suite using ansible * add check_pgbackrest regress tests to the new test suite --- .github/workflows/main.yml | 75 +++++ .gitignore | 6 +- CHANGELOG.md | 4 + README | 4 + README.pod | 5 + check_pgbackrest | 45 ++- tests/Makefile | 42 +++ tests/README.md | 79 ++++++ tests/VALIDATION.md | 51 ++++ tests/Vagrantfile | 78 +++++ tests/architectures/use-case-1/config.yml | 32 +++ tests/architectures/use-case-2/config.yml | 37 +++ tests/centos7/Makefile | 78 ----- tests/centos7/README.md | 156 ---------- tests/centos7/VALIDATION.md | 69 ----- tests/centos7/Vagrantfile | 240 ---------------- tests/centos7/provision/EDB/epas.bash | 91 ------ .../provision/EDB/pgbackrest_build.bash | 46 --- .../provision/PGDG/pgbackrest_build.bash | 35 --- tests/centos7/provision/PGDG/pgsql.bash | 70 ----- tests/centos7/provision/azurite.bash | 56 ---- tests/centos7/provision/check_pgbackrest.bash | 44 --- tests/centos7/provision/cifs.bash | 44 --- tests/centos7/provision/gcs.bash | 36 --- tests/centos7/provision/icinga2.bash | 169 ----------- tests/centos7/provision/icinga2_multi.bash | 70 ----- tests/centos7/provision/minio.bash | 113 -------- tests/centos7/provision/minio_http.bash | 66 ----- tests/centos7/provision/perl_build.bash | 38 --- .../provision/pgbackrest_azurite_primary.bash | 58 ---- .../provision/pgbackrest_azurite_standby.bash | 61 ---- .../provision/pgbackrest_gcs_primary.bash | 57 ---- .../provision/pgbackrest_gcs_standby.bash | 60 ---- .../provision/pgbackrest_local_primary.bash | 67 ----- .../provision/pgbackrest_local_standby.bash | 56 ---- .../provision/pgbackrest_minio_primary.bash | 61 ---- .../provision/pgbackrest_minio_standby.bash | 62 ---- .../provision/pgbackrest_remote_primary.bash | 32 --- .../provision/pgbackrest_remote_standby.bash | 52 ---- tests/centos7/vagrant.yml-dist | 6 - tests/ci.sh | 14 + tests/common/regress/expected/version.out | 1 - tests/common/regress/test-01.bash | 143 ---------- .../scripts/simulate-basic-activity.bash | 139 --------- .../scripts/simulate-extended-activity.bash | 83 ------ tests/common/ssh/authorized_keys | 1 - tests/common/ssh/config | 4 - tests/common/ssh/id_rsa | 27 -- tests/common/ssh/id_rsa.pub | 1 - tests/config.pl | 131 +++++++++ tests/debian/Makefile | 11 - tests/debian/Vagrantfile | 52 ---- tests/debian/provision/check_pgbackrest.bash | 37 --- tests/debian/provision/pgbackrest_local.bash | 37 --- tests/debian/provision/pgsql.bash | 42 --- .../platforms/azure/blob-create-container.py | 29 ++ tests/platforms/common/inventory/docker.j2 | 9 + tests/platforms/common/inventory/inventory.j2 | 19 ++ tests/platforms/common/inventory/write.yml | 89 ++++++ tests/platforms/common/provision.yml | 28 ++ tests/platforms/deprovision.yml | 23 ++ tests/platforms/docker/build_all_images.yml | 21 ++ .../docker/deprovision-repository-types.yml | 30 ++ tests/platforms/docker/deprovision.yml | 15 + tests/platforms/docker/docker_container.yml | 43 +++ .../docker/provision-repository-types.yml | 109 +++++++ tests/platforms/docker/provision.yml | 76 +++++ .../docker/systemd/centos.Dockerfile | 19 ++ .../docker/systemd/debian.Dockerfile | 23 ++ .../docker/systemd/ubuntu.Dockerfile | 30 ++ tests/platforms/load-config.yml | 24 ++ tests/platforms/provision.yml | 25 ++ tests/platforms/system-config.yml | 15 + tests/playbooks/activity.yml | 79 ++++++ tests/playbooks/deploy.yml | 81 ++++++ .../expected/archives-age-alert-ko.out | 0 .../expected/archives-age-alert-ok.out | 0 .../expected/archives-ignore-after.out | 0 .../expected/archives-ignore-before.out | 0 .../regress/expected/archives-ok.out | 0 .../regress/expected/list.out | 0 .../expected/retention-age-to-full.out | 0 .../regress/expected/retention-age.out | 0 .../regress/expected/retention-fail.out | 0 .../regress/expected/retention-full.out | 0 tests/playbooks/regress/regression-tests.bash | 149 ++++++++++ .../scripts/simulate-activity-basic.bash | 159 +++++++++++ tests/playbooks/templates/profile.fact.j2 | 18 ++ tests/profile.d/c7epas.profile | 4 + tests/profile.d/c7pg.profile | 4 + tests/profile.d/d10epas.profile | 4 + tests/profile.d/d10pg.profile | 4 + tests/profile.d/u20epas.profile | 4 + tests/profile.d/u20pg.profile | 4 + tests/profile.d/vagrant.profile | 7 + .../setup_check_pgbackrest/defaults/main.yml | 15 + .../setup_check_pgbackrest/tasks/build.yml | 43 +++ .../tasks/icinga2-check.yml | 48 ++++ .../tasks/icinga2-config.yml | 268 ++++++++++++++++++ .../setup_check_pgbackrest/tasks/main.yml | 63 ++++ .../roles/setup_pgbackrest/defaults/main.yml | 37 +++ tests/roles/setup_pgbackrest/tasks/backup.yml | 66 +++++ tests/roles/setup_pgbackrest/tasks/build.yml | 67 +++++ tests/roles/setup_pgbackrest/tasks/client.yml | 27 ++ .../setup_pgbackrest/tasks/create_user.yml | 25 ++ tests/roles/setup_pgbackrest/tasks/info.yml | 18 ++ tests/roles/setup_pgbackrest/tasks/main.yml | 96 +++++++ tests/roles/setup_pgbackrest/tasks/server.yml | 17 ++ .../setup_pgbackrest/tasks/ssh_setup.yml | 118 ++++++++ .../setup_pgbackrest/tasks/stanza-create.yml | 28 ++ .../templates/pgbackrest-dbserver.conf.j2 | 83 ++++++ .../templates/pgbackrest-repository.conf.j2 | 69 +++++ tests/roles/sys/pkg/defaults/main.yml | 16 ++ tests/roles/sys/pkg/tasks/main.yml | 10 + tests/roles/sys/tasks/main.yml | 72 +++++ tests/run.sh | 119 ++++++++ tests/vagrant.sh | 39 +++ tests/vagrant.yml-dist | 9 + 118 files changed, 3092 insertions(+), 2579 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 tests/Makefile create mode 100644 tests/README.md create mode 100644 tests/VALIDATION.md create mode 100644 tests/Vagrantfile create mode 100644 tests/architectures/use-case-1/config.yml create mode 100644 tests/architectures/use-case-2/config.yml delete mode 100644 tests/centos7/Makefile delete mode 100644 tests/centos7/README.md delete mode 100644 tests/centos7/VALIDATION.md delete mode 100644 tests/centos7/Vagrantfile delete mode 100644 tests/centos7/provision/EDB/epas.bash delete mode 100755 tests/centos7/provision/EDB/pgbackrest_build.bash delete mode 100755 tests/centos7/provision/PGDG/pgbackrest_build.bash delete mode 100644 tests/centos7/provision/PGDG/pgsql.bash delete mode 100644 tests/centos7/provision/azurite.bash delete mode 100644 tests/centos7/provision/check_pgbackrest.bash delete mode 100644 tests/centos7/provision/cifs.bash delete mode 100644 tests/centos7/provision/gcs.bash delete mode 100644 tests/centos7/provision/icinga2.bash delete mode 100644 tests/centos7/provision/icinga2_multi.bash delete mode 100644 tests/centos7/provision/minio.bash delete mode 100644 tests/centos7/provision/minio_http.bash delete mode 100755 tests/centos7/provision/perl_build.bash delete mode 100644 tests/centos7/provision/pgbackrest_azurite_primary.bash delete mode 100644 tests/centos7/provision/pgbackrest_azurite_standby.bash delete mode 100644 tests/centos7/provision/pgbackrest_gcs_primary.bash delete mode 100644 tests/centos7/provision/pgbackrest_gcs_standby.bash delete mode 100644 tests/centos7/provision/pgbackrest_local_primary.bash delete mode 100644 tests/centos7/provision/pgbackrest_local_standby.bash delete mode 100644 tests/centos7/provision/pgbackrest_minio_primary.bash delete mode 100644 tests/centos7/provision/pgbackrest_minio_standby.bash delete mode 100644 tests/centos7/provision/pgbackrest_remote_primary.bash delete mode 100644 tests/centos7/provision/pgbackrest_remote_standby.bash delete mode 100644 tests/centos7/vagrant.yml-dist create mode 100644 tests/ci.sh delete mode 100644 tests/common/regress/expected/version.out delete mode 100755 tests/common/regress/test-01.bash delete mode 100755 tests/common/scripts/simulate-basic-activity.bash delete mode 100755 tests/common/scripts/simulate-extended-activity.bash delete mode 100644 tests/common/ssh/authorized_keys delete mode 100644 tests/common/ssh/config delete mode 100644 tests/common/ssh/id_rsa delete mode 100644 tests/common/ssh/id_rsa.pub create mode 100644 tests/config.pl delete mode 100644 tests/debian/Makefile delete mode 100644 tests/debian/Vagrantfile delete mode 100644 tests/debian/provision/check_pgbackrest.bash delete mode 100644 tests/debian/provision/pgbackrest_local.bash delete mode 100644 tests/debian/provision/pgsql.bash create mode 100755 tests/platforms/azure/blob-create-container.py create mode 100644 tests/platforms/common/inventory/docker.j2 create mode 100644 tests/platforms/common/inventory/inventory.j2 create mode 100644 tests/platforms/common/inventory/write.yml create mode 100644 tests/platforms/common/provision.yml create mode 100644 tests/platforms/deprovision.yml create mode 100644 tests/platforms/docker/build_all_images.yml create mode 100644 tests/platforms/docker/deprovision-repository-types.yml create mode 100644 tests/platforms/docker/deprovision.yml create mode 100644 tests/platforms/docker/docker_container.yml create mode 100644 tests/platforms/docker/provision-repository-types.yml create mode 100644 tests/platforms/docker/provision.yml create mode 100644 tests/platforms/docker/systemd/centos.Dockerfile create mode 100644 tests/platforms/docker/systemd/debian.Dockerfile create mode 100644 tests/platforms/docker/systemd/ubuntu.Dockerfile create mode 100644 tests/platforms/load-config.yml create mode 100644 tests/platforms/provision.yml create mode 100644 tests/platforms/system-config.yml create mode 100644 tests/playbooks/activity.yml create mode 100644 tests/playbooks/deploy.yml rename tests/{common => playbooks}/regress/expected/archives-age-alert-ko.out (100%) rename tests/{common => playbooks}/regress/expected/archives-age-alert-ok.out (100%) rename tests/{common => playbooks}/regress/expected/archives-ignore-after.out (100%) rename tests/{common => playbooks}/regress/expected/archives-ignore-before.out (100%) rename tests/{common => playbooks}/regress/expected/archives-ok.out (100%) rename tests/{common => playbooks}/regress/expected/list.out (100%) rename tests/{common => playbooks}/regress/expected/retention-age-to-full.out (100%) rename tests/{common => playbooks}/regress/expected/retention-age.out (100%) rename tests/{common => playbooks}/regress/expected/retention-fail.out (100%) rename tests/{common => playbooks}/regress/expected/retention-full.out (100%) create mode 100755 tests/playbooks/regress/regression-tests.bash create mode 100644 tests/playbooks/scripts/simulate-activity-basic.bash create mode 100644 tests/playbooks/templates/profile.fact.j2 create mode 100644 tests/profile.d/c7epas.profile create mode 100644 tests/profile.d/c7pg.profile create mode 100644 tests/profile.d/d10epas.profile create mode 100644 tests/profile.d/d10pg.profile create mode 100644 tests/profile.d/u20epas.profile create mode 100644 tests/profile.d/u20pg.profile create mode 100644 tests/profile.d/vagrant.profile create mode 100644 tests/roles/setup_check_pgbackrest/defaults/main.yml create mode 100644 tests/roles/setup_check_pgbackrest/tasks/build.yml create mode 100644 tests/roles/setup_check_pgbackrest/tasks/icinga2-check.yml create mode 100644 tests/roles/setup_check_pgbackrest/tasks/icinga2-config.yml create mode 100644 tests/roles/setup_check_pgbackrest/tasks/main.yml create mode 100644 tests/roles/setup_pgbackrest/defaults/main.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/backup.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/build.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/client.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/create_user.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/info.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/main.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/server.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/ssh_setup.yml create mode 100644 tests/roles/setup_pgbackrest/tasks/stanza-create.yml create mode 100644 tests/roles/setup_pgbackrest/templates/pgbackrest-dbserver.conf.j2 create mode 100644 tests/roles/setup_pgbackrest/templates/pgbackrest-repository.conf.j2 create mode 100644 tests/roles/sys/pkg/defaults/main.yml create mode 100644 tests/roles/sys/pkg/tasks/main.yml create mode 100644 tests/roles/sys/tasks/main.yml create mode 100644 tests/run.sh create mode 100755 tests/vagrant.sh create mode 100644 tests/vagrant.yml-dist diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..1a33d8c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,75 @@ +--- +name: main + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + use-case-1: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - DOCKERI: centos:7 + DBTYPE: PG + DBVERSION: 13 + CLNAME: c7pg + EXTRA_VARS: "pgbackrest_excpected_release=2.34 check_pgbackrest_build=true" + + steps: + - uses: actions/checkout@v2 + - uses: shogo82148/actions-setup-perl@v1 + + - name: Initial step + run: sh run.sh -i + + - name: Run CI script + env: + EDB_REPO_USERNAME: ${{ secrets.EDB_REPO_USERNAME }} + EDB_REPO_PASSWORD: ${{ secrets.EDB_REPO_PASSWORD }} + ARCH: use-case-1 + CLPATH: /home/runner/clusters + CLNAME: ${{ matrix.CLNAME }} + DBTYPE: ${{ matrix.DBTYPE }} + DBVERSION: ${{ matrix.DBVERSION }} + DOCKERI: ${{ matrix.DOCKERI }} + EXTRA_VARS: ${{ matrix.EXTRA_VARS }} + run: sh ci.sh + + use-case-2: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - DOCKERI: ubuntu:20.04 + DBTYPE: PG + DBVERSION: 13 + CLNAME: u20pg + EXTRA_VARS: "pgbackrest_excpected_release=2.34 check_pgbackrest_build=true" + + steps: + - uses: actions/checkout@v2 + - uses: shogo82148/actions-setup-perl@v1 + + - name: Initial step + run: sh run.sh -i + + - name: Run CI script + env: + EDB_REPO_USERNAME: ${{ secrets.EDB_REPO_USERNAME }} + EDB_REPO_PASSWORD: ${{ secrets.EDB_REPO_PASSWORD }} + ARCH: use-case-2 + CLPATH: /home/runner/clusters + CLNAME: ${{ matrix.CLNAME }} + DBTYPE: ${{ matrix.DBTYPE }} + DBVERSION: ${{ matrix.DBVERSION }} + DOCKERI: ${{ matrix.DOCKERI }} + EXTRA_VARS: ${{ matrix.EXTRA_VARS }} + run: sh ci.sh \ No newline at end of file diff --git a/.gitignore b/.gitignore index ab9a3f6..ae120ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ .vagrant/ -tests/common/perf/nytprof* vagrant.yml -tests/common/configuration.profile -_old.* -*.rpm \ No newline at end of file +tests/validation.sh +tests/validation.log \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 06c8b8d..973668c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Changelog 2021-xx-xx v2.1: + - Only support pgBackRest **2.33** and above in order to introduce some basic + support for the multi-repository feature. + Introduce the `--repo` option to set the repository index to operate on. + When multiple repositories will be found, the `--repo` option is mandatory. - ... diff --git a/README b/README index 61fab00..fdc815d 100644 --- a/README +++ b/README @@ -18,6 +18,10 @@ DESCRIPTION -S, --stanza NAME Name of the stanza to check. + --repo REPOSITORY + Repository index to operate on. The "--repo" argument is mandatory + when multiple repositories are defined. + -O, --output OUTPUT_FORMAT The output format. Supported outputs are: "human", "json" and "nagios" (default). diff --git a/README.pod b/README.pod index 5bf63da..3a30198 100644 --- a/README.pod +++ b/README.pod @@ -24,6 +24,11 @@ list. Name of the stanza to check. +=item B<--repo> REPOSITORY + +Repository index to operate on. The C<--repo> argument is mandatory when +multiple repositories are defined. + =item B<-O>, B<--output> OUTPUT_FORMAT The output format. Supported outputs are: C, C and C (default). diff --git a/check_pgbackrest b/check_pgbackrest index 8abc768..b878756 100755 --- a/check_pgbackrest +++ b/check_pgbackrest @@ -63,7 +63,7 @@ my $output_fmt; $VERSION = '2.1dev'; $PROGRAM = 'check_pgbackrest'; -$PGBR_SUPPORT = '2.32'; +$PGBR_SUPPORT = '2.33'; $INIT_TIME = time(); # Available services and descriptions. @@ -99,6 +99,11 @@ list. Name of the stanza to check. +=item B<--repo> REPOSITORY + +Repository index to operate on. The C<--repo> argument is mandatory when +multiple repositories are defined. + =item B<-O>, B<--output> OUTPUT_FORMAT The output format. Supported outputs are: C, C and C (default). @@ -427,7 +432,11 @@ sub pgbackrest_info { if(defined $args{'config'}) { $infocmd .= " --config=".$args{'config'}; - } + } + + if(defined $args{'repo'}) { + $infocmd .= " --repo=".$args{'repo'}; + } if(defined $args{'prefix'}) { $infocmd = $args{'prefix'}." $infocmd"; @@ -467,6 +476,10 @@ sub pgbackrest_get { $getcmd .= " --config=".$args{'config'}; } + if(defined $args{'repo'}) { + $getcmd .= " --repo=".$args{'repo'}; + } + if(defined $args{'prefix'}) { $getcmd = $args{'prefix'}." $getcmd"; } @@ -501,7 +514,11 @@ sub pgbackrest_ls { if(defined $args{'config'}) { $lscmd .= " --config=".$args{'config'}; - } + } + + if(defined $args{'repo'}) { + $lscmd .= " --repo=".$args{'repo'}; + } if(defined $args{'prefix'}) { $lscmd = $args{'prefix'}." $lscmd"; @@ -576,6 +593,12 @@ sub check_retention { die("Can't get pgBackRest info.\n") unless (defined $backups_info); if($backups_info->{'status'}->{'code'} == 0) { + # Require the --repo option if multiple repositories are defined + pod2usage( + -message => 'FATAL: multiple repositories found, you must provide --repo.', + -exitval => 127 + ) if scalar(@{$backups_info->{'repo'}}) > 1 and not defined $args{'repo'}; + my @full_bck; my @diff_bck; my @incr_bck; @@ -629,6 +652,13 @@ sub check_retention { } }else{ push @crit_msg, $backups_info->{'status'}->{'message'}; + + # Add detailed messages in case of multiple repositories + if(scalar(@{$backups_info->{'repo'}}) > 1) { + foreach my $line (@{$backups_info->{'repo'}}) { + push @crit_msg, "repo".$line->{'key'}." - ".$line->{'status'}->{'message'}; + } + } } return critical($me, \@crit_msg, \@longmsg) if @crit_msg; @@ -734,7 +764,7 @@ sub get_archived_wal_list { push @filelist, [substr($filename, 0, 24), $filename, $list->{$key}->{'time'}, $list->{$key}->{'size'}, "$archives_dir/$key"]; }elsif($filename =~ /$history_re_full/ && $start_tl ne $end_tl){ - # Look for the last history file if needed + # Look for the last history file if needed dprint("history file to open : $archives_dir/$key\n"); my $history_content = pgbackrest_get(\%args, $archives_dir, $filename); @@ -807,6 +837,12 @@ sub check_wal_archives { dprint("!> pgBackRest info took ".(time() - $start_time)."s\n"); if($backups_info->{'status'}->{'code'} == 0) { + # Require the --repo option if multiple repositories are defined + pod2usage( + -message => 'FATAL: multiple repositories found, you must provide --repo.', + -exitval => 127 + ) if scalar(@{$backups_info->{'repo'}}) > 1 and not defined $args{'repo'}; + my $archives_dir = "archive/".$args{'stanza'}."/".$backups_info->{'archive'}[0]->{'id'}; # Relative path inside repository dprint("archives_dir: $archives_dir\n"); my $min_wal = $backups_info->{'archive'}[0]->{'min'}; @@ -1045,6 +1081,7 @@ GetOptions( 'list-archives|L!', 'output|O=s', 'prefix|P=s', + 'repo=s', 'retention-age=s', 'retention-age-to-full=s', 'retention-full=i', diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..3a7c288 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,42 @@ +### Global variables +# disable running the activity script by default +ACTIVITY='false' +# define PG on CentOS 7 as default profile +PROFILE='c7pg' + +### Make targets +init: clean_vm create_vm + +uc1: + ACTIVITY=$(ACTIVITY) ARCH='use-case-1' EXTRA="$(EXTRA) check_pgbackrest_build=true deploy_icinga2=true" PGBR_BUILD='false' PGBR_REPO_TYPE=$(PGBR_REPO_TYPE) PROFILE=$(PROFILE) vagrant up --provision-with=exec-ci +uc1_full: + ACTIVITY=$(ACTIVITY) ARCH='use-case-1' EXTRA="$(EXTRA) check_pgbackrest_build=true deploy_icinga2=true" PGBR_BUILD='true' PGBR_REPO_TYPE=$(PGBR_REPO_TYPE) PROFILE=$(PROFILE) vagrant up --provision-with=exec-ci +uc1_light: + ACTIVITY=$(ACTIVITY) ARCH='use-case-1' EXTRA="$(EXTRA)" PGBR_BUILD='false' PGBR_REPO_TYPE=$(PGBR_REPO_TYPE) PROFILE=$(PROFILE) vagrant up --provision-with=exec-ci + +uc2: + ACTIVITY=$(ACTIVITY) ARCH='use-case-2' EXTRA="$(EXTRA) check_pgbackrest_build=true deploy_icinga2=true" PGBR_BUILD='false' PGBR_REPO_TYPE=$(PGBR_REPO_TYPE) PROFILE=$(PROFILE) vagrant up --provision-with=exec-ci +uc2_full: + ACTIVITY=$(ACTIVITY) ARCH='use-case-2' EXTRA="$(EXTRA) check_pgbackrest_build=true deploy_icinga2=true" PGBR_BUILD='true' PGBR_REPO_TYPE=$(PGBR_REPO_TYPE) PROFILE=$(PROFILE) vagrant up --provision-with=exec-ci +uc2_light: + ACTIVITY=$(ACTIVITY) ARCH='use-case-2' EXTRA="$(EXTRA)" PGBR_BUILD='false' PGBR_REPO_TYPE=$(PGBR_REPO_TYPE) PROFILE=$(PROFILE) vagrant up --provision-with=exec-ci + +### Setup +clean_ci: + PROFILE=$(PROFILE) vagrant up --provision-with=clean-ci + +clean_docker: + vagrant ssh -c "docker rm -f $(docker ps -a -q)" + +clean_git: + git clean -f -dX --dry-run + +clean_icinga2: + vagrant ssh -c "docker stop $(PROFILE)-icinga2 && docker rm $(PROFILE)-icinga2" + +clean_vm: + vagrant destroy -f + +create_vm: + vagrant up + vagrant ssh -c "sh /vagrant/run.sh -i" \ No newline at end of file diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..149c1e3 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,79 @@ +# README + + + +--- + +## Introduction + +This _Test Suite_ is based on the [edb-ansible](https://github.com/EnterpriseDB/edb-ansible) Ansible Collection. It deploys docker containers and typical architectures. + +It tends to support the following situations: +* Directly-attached storage - [Use Case 1](https://www.enterprisedb.com/docs/supported-open-source/pgbackrest/06-use_case_1/) +* Dedicated repository host - [Use Case 2](https://www.enterprisedb.com/docs/supported-open-source/pgbackrest/07-use_case_2) + +--- + +## GitHub Actions + +[GitHub Actions](../.github/workflows/main.yml) are testing: + * Use-Case 1: PG 13, CentOS 7, using pgBackRest PGDG packages + * Use-Case 2: PG 13, Ubuntu 20.04, using pgBackRest PGDG packages + +--- + +## Vagrant + +To be able to run the tests manually, define your EDB repositories personal credential `vagrant.yml`. Example in [vagrant.yml-dist](vagrant.yml-dist). + +First of all, initialize the virtual machine with `make init`. + +* Deploy Use-Case 1 and run the activity script: `make ACTIVITY=true uc1` +* Deploy Use-Case 2 and run the activity script: `make ACTIVITY=true uc2` + +To build pgBackRest from sources, use `uc1_full` or `uc2_full` make targets. + +To install pgBackRest and **check_pgbackrest** using PGDG packages, without deploying Icinga2, use `uc1_light` or `uc2_light` make targets. + +### Change the test profile + +Add `PROFILE=xxx` to the make command. + +Available profiles: `c7epas`, `c7pg`, `d10epas`, `d10pg`, `u20epas`, `u20pg`. + +### Change the pgBackRest repository type + +Add `PGBR_REPO_TYPE=xxx` to the make command. + +Available types: `azure`, `s3`, `multi`, `posix`. + +When setting `multi` repository, both `s3` and `azure` will be used. When setting `posix` repository, the repository path will be automatically adjusted to `/shared/repo1` where */shared* is a shared volume between the docker containers. + +### Icinga2 + +To interact with Icinga2, the easiest way is to use the API: + +```bash +# Login to the vagrant box +$ vagrant ssh + +# Reschedule check_pgbackrest checks +$ curl -k -s -u 'icinga2-director:anyPassWord' -H 'Accept: application/json' -X POST \ + 'https://localhost:5665/v1/actions/reschedule-check' \ + -d '{ "type": "Service", "filter": "match(pattern,service.name)", "filter_vars": { "pattern": "pgbackrest*" }, "pretty": true }' |jq + +# Get check_pgbackrest checks status +$ curl -k -s -u 'icinga2-director:anyPassWord' -H 'Accept: application/json' -X GET \ + 'https://localhost:5665/v1/objects/services' \ + -d '{ "filter": "match(pattern,service.name)", "filter_vars": { "pattern": "pgbackrest*" } }' |jq +``` + +### Cleaning + +Before changing the `PROFILE` to deploy a new architecture, remove the docker containers and cluster directory using `make PROFILE=xxx clean_ci`. + +To remove the vagrant virtual machine: `make clean_vm`. diff --git a/tests/VALIDATION.md b/tests/VALIDATION.md new file mode 100644 index 0000000..8b4f16c --- /dev/null +++ b/tests/VALIDATION.md @@ -0,0 +1,51 @@ +# Validation process + +First of all, initialize the virtual machine: + +```bash +time make init +``` + +## PostgreSQL + +```bash +# Use case 1 - CentOS 7 - pgBackRest packages, multi-repositories +time make ACTIVITY=true PROFILE=c7pg PGBR_REPO_TYPE=multi uc1 +make PROFILE=c7pg clean_ci + +# Use case 2 - CentOS 7 - pgBackRest packages +time make ACTIVITY=true PROFILE=c7pg uc2 +make PROFILE=c7pg clean_ci + +# Use case 1 - Ubuntu 20.04 - pgBackRest packages +time make ACTIVITY=true PROFILE=u20pg uc1 +make PROFILE=u20pg clean_ci + +# Use case 2 - Ubuntu 20.04 - pgBackRest packages, multi-repositories +time make ACTIVITY=true PROFILE=u20pg PGBR_REPO_TYPE=multi uc2 +make PROFILE=u20pg clean_ci +``` + +* To build pgBackRest from sources, use `uc1_full` of `uc2_full` make target + +## EDB Postgres Advanced Server + +```bash +# Use case 1 - CentOS 7 - pgBackRest packages, multi-repositories +time make ACTIVITY=true PROFILE=c7epas PGBR_REPO_TYPE=multi uc1 +make PROFILE=c7epas clean_ci + +# Use case 2 - CentOS 7 - pgBackRest packages +time make ACTIVITY=true PROFILE=c7epas uc2 +make PROFILE=c7epas clean_ci + +# Use case 1 - Ubuntu 20.04 - pgBackRest packages +time make ACTIVITY=true PROFILE=u20epas uc1 +make PROFILE=u20epas clean_ci + +# Use case 2 - Ubuntu 20.04 - pgBackRest packages, multi-repositories +time make ACTIVITY=true PROFILE=u20epas PGBR_REPO_TYPE=multi uc2 +make PROFILE=u20epas clean_ci +``` + +* To build pgBackRest from sources, use `uc1_full` of `uc2_full` make target \ No newline at end of file diff --git a/tests/Vagrantfile b/tests/Vagrantfile new file mode 100644 index 0000000..c6d6162 --- /dev/null +++ b/tests/Vagrantfile @@ -0,0 +1,78 @@ +require 'yaml' + +if File.file?('vagrant.yml') and ( custom = YAML.load_file('vagrant.yml') ) + edb_repository_username = custom['edb_repository_username'] if custom.has_key?('edb_repository_username') + edb_repository_password = custom['edb_repository_password'] if custom.has_key?('edb_repository_password') + pgbackrest_git_url = custom['pgbackrest_git_url'] if custom.has_key?('pgbackrest_git_url') + pgbackrest_git_branch = custom['pgbackrest_git_branch'] if custom.has_key?('pgbackrest_git_branch') +end + +Vagrant.configure(2) do |config| + config.vm.provider :virtualbox do |vb| + vb.memory = 4096 + vb.cpus = 4 + vb.name = "check_pgbackrest-docker-host" + end + + config.vm.box = "bento/ubuntu-20.04" + # config.vm.box = "ubuntu/focal64" + config.ssh.insert_key = false + # mount check_pgbackrest path for development testing + config.vm.synced_folder "..", "/check_pgbackrest" + # mount edb-ansible local git clone + if File.directory?(File.expand_path("../../edb-ansible")) + config.vm.synced_folder "../../edb-ansible", "/edb-ansible" + end + + config.vm.provision "shell", inline: <<-SHELL + #----------------------------------------------------------------------------------------------------------------------- + echo 'Install Docker' && date + curl -fsSL https://get.docker.com | sh + usermod -aG docker vagrant + #----------------------------------------------------------------------------------------------------------------------- + echo 'Install Perl modules' && date + apt-get install -y libyaml-libyaml-perl jq + SHELL + + config.vm.provision "shell", privileged: false, inline: <<-SHELL + #----------------------------------------------------------------------------------------------------------------------- + echo 'Install Ansible' && date + sudo apt-get install -y python3-pip python3-venv + python3 -m pip install --user pipx + python3 -m pipx ensurepath + python3 -m pipx install ansible-base + SHELL + + # Execute CI script in Vagrant environment + config.vm.provision "exec-ci", privileged: false, type: "shell", + path: 'vagrant.sh', + env: { + "ACTIVITY" => ENV['ACTIVITY'], + "ARCH" => ENV['ARCH'], + "EXTRA" => ENV['EXTRA'], + "PGBR_BUILD" => ENV['PGBR_BUILD'], + "PGBR_REPO_TYPE" => ENV['PGBR_REPO_TYPE'], + "PROFILE" => ENV['PROFILE'], + "edb_repository_username" => edb_repository_username, + "edb_repository_password" => edb_repository_password, + "pgbackrest_git_url" => pgbackrest_git_url, + "pgbackrest_git_branch" => pgbackrest_git_branch + }, + run: 'never' + + # Clean a specific cluster in Vagrant environment + $clean_script = <<-SCRIPT + cd /vagrant + echo "PROFILE = '$PROFILE'" + source profile.d/$PROFILE.profile + source profile.d/vagrant.profile + sh run.sh -C -c "$CLPATH/$CLNAME" + SCRIPT + + config.vm.provision "clean-ci", privileged: false, type: 'shell', + inline: $clean_script, + env: { + "PROFILE" => ENV['PROFILE'] + }, + run: 'never' +end diff --git a/tests/architectures/use-case-1/config.yml b/tests/architectures/use-case-1/config.yml new file mode 100644 index 0000000..fcf5bf3 --- /dev/null +++ b/tests/architectures/use-case-1/config.yml @@ -0,0 +1,32 @@ +--- +cluster_name: use-case-1 +platform: docker +docker: + image_name: centos:7 + exposed_ports: + - '22' + - '5432' + - '5444' + +cluster_vars: + pg_version: 13 + pg_type: PG + disable_logging: false + pgbackrest_repo_type: s3 + +instances: +- name: pg1 + ansible_group: primary + pgbackrest: true + +- name: pg2 + ansible_group: standby + upstream: pg1 + replication_type: asynchronous + pgbackrest: true + +- name: pg3 + ansible_group: standby + upstream: pg1 + replication_type: asynchronous + pgbackrest: true diff --git a/tests/architectures/use-case-2/config.yml b/tests/architectures/use-case-2/config.yml new file mode 100644 index 0000000..0665350 --- /dev/null +++ b/tests/architectures/use-case-2/config.yml @@ -0,0 +1,37 @@ +--- +cluster_name: use-case-2 +platform: docker +docker: + image_name: centos:7 + exposed_ports: + - '22' + - '5432' + - '5444' + +cluster_vars: + pg_version: 13 + pg_type: PG + disable_logging: false + +instances: +- name: backup + ansible_group: pgbackrest_repo_host + +- name: pg1 + ansible_group: primary + pgbackrest: true + pgbackrest_repo_host: backup + +- name: pg2 + ansible_group: standby + upstream: pg1 + replication_type: asynchronous + pgbackrest: true + pgbackrest_repo_host: backup + +- name: pg3 + ansible_group: standby + upstream: pg1 + replication_type: asynchronous + pgbackrest: true + pgbackrest_repo_host: backup diff --git a/tests/centos7/Makefile b/tests/centos7/Makefile deleted file mode 100644 index f831ceb..0000000 --- a/tests/centos7/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -### Global variables -EPAS='false' - -### Make scenario -s1: clean create_vm cifs pgbackrest_local icinga2_multi generate_config_file_local -s1_full: clean create_vm cifs pgbackrest_build pgbackrest_local icinga2_multi generate_config_file_local -s1_light: clean create_vm cifs pgbackrest_local generate_config_file_local - -s2: clean create_vm pgbackrest_remote icinga2_multi generate_config_file_remote -s2_full: clean create_vm pgbackrest_build pgbackrest_remote icinga2_multi generate_config_file_remote -s2_light: clean create_vm pgbackrest_remote generate_config_file_remote - -s3: clean create_vm pgbackrest_minio icinga2_multi generate_config_file_local -s3_full: clean create_vm pgbackrest_build pgbackrest_minio icinga2_multi generate_config_file_local -s3_light: clean create_vm pgbackrest_minio generate_config_file_local - -s4: clean create_vm pgbackrest_azurite icinga2_multi generate_config_file_local -s4_full: clean create_vm pgbackrest_build pgbackrest_azurite icinga2_multi generate_config_file_local -s4_light: clean create_vm pgbackrest_azurite generate_config_file_local - -s5: clean create_vm pgbackrest_gcs icinga2_multi generate_config_file_local -s5_full: clean create_vm pgbackrest_build pgbackrest_gcs icinga2_multi generate_config_file_local -s5_light: clean create_vm pgbackrest_gcs generate_config_file_local - -### Setup -clean: - vagrant destroy -f - -clean_git: - git clean -f -dX --dry-run - -create_vm: - EPAS=$(EPAS) vagrant up - -### Configuration -cifs: - vagrant up --provision-with=cifs - -pgbackrest_local: - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_local_primary - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_local_standby - -pgbackrest_remote: - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_remote_primary - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_remote_standby - -pgbackrest_minio: - vagrant up --provision-with=minio - vagrant up --provision-with=minio_http - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_minio_primary - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_minio_standby - -pgbackrest_azurite: - vagrant up --provision-with=azurite - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_azurite_primary - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_azurite_standby - -pgbackrest_gcs: - vagrant up --provision-with=gcs - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_gcs_primary - EPAS=$(EPAS) vagrant up --provision-with=pgbackrest_gcs_standby - -icinga2_multi: - EPAS=false vagrant up --provision-with=icinga2 # use PostgreSQL to install icinga2 - EPAS=$(EPAS) vagrant up --provision-with=icinga2_multi - -### Specific operations -pgbackrest_build: - EPAS=$(EPAS) vagrant up --no-parallel --provision-with=pgbackrest_build - -perl_build: - vagrant up --provision-with=perl_build - -generate_config_file_local: - EPAS=$(EPAS) SPROFILE='local' vagrant up --provision-with=generate_config_file - -generate_config_file_remote: - EPAS=$(EPAS) SPROFILE='remote' vagrant up --provision-with=generate_config_file diff --git a/tests/centos7/README.md b/tests/centos7/README.md deleted file mode 100644 index 125d354..0000000 --- a/tests/centos7/README.md +++ /dev/null @@ -1,156 +0,0 @@ -# check_pgbackrest - -## Introduction - -This `Vagrantfile` is bootstrapping 3 possible test cases: - -### 1. pgBackRest configured to backup and archive on a CIFS mount - - * `icinga-srv` executes check_pgbackrest by ssh with Icinga 2; - * `pgsql-srv` hosting a primary pgsql cluster with pgBackRest installed; - * `backup-srv` hosting the CIFS share; - * pgBackRest backups are used to build a Streaming Replication with `backup-srv` as standby server. - -Backups and archiving are done locally on `pgsql-srv` on the CIFS mount point. - - -### 2. pgBackRest configured to backup and archive remotely - - * `icinga-srv` executes check_pgbackrest by ssh with Icinga 2; - * `pgsql-srv` hosting a primary pgsql cluster with pgBackRest installed; - * `backup-srv` acting as pgBackRest repository host; - * pgBackRest backups are used to build a Streaming Replication with `backup-srv` as standby server. - -Backups of `pgsql-srv` are taken from `backup-srv`. -Archives are pushed from `pgsql-srv` to `backup-srv`. - -### 3. pgBackRest configured to backup and archive to a MinIO S3 bucket - - * `icinga-srv` executes check_pgbackrest by ssh with Icinga 2; - * `pgsql-srv` hosting a primary pgsql cluster with pgBackRest installed; - * `backup-srv` hosting the MinIO server; - * pgBackRest backups are used to build a Streaming Replication with `backup-srv` as standby server. - -### 4. pgBackRest configured to backup and archive to an Azurite container - - * `icinga-srv` executes check_pgbackrest by ssh with Icinga 2; - * `pgsql-srv` hosting a primary pgsql cluster with pgBackRest installed; - * `backup-srv` hosting an Azurite docker container; - * pgBackRest backups are used to build a Streaming Replication with `backup-srv` as standby server. - -### 5. pgBackRest configured to backup and archive to a fake-gcs-server container - - * `icinga-srv` executes check_pgbackrest by ssh with Icinga 2; - * `pgsql-srv` hosting a primary pgsql cluster with pgBackRest installed; - * `backup-srv` hosting a fake-gcs-server docker container; - * pgBackRest backups are used to build a Streaming Replication with `backup-srv` as standby server. - -## Testing - -The easiest way to start testing is with the included `Makefile`. - - * `s*`: pgBackRest installed from PGDG repository, Icinga 2 configured; - * `s*_full`: build pgBackRest from sources, Icinga 2 configured; - * `s*_light`: pgBackRest installed from PGDG repository, Icinga 2 not installed. - -### Build - -_Test case 1_: - -```bash -make s1 -``` - -_Test case 2_: - -```bash -make s2 -``` - -_Test case 3_: - -```bash -make s3 -``` - -_Test case 4_: - -```bash -make s4 -``` - -_Test case 5_: - -```bash -make s5 -``` - -After each build, a `configuration.profile` file is generated. -This allows the various regress and activity scripts to adjust their settings -according to the test case built. - -### Check the results of a manual execution - -```bash -vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/test/regress/test-01.bash" -``` - -### Simulate some activity - -- pgbench activity, backup and local and remote restore: - -```bash -vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s -a " -``` - -- corrupt some data pages and setup asynchronous archiving: - -```bash -vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-extended-activity.bash" -``` - -### Icinga 2 connectivity - -_Check the results of _check_pgbackrest_ launched by Icinga 2: - -```bash -vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" -``` - -_Navigate to Icinga Web 2_: - -Get the IP address of `icinga-srv` with: - -```bash -vagrant ssh icinga-srv -c "ip addr show eth0" -``` - -And then go to `http://IP/icingaweb2`. Credentials are `icingaweb / icingaweb`. - -### Clean up - -Don't forget to clean the VM's after the tests: - -```bash -make clean -``` - -## Tips - -Find all existing VM created by vagrant on your system: - -```bash -vagrant global-status -``` - -Shutdown all VM: - -```bash -vagrant halt -``` - -Restart the halted cluster: - -```bash -vagrant up -``` diff --git a/tests/centos7/VALIDATION.md b/tests/centos7/VALIDATION.md deleted file mode 100644 index 1cb490e..0000000 --- a/tests/centos7/VALIDATION.md +++ /dev/null @@ -1,69 +0,0 @@ -# Validation process - -## PostgreSQL - -```bash -# Test case 1 -time sudo make s1 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 2 -time sudo make s2 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 3 -time sudo make s3 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 4 -time sudo make s4 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 5 -time sudo make s5 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 1 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" -``` - -## EDB Postgres Advanced Server - -```bash -# Test case 1 -time sudo make EPAS='true' s1 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 2 -time sudo make EPAS='true' s2 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 3 -time sudo make EPAS='true' s3 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 4 -time sudo make EPAS='true' s4 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 10 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" - -# Test case 5 -time sudo make EPAS='true' s5 -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/scripts/simulate-basic-activity.bash -s 1 -a 10" -time sudo vagrant ssh pgsql-srv -c "sudo /check_pgbackrest/tests/common/regress/test-01.bash -s -P /check_pgbackrest" -time sudo vagrant ssh icinga-srv -c "sudo icingacli monitoring list services --service=pgbackrest* --verbose" -``` diff --git a/tests/centos7/Vagrantfile b/tests/centos7/Vagrantfile deleted file mode 100644 index 5d4f336..0000000 --- a/tests/centos7/Vagrantfile +++ /dev/null @@ -1,240 +0,0 @@ -require 'yaml' - -# default variable values -pgver = '13' -pgbr_branch = 'release/2.34' -vm_prefix = 'check_pgbr_c7' -encrypted_repo = 'true' -edb_repository_username = 'username' -edb_repository_password = 'password' - -if File.file?('vagrant.yml') and ( custom = YAML.load_file('vagrant.yml') ) - pgver = custom['pgver'] if custom.has_key?('pgver') - pgbr_branch = custom['pgbr_branch'] if custom.has_key?('pgbr_branch') - vm_prefix = custom['vm_prefix'] if custom.has_key?('vm_prefix') - encrypted_repo = custom['encrypted_repo'] if custom.has_key?('encrypted_repo') - edb_repository_username = custom['edb_repository_username'] if custom.has_key?('edb_repository_username') - edb_repository_password = custom['edb_repository_password'] if custom.has_key?('edb_repository_password') -end - -epas = 'false' -if defined?(ENV['EPAS']) and ENV['EPAS'] == 'true' - epas = 'true' -end - -Vagrant.configure(2) do |config| - - if epas == 'true' - pgdata = "/var/lib/edb/as#{pgver}/data" - pguser = "enterprisedb" - pgport = 5444 - pgsvc = "edb-as-#{pgver}" - else - pgdata = "/var/lib/pgsql/#{pgver}/data" - pguser = "postgres" - pgport = 5432 - pgsvc = "postgresql-#{pgver}" - end - - config.vm.box = 'centos/7' - - # hardware and host settings - config.vm.provider 'libvirt' do |lv| - lv.cpus = 1 - lv.memory = 2048 - lv.default_prefix = vm_prefix - end - - # don't mind about insecure ssh key - config.ssh.insert_key = false - - # share the default vagrant folder - config.vm.synced_folder ".", "/vagrant" - - # mount check_pgbackrest path for testing - config.vm.synced_folder "../..", "/check_pgbackrest", type: "nfs" - if File.directory?(File.expand_path("../../../pgbackrest")) - config.vm.synced_folder "../../../pgbackrest", "/pgbackrest", type: "nfs" - end - - # ssh configuration - config.vm.synced_folder '../common/ssh', '/root/.ssh', type: 'rsync', - owner: 'root', group: 'root', - rsync__args: [ "--verbose", "--archive", "--delete", "--copy-links", "--no-perms" ] - - # check_pgbackrest install on all the nodes - config.vm.provision 'check_pgbackrest', type: 'shell', path: 'provision/check_pgbackrest.bash' - - config.vm.define "icinga-srv" do |icinga| - icinga.vm.hostname = "icinga-srv" - - # install PostgreSQL - icinga.vm.provision 'pgsql', type: 'shell', - path: 'provision/PGDG/pgsql.bash', - args: [ pgver, "/var/lib/pgsql/#{pgver}/data", "postgres" ] - - # icinga2 local setup - icinga.vm.provision 'icinga2', type: 'shell', - path: 'provision/icinga2.bash', run: 'never' - - # pgbackrest setup - icinga.vm.provision 'icinga2_multi', type: 'shell', - path: 'provision/icinga2_multi.bash', - args: [ pguser ], - run: 'never' - end - - config.vm.define "pgsql-srv" do |pgsql| - pgsql.vm.hostname = "pgsql-srv" - - if epas == 'true' - # install EDB Postgres Advanced Server - pgsql.vm.provision 'epas', type: 'shell', - path: 'provision/EDB/epas.bash', - args: [ pgver, pgdata, pguser, pgport, edb_repository_username, edb_repository_password ] - - # compile pgBackRest besides EDB Postgres Advanced Server - pgsql.vm.provision 'pgbackrest_build', type: 'shell', - path: 'provision/EDB/pgbackrest_build.bash', - args: [ pgver, pgbr_branch ], - run: 'never' - else - # install PostgreSQL - pgsql.vm.provision 'pgsql', type: 'shell', - path: 'provision/PGDG/pgsql.bash', - args: [ pgver, pgdata, pguser ] - - # compile pgBackRest besides PostgreSQL - pgsql.vm.provision 'pgbackrest_build', type: 'shell', - path: 'provision/PGDG/pgbackrest_build.bash', - args: [ pgbr_branch ], - run: 'never' - end - - # pgbackrest local setup - pgsql.vm.provision 'pgbackrest_local_primary', type: 'shell', - path: 'provision/pgbackrest_local_primary.bash', - args: [ pgver, pgdata, pguser, pgport, encrypted_repo ], - run: 'never' - - # pgbackrest remote setup - pgsql.vm.provision 'pgbackrest_remote_primary', type: 'shell', - path: 'provision/pgbackrest_remote_primary.bash', - args: [ pgver, pgdata, pguser, pgport, encrypted_repo ], - run: 'never' - - # pgbackrest minio setup - pgsql.vm.provision 'pgbackrest_minio_primary', type: 'shell', - path: 'provision/pgbackrest_minio_primary.bash', - args: [ pgver, pgdata, pguser, pgport, encrypted_repo ], - run: 'never' - - # pgbackrest azurite setup - pgsql.vm.provision 'pgbackrest_azurite_primary', type: 'shell', - path: 'provision/pgbackrest_azurite_primary.bash', - args: [ pgver, pgdata, pguser, pgport, encrypted_repo ], - run: 'never' - - # pgbackrest gcs setup - pgsql.vm.provision 'pgbackrest_gcs_primary', type: 'shell', - path: 'provision/pgbackrest_gcs_primary.bash', - args: [ pgver, pgdata, pguser, pgport, encrypted_repo ], - run: 'never' - - # generate configuration file for common scripts - $script = <<-SCRIPT - echo export PGVER=\\"$1\\" > $7 - echo export PGDATA=\\"$2\\" >> $7 - echo export PGUSER=\\"$3\\" >> $7 - echo export PGPORT=\\"$4\\" >> $7 - echo export PGSVC=\\"$5\\" >> $7 - echo export SPROFILE=\\"$6\\" >> $7 - SCRIPT - - pgsql.vm.provision 'generate_config_file', type: 'shell', - inline: $script, run: 'never', - args: [ pgver, pgdata, pguser, pgport, pgsvc, ENV['SPROFILE'] || 'local', '/check_pgbackrest/tests/common/configuration.profile' ] - end - - config.vm.define "backup-srv" do |backup| - backup.vm.hostname = "backup-srv" - - # cifs share to store pgbackrest backups - backup.vm.provision 'cifs', type: 'shell', - path: 'provision/cifs.bash', run: 'never' - - if epas == 'true' - # install EDB Postgres Advanced Server - backup.vm.provision 'epas', type: 'shell', - path: 'provision/EDB/epas.bash', - args: [ pgver, pgdata, pguser, pgport, edb_repository_username, edb_repository_password ] - - # compile pgBackRest besides EDB Postgres Advanced Server - backup.vm.provision 'pgbackrest_build', type: 'shell', - path: 'provision/EDB/pgbackrest_build.bash', - args: [ pgver, pgbr_branch ], - run: 'never' - else - # install PostgreSQL - backup.vm.provision 'pgsql', type: 'shell', - path: 'provision/PGDG/pgsql.bash', - args: [ pgver, pgdata, pguser ] - - # compile pgBackRest besides PostgreSQL - backup.vm.provision 'pgbackrest_build', type: 'shell', - path: 'provision/PGDG/pgbackrest_build.bash', - args: [ pgbr_branch ], - run: 'never' - end - - # pgbackrest local setup - backup.vm.provision 'pgbackrest_local_standby', type: 'shell', - path: 'provision/pgbackrest_local_standby.bash', - args: [ pgver, pgdata, pguser, pgport, pgsvc, encrypted_repo ], - run: 'never' - - # pgbackrest remote setup - backup.vm.provision 'pgbackrest_remote_standby', type: 'shell', - path: 'provision/pgbackrest_remote_standby.bash', - args: [ pgver, pgdata, pguser, pgport, pgsvc, encrypted_repo ], - run: 'never' - - # pgbackrest minio setup - backup.vm.provision 'pgbackrest_minio_standby', type: 'shell', - path: 'provision/pgbackrest_minio_standby.bash', - args: [ pgver, pgdata, pguser, pgport, pgsvc, encrypted_repo ], - run: 'never' - - # pgbackrest azurite setup - backup.vm.provision 'pgbackrest_azurite_standby', type: 'shell', - path: 'provision/pgbackrest_azurite_standby.bash', - args: [ pgver, pgdata, pguser, pgport, pgsvc, encrypted_repo ], - run: 'never' - - # pgbackrest gcs setup - backup.vm.provision 'pgbackrest_gcs_standby', type: 'shell', - path: 'provision/pgbackrest_gcs_standby.bash', - args: [ pgver, pgdata, pguser, pgport, pgsvc, encrypted_repo ], - run: 'never' - - # minio local setup - backup.vm.provision 'minio', type: 'shell', - path: 'provision/minio.bash', run: 'never' - - # minio http setup - backup.vm.provision 'minio_http', type: 'shell', - path: 'provision/minio_http.bash', run: 'never' - - # azurite local setup - backup.vm.provision 'azurite', type: 'shell', - path: 'provision/azurite.bash', run: 'never' - - # fake-gcs-server local setup - backup.vm.provision 'gcs', type: 'shell', - path: 'provision/gcs.bash', run: 'never' - end - - # build a specific Perl version on all the nodes - config.vm.provision 'perl_build', type: 'shell', - path: 'provision/perl_build.bash', run: 'never' -end diff --git a/tests/centos7/provision/EDB/epas.bash b/tests/centos7/provision/EDB/epas.bash deleted file mode 100644 index fe692ab..0000000 --- a/tests/centos7/provision/EDB/epas.bash +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -REPO_USER="$5" -REPO_PWD="$6" - -# configure EDB repo and install required packages -cat< "/etc/yum.repos.d/edb.repo" -[edb] -name=EnterpriseDB RPMs \$releasever - \$basearch -baseurl=https://${REPO_USER}:${REPO_PWD}@yum.enterprisedb.com/edb/redhat/rhel-\$releasever-\$basearch -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/ENTERPRISEDB-GPG-KEY - -[edb-testing] -name=EnterpriseDB Testing - Not For Production \$releasever - \$basearch -baseurl=https://${REPO_USER}:${REPO_PWD}@yum.enterprisedb.com/edb-testing/redhat/rhel-\$releasever-\$basearch -enabled=0 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/ENTERPRISEDB-GPG-KEY -EOF - -curl --silent -o /etc/pki/rpm-gpg/ENTERPRISEDB-GPG-KEY https://${REPO_USER}:${REPO_PWD}@yum.enterprisedb.com/ENTERPRISEDB-GPG-KEY -rpm --import /etc/pki/rpm-gpg/ENTERPRISEDB-GPG-KEY -yum install --nogpgcheck --quiet -y -e 0 edb-as${PGVER}-server - -# firewall setup -firewall-cmd --quiet --permanent --add-port=${PGPORT}/tcp -firewall-cmd --quiet --reload - -# init instance -systemctl stop "edb-as-${PGVER}" -systemctl disable "edb-as-${PGVER}" -rm -rf "${PGDATA}" -export PGSETUP_INITDB_OPTIONS="-E UTF-8 --data-checksums" -"/usr/edb/as${PGVER}/bin/edb-as-${PGVER}-setup" initdb - -# pg_hba setup -cat< "${PGDATA}/pg_hba.conf" -local all all trust -host all all 0.0.0.0/0 trust -host all all ::/0 trust -local replication all trust -host replication all 0.0.0.0/0 trust -host replication all ::/0 trust -EOC - -systemctl enable "edb-as-${PGVER}" -systemctl start "edb-as-${PGVER}" - -# postgresql.conf setup -cat <<'EOS' | "/usr/edb/as${PGVER}/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "listen_addresses" TO '*'; -ALTER SYSTEM SET "wal_level" TO 'replica'; -ALTER SYSTEM SET "archive_mode" TO 'on'; -ALTER SYSTEM SET "archive_command" TO '/bin/true'; -EOS - -# restart pgsql server -systemctl restart "edb-as-${PGVER}" -echo "pathmunge /usr/edb/as${PGVER}/bin" > /etc/profile.d/epas${PGVER}.sh -chmod +x /etc/profile.d/epas${PGVER}.sh - -# force proper permissions on .ssh files -cp -rf /root/.ssh /var/lib/edb/.ssh -chown -R ${PGUSER}: /var/lib/edb/.ssh -restorecon -R /var/lib/edb/.ssh -usermod -aG ${PGUSER} accessed_by_ssh - -# install pgBackRest -yum install --nogpgcheck --quiet -y -e 0 "https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm" - -if ls /vagrant/rpms/pgbackrest-*.rhel7.x86_64.rpm &> /dev/null; then - echo "-----Install the following provided rpm" - ls /vagrant/rpms/pgbackrest-*.rhel7.x86_64.rpm - yum install --nogpgcheck --quiet -y -e 0 /vagrant/rpms/pgbackrest-*.rhel7.x86_64.rpm -else - yum install --nogpgcheck --quiet -y -e 0 pgbackrest -fi - -chown -R ${PGUSER}: /var/lib/pgbackrest -chown -R ${PGUSER}: /var/log/pgbackrest -chown -R ${PGUSER}: /var/spool/pgbackrest \ No newline at end of file diff --git a/tests/centos7/provision/EDB/pgbackrest_build.bash b/tests/centos7/provision/EDB/pgbackrest_build.bash deleted file mode 100755 index a1aa8df..0000000 --- a/tests/centos7/provision/EDB/pgbackrest_build.bash +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGBR_BRANCH="$2" -EDB_PATH="/usr/edb/as${PGVER}" - -if [[ -e "/usr/bin/pgbackrest" && ! -L "/usr/bin/pgbackrest" ]]; then - mv /usr/bin/pgbackrest /usr/bin/pgbackrest.origin - ORIG_VERSION=`/usr/bin/pgbackrest.origin version | sed -e s/pgBackRest\ //` - alternatives --install /usr/bin/pgbackrest pgbackrest /usr/bin/pgbackrest.origin `echo $ORIG_VERSION | tr -d . | tr -d dev` -fi - -if [ -e $EDB_PATH/bin/pgbackrest ]; then - rm -f $EDB_PATH/bin/pgbackrest -fi - -yum install --nogpgcheck --quiet -y -e 0 make gcc openssl-devel libxml2-devel lz4-devel libzstd-devel bzip2-devel libyaml-devel - -if [ ! -d /build ]; then - mkdir /build -else - rm -rf /build/pgbackrest -fi - -if [ "$PGBR_BRANCH" == "local" ] && [ -e /pgbackrest ]; then - echo "Build local pgbackrest environment" - ln -s /pgbackrest /build/pgbackrest -else - yum install --nogpgcheck --quiet -y -e 0 git - echo "Branch to clone is : $PGBR_BRANCH" - git clone --single-branch --branch $PGBR_BRANCH https://github.com/pgbackrest/pgbackrest.git /build/pgbackrest -fi - -export CPPFLAGS="-I $EDB_PATH/include" -export PATH=$EDB_PATH/bin/:$PATH -export LDFLAGS="-L$EDB_PATH/lib" -cd /build/pgbackrest/src && ./configure -make -s -C /build/pgbackrest/src -MAKE_VERSION=`/build/pgbackrest/src/pgbackrest version | sed -e s/pgBackRest\ //` -echo "pgBackRest $PGBR_BRANCH version is : $MAKE_VERSION" -mv /build/pgbackrest/src/pgbackrest $EDB_PATH/bin/pgbackrest -alternatives --install /usr/bin/pgbackrest pgbackrest $EDB_PATH/bin/pgbackrest `echo $MAKE_VERSION | tr -d . | tr -d dev` \ No newline at end of file diff --git a/tests/centos7/provision/PGDG/pgbackrest_build.bash b/tests/centos7/provision/PGDG/pgbackrest_build.bash deleted file mode 100755 index 6e027bc..0000000 --- a/tests/centos7/provision/PGDG/pgbackrest_build.bash +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGBR_BRANCH="$1" - -if [ -e /usr/bin/pgbackrest ]; then - rm -f /usr/bin/pgbackrest -fi - -yum install --nogpgcheck --quiet -y -e 0 make gcc openssl-devel libxml2-devel lz4-devel libzstd-devel bzip2-devel libyaml-devel -yum install --nogpgcheck --quiet -y -e 0 postgresql-devel - -if [ ! -d /build ]; then - mkdir /build -else - rm -rf /build/pgbackrest -fi - -if [ "$PGBR_BRANCH" == "local" ] && [ -e /pgbackrest ]; then - echo "Build local pgbackrest environment" - ln -s /pgbackrest /build/pgbackrest -else - yum install --nogpgcheck --quiet -y -e 0 git - echo "Branch to clone is : $PGBR_BRANCH" - git clone --single-branch --branch $PGBR_BRANCH https://github.com/pgbackrest/pgbackrest.git /build/pgbackrest -fi - -cd /build/pgbackrest/src && ./configure -make -s -C /build/pgbackrest/src -MAKE_VERSION=`/build/pgbackrest/src/pgbackrest version | sed -e s/pgBackRest\ //` -echo "pgBackRest $PGBR_BRANCH version is : $MAKE_VERSION" -mv /build/pgbackrest/src/pgbackrest /usr/bin/pgbackrest diff --git a/tests/centos7/provision/PGDG/pgsql.bash b/tests/centos7/provision/PGDG/pgsql.bash deleted file mode 100644 index a477a69..0000000 --- a/tests/centos7/provision/PGDG/pgsql.bash +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" - -# install required packages -yum install --nogpgcheck --quiet -y -e 0 "https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm" - -if [ $PGVER -ge "14" ]; then - yum-config-manager --enable pgdg$PGVER-updates-testing -fi - -PACKAGES=( - "postgresql${PGVER}" - "postgresql${PGVER}-server" - "postgresql${PGVER}-contrib" -) - -yum install --nogpgcheck --quiet -y -e 0 "${PACKAGES[@]}" - -# install pgBackRest -yum install --nogpgcheck --quiet -y -e 0 pgbackrest - -# firewall setup -firewall-cmd --quiet --permanent --add-service=postgresql -firewall-cmd --quiet --reload - -# init instance -systemctl stop "postgresql-${PGVER}" -systemctl disable "postgresql-${PGVER}" -rm -rf "${PGDATA}" -export PGSETUP_INITDB_OPTIONS="-E UTF-8 --data-checksums" -"/usr/pgsql-${PGVER}/bin/postgresql-${PGVER}-setup" initdb - -# pg_hba setup -cat< "${PGDATA}/pg_hba.conf" -local all all trust -host all all 0.0.0.0/0 trust -host all all ::/0 trust -local replication all trust -host replication all 0.0.0.0/0 trust -host replication all ::/0 trust -EOC - -systemctl enable "postgresql-${PGVER}" -systemctl start "postgresql-${PGVER}" - -# postgresql.conf setup -cat <<'EOS' | "/usr/pgsql-${PGVER}/bin/psql" -U ${PGUSER} -ALTER SYSTEM SET "listen_addresses" TO '*'; -ALTER SYSTEM SET "wal_level" TO 'replica'; -ALTER SYSTEM SET "archive_mode" TO 'on'; -ALTER SYSTEM SET "archive_command" TO '/bin/true'; -EOS - -# restart pgsql server -systemctl restart "postgresql-${PGVER}" -echo "pathmunge /usr/pgsql-${PGVER}/bin" > /etc/profile.d/pgsql${PGVER}.sh -chmod +x /etc/profile.d/pgsql${PGVER}.sh - -# force proper permissions on .ssh files -cp -rf /root/.ssh /var/lib/pgsql/.ssh -chown -R ${PGUSER}: /var/lib/pgsql/.ssh -restorecon -R /var/lib/pgsql/.ssh -usermod -aG ${PGUSER} accessed_by_ssh \ No newline at end of file diff --git a/tests/centos7/provision/azurite.bash b/tests/centos7/provision/azurite.bash deleted file mode 100644 index 073288f..0000000 --- a/tests/centos7/provision/azurite.bash +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -# global config -CERTS_PATH="/opt/azurite/certs" -HOST_AZURE="127.0.0.1" -HOST_AZURE_ACCOUNT="pgbackrest" -HOST_AZURE_KEY="YXpLZXk=" -HOST_AZURE_CONTAINER="pgbackrest-container" - -# generate certs -mkdir -p -m 755 $CERTS_PATH -cd /opt/azurite/certs -openssl genrsa -out ca.key 2048 -openssl req -new -x509 -extensions v3_ca -key ca.key -out ca.crt -days 99999 -subj "/C=BE/ST=Country/L=City/O=Organization/CN=check_pgbackrest" -openssl genrsa -out server.key 2048 -openssl req -new -key server.key -out server.csr -subj "/C=BE/ST=Country/L=City/O=Organization/CN=check_pgbackrest" -openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 99999 -sha256 -cp /opt/azurite/certs/server.crt /opt/azurite/certs/public.crt -cp /opt/azurite/certs/server.key /opt/azurite/certs/private.key -chmod 644 /opt/azurite/certs/* -firewall-cmd --quiet --permanent --add-service=https -firewall-cmd --quiet --reload - -# run azurite -mkdir -p -m 755 /opt/azurite/data -yum install --nogpgcheck --quiet -y -e 0 docker -systemctl start docker -docker run --privileged -d -p 443:443 \ --v /opt/azurite/data:/workspace \ --v $CERTS_PATH/public.crt:/root/public.crt:ro \ --v $CERTS_PATH/private.key:/root/private.key:ro \ --e AZURITE_ACCOUNTS="$HOST_AZURE_ACCOUNT:$HOST_AZURE_KEY" \ -mcr.microsoft.com/azure-storage/azurite \ -azurite-blob --blobPort 443 --blobHost 0.0.0.0 --cert=/root/public.crt --key=/root/private.key -l /workspace -d /workspace/debug.log - -# create pgbackrest repo -cat< /etc/pgbackrest.conf -[global] -repo1-type=azure -repo1-azure-host=$HOST_AZURE -repo1-azure-verify-tls=n -repo1-azure-account=$HOST_AZURE_ACCOUNT -repo1-azure-key=$HOST_AZURE_KEY -repo1-azure-container=$HOST_AZURE_CONTAINER -repo1-path=/repo1 -EOC - -sudo -iu postgres pgbackrest repo-create - -# Tips: -# Stop all running containers: docker stop $(docker ps -a -q) -# Delete all stopped containers: docker rm $(docker ps -a -q) \ No newline at end of file diff --git a/tests/centos7/provision/check_pgbackrest.bash b/tests/centos7/provision/check_pgbackrest.bash deleted file mode 100644 index 5879597..0000000 --- a/tests/centos7/provision/check_pgbackrest.bash +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PLUGIN_PATH=/usr/lib64/nagios/plugins - -yum install --nogpgcheck --quiet -y -e 0 epel-release - -PACKAGES=( - nagios-plugins - nagios-plugins-all - perl-JSON - perl-Data-Dumper - wget - perl-Devel-NYTProf - perl-JSON-MaybeXS -) - -yum install --nogpgcheck --quiet -y -e 0 "${PACKAGES[@]}" -cp /check_pgbackrest/check_pgbackrest $PLUGIN_PATH -chmod 755 $PLUGIN_PATH/check_pgbackrest -echo "export PATH=\$PATH:/usr/lib64/nagios/plugins" >> /etc/profile - -# set timezone -ln -sf /usr/share/zoneinfo/Europe/Brussels /etc/localtime - -# firewall setup -systemctl enable firewalld -systemctl start firewalld - -# force proper permissions on .ssh files -chmod -R 0600 /root/.ssh -chmod 0700 /root/.ssh -restorecon -R /root/.ssh - -# create user to be accessed by ssh -adduser accessed_by_ssh -usermod -aG wheel accessed_by_ssh -echo "accessed_by_ssh ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers -cp -rf /root/.ssh /home/accessed_by_ssh/.ssh -chown -R accessed_by_ssh: /home/accessed_by_ssh/.ssh -restorecon -R /home/accessed_by_ssh/.ssh \ No newline at end of file diff --git a/tests/centos7/provision/cifs.bash b/tests/centos7/provision/cifs.bash deleted file mode 100644 index 508aad0..0000000 --- a/tests/centos7/provision/cifs.bash +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - - -PACKAGES=( - samba - samba-client - policycoreutils-python -) - -yum install --nogpgcheck --quiet -y -e 0 "${PACKAGES[@]}" -setsebool -P samba_export_all_ro on -setsebool -P samba_export_all_rw on -setsebool -P samba_share_nfs on - -mkdir -p /samba/export_rw/pgbackrest -useradd samba_user1 -chown -R samba_user1:samba_user1 /samba/export_rw -semanage fcontext -at samba_share_t "/samba/export_rw(/.*)?" -restorecon -R /samba/export_rw - -firewall-cmd --permanent --add-service=samba -systemctl restart firewalld - -cat<> "/etc/samba/smb.conf" -[bckp_storage] - comment = Folder for storing backups - read only = no - available = yes - path = /samba/export_rw - public = yes - valid users = samba_user1 - write list = samba_user1 - writable = yes - browseable = yes -EOF - -echo 'samba' | tee - | smbpasswd -s -a samba_user1 - -systemctl enable smb -systemctl start smb \ No newline at end of file diff --git a/tests/centos7/provision/gcs.bash b/tests/centos7/provision/gcs.bash deleted file mode 100644 index e4b34a8..0000000 --- a/tests/centos7/provision/gcs.bash +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -# global config -HOST_GCS="127.0.0.1" -HOST_GCS_BUCKET="pgbackrest" -HOST_GCS_KEY="my-token" - -# firewall -firewall-cmd --quiet --permanent --add-service=https -firewall-cmd --quiet --reload - -# run fake gcs server -yum install --nogpgcheck --quiet -y -e 0 docker -systemctl start docker -docker run -d -p 443:4443 fsouza/fake-gcs-server - -# create pgbackrest repo -cat< /etc/pgbackrest.conf -[global] -repo1-type=gcs -repo1-storage-verify-tls=n -repo1-gcs-endpoint=$HOST_GCS -repo1-gcs-bucket=$HOST_GCS_BUCKET -repo1-gcs-key-type=token -repo1-gcs-key=$HOST_GCS_KEY -EOC - -pgbackrest --log-level-console=info repo-create - -# Tips: -# Stop all running containers: docker stop $(docker ps -a -q) -# Delete all stopped containers: docker rm $(docker ps -a -q) \ No newline at end of file diff --git a/tests/centos7/provision/icinga2.bash b/tests/centos7/provision/icinga2.bash deleted file mode 100644 index 11cf8d7..0000000 --- a/tests/centos7/provision/icinga2.bash +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -yum install --nogpgcheck --quiet -y -e 0 https://packages.icinga.com/epel/icinga-rpm-release-7-latest.noarch.rpm - -PACKAGES=( - icinga2 - icinga2-selinux - icinga2-ido-pgsql -) - -yum install --nogpgcheck --quiet -y -e 0 "${PACKAGES[@]}" - -systemctl enable icinga2 -systemctl start icinga2 - -# link icinga2 - postgresql -sudo -iu postgres psql -c "CREATE ROLE icinga WITH LOGIN;" -sudo -iu postgres createdb -O icinga -E UTF8 icinga -psql -U icinga -d icinga -c "select version();" -psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/pgsql.sql -icinga2 feature enable ido-pgsql -icinga2 feature enable debuglog - -# setup api for icingaweb2 -icinga2 api setup -cat <>/etc/icinga2/conf.d/api-users.conf -object ApiUser "icingaweb2" { - password = "Wijsn8Z9eRs5E25d" - permissions = [ "*" ] -} -EOF -systemctl restart icinga2 - -# setup httpd for icingaweb2 -yum install --nogpgcheck --quiet -y -e 0 httpd -systemctl enable httpd -systemctl start httpd -firewall-cmd --add-service=http -firewall-cmd --permanent --add-service=http -touch /var/www/html/index.html -chmod 755 /var/www/html/index.html - -# install icingaweb2 -yum install --nogpgcheck --quiet -y -e 0 centos-release-scl -yum install --nogpgcheck --quiet -y -e 0 icingaweb2 icingacli icingaweb2-selinux php-pecl-imagick -echo "date.timezone = Europe/Brussels">> /etc/opt/rh/rh-php73/php.ini -systemctl start rh-php73-php-fpm.service -systemctl enable rh-php73-php-fpm.service -sudo -iu postgres psql -c "CREATE ROLE icingaweb WITH LOGIN;" -sudo -iu postgres createdb -O icingaweb -E UTF8 icingaweb -psql -U icingaweb -d icingaweb < /usr/share/doc/icingaweb2/schema/pgsql.schema.sql -systemctl restart httpd - -# configure icingaweb2 -cat <>/etc/icingaweb2/authentication.ini -[icingaweb2] -backend = "db" -resource = "icingaweb_db" -EOF - -cat <>/etc/icingaweb2/config.ini -[global] -show_stacktraces = "1" -show_application_state_messages = "1" -config_backend = "db" -config_resource = "icingaweb_db" - -[logging] -log = "syslog" -level = "ERROR" -application = "icingaweb2" -facility = "user" -EOF - -cat <>/etc/icingaweb2/groups.ini -[icingaweb2] -backend = "db" -resource = "icingaweb_db" -EOF - -cat <>/etc/icingaweb2/resources.ini -[icingaweb_db] -type = "db" -db = "pgsql" -host = "/var/run/postgresql" -port = "5432" -dbname = "icingaweb" -username = "icingaweb" -password = "icingaweb" -charset = "" -use_ssl = "0" - -[icinga_ido] -type = "db" -db = "pgsql" -host = "/var/run/postgresql" -port = "5432" -dbname = "icinga" -username = "icinga" -password = "icinga" -charset = "" -use_ssl = "0" -EOF - -cat <>/etc/icingaweb2/roles.ini -[Administrators] -users = "icingaweb" -permissions = "*" -groups = "Administrators" -EOF - -if [ ! -d /etc/icingaweb2/modules/monitoring ]; then - mkdir /etc/icingaweb2/modules/monitoring -fi - -cat <>/etc/icingaweb2/modules/monitoring/config.ini -[security] -protected_customvars = "*pw*,*pass*,community" -EOF - -cat <>/etc/icingaweb2/modules/monitoring/backends.ini -[icinga] -type = "ido" -resource = "icinga_ido" -EOF - -cat <>/etc/icingaweb2/modules/monitoring/commandtransports.ini -[icinga2] -transport = "api" -host = "localhost" -port = "5665" -username = "icingaweb2" -password = "Wijsn8Z9eRs5E25d" -EOF - -chown -R apache:icingaweb2 /etc/icingaweb2 -icingacli module enable monitoring -psql -U icingaweb -d icingaweb -c "INSERT INTO public.icingaweb_group (name, ctime) VALUES ('Administrators', now());" -psql -U icingaweb -d icingaweb -c $'INSERT INTO icingaweb_user (name, active, password_hash) VALUES (\'icingaweb\', 1, \'$2y$10$lZil3NzXm.XC55NB4fxb8e4oMIJKh8Awa6BSjf9ka2bH4yCHgukTu\');' - -# add pgsql-srv host -cat <>/etc/icinga2/conf.d/hosts.conf - -object Host "pgsql-srv" { - import "generic-host" - address = "pgsql-srv" - vars.os= "Linux" -} - -object Host "backup-srv" { - import "generic-host" - address = "backup-srv" - vars.os= "Linux" -} -EOF - -systemctl restart icinga2 - -# ssh configuration -cp -rf /root/.ssh /var/spool/icinga2/.ssh -chown -R icinga: /var/spool/icinga2/.ssh -restorecon -R /var/spool/icinga2/.ssh - -# show -icingacli monitoring list services \ No newline at end of file diff --git a/tests/centos7/provision/icinga2_multi.bash b/tests/centos7/provision/icinga2_multi.bash deleted file mode 100644 index a12645d..0000000 --- a/tests/centos7/provision/icinga2_multi.bash +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGUSER="$1" - -# add check_pgbackrest tests -cat <>/etc/icinga2/conf.d/hosts.conf - -/* retention service should work on both primary and standby */ -object CheckCommand "by_ssh_pgbackrest_retention" { - import "by_ssh" - vars.by_ssh_command = "/usr/lib64/nagios/plugins/check_pgbackrest --stanza=\$stanza$ --service=retention --retention-full=\$retention_full$ --prefix=\"\$prefix$\"" -} - -object Service "pgbackrest_retention" { - import "generic-service" - host_name = "pgsql-srv" - check_command = "by_ssh_pgbackrest_retention" - vars.by_ssh_logname = "accessed_by_ssh" - - vars.stanza = "my_stanza" - vars.retention_full = 1 - vars.prefix = "sudo -u $PGUSER" -} - -object Service "pgbackrest_retention" { - import "generic-service" - host_name = "backup-srv" - check_command = "by_ssh_pgbackrest_retention" - vars.by_ssh_logname = "accessed_by_ssh" - - vars.stanza = "my_stanza" - vars.retention_full = 1 - vars.prefix = "sudo -u $PGUSER" -} - -/* archives service should work on both primary and standby */ -object CheckCommand "by_ssh_pgbackrest_archives" { - import "by_ssh" - vars.by_ssh_command = "/usr/lib64/nagios/plugins/check_pgbackrest --stanza=\$stanza$ --service=archives --prefix=\"\$prefix$\"" -} - -object Service "pgbackrest_archives" { - import "generic-service" - host_name = "pgsql-srv" - check_command = "by_ssh_pgbackrest_archives" - vars.by_ssh_logname = "accessed_by_ssh" - - vars.stanza = "my_stanza" - vars.prefix = "sudo -u $PGUSER" -} - -object Service "pgbackrest_archives" { - import "generic-service" - host_name = "backup-srv" - check_command = "by_ssh_pgbackrest_archives" - vars.by_ssh_logname = "accessed_by_ssh" - - vars.stanza = "my_stanza" - vars.prefix = "sudo -u $PGUSER" -} -EOF - -systemctl restart icinga2 - -# show -icingacli monitoring list services --service=pgbackrest* --verbose \ No newline at end of file diff --git a/tests/centos7/provision/minio.bash b/tests/centos7/provision/minio.bash deleted file mode 100644 index ade6f81..0000000 --- a/tests/centos7/provision/minio.bash +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -# install MinIO -# based on https://www.centosblog.com/install-configure-minio-object-storage-server-centos-linux/ -useradd -s /sbin/nologin -d /opt/minio minio -mkdir -p /opt/minio/bin -mkdir /opt/minio/data - -# download ~40MB, this step will take some time... -echo "--wget minio: download ~40MB, this step will take some time..." -wget --quiet https://dl.min.io/server/minio/release/linux-amd64/minio -O /opt/minio/bin/minio -chmod +x /opt/minio/bin/minio - -# generate self-signed certificates -mkdir -p -m 755 /opt/minio/certs -cd /opt/minio/certs -openssl genrsa -out ca.key 2048 -openssl req -new -x509 -extensions v3_ca -key ca.key -out ca.crt -days 99999 -subj "/C=BE/ST=Country/L=City/O=Organization/CN=check_pgbackrest" -openssl genrsa -out server.key 2048 -openssl req -new -key server.key -out server.csr -subj "/C=BE/ST=Country/L=City/O=Organization/CN=check_pgbackrest" -openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 99999 -sha256 -cp /opt/minio/certs/server.crt /opt/minio/certs/public.crt -cp /opt/minio/certs/server.key /opt/minio/certs/private.key -chmod 644 /opt/minio/certs/* - -# basic configuration -cat<"/opt/minio/minio.conf" -MINIO_VOLUMES=/opt/minio/data -MINIO_DOMAIN=minio.local -MINIO_OPTS="--certs-dir /opt/minio/certs --address :443 --compat" -MINIO_ACCESS_KEY="accessKey" -MINIO_SECRET_KEY="superSECRETkey" -EOF - -cat<>"/etc/hosts" -127.0.0.1 pgbackrest.minio.local minio.local s3.eu-west-3.amazonaws.com -EOF - -chown -R minio:minio /opt/minio - -# systemd service -cat<"/etc/systemd/system/minio.service" -[Unit] -Description=Minio -Documentation=https://docs.minio.io -Wants=network-online.target -After=network-online.target -AssertFileIsExecutable=/opt/minio/bin/minio - -[Service] -AmbientCapabilities=CAP_NET_BIND_SERVICE -WorkingDirectory=/opt/minio - -User=minio -Group=minio - -PermissionsStartOnly=true - -EnvironmentFile=-/opt/minio/minio.conf -ExecStartPre=/bin/bash -c "[ -n \\"\${MINIO_VOLUMES}\\" ] || echo \\"Variable MINIO_VOLUMES not set in /opt/minio/minio.conf\\"" - -ExecStart=/opt/minio/bin/minio server \$MINIO_OPTS \$MINIO_VOLUMES - -StandardOutput=journal -StandardError=inherit - -# Specifies the maximum file descriptor number that can be opened by this process -LimitNOFILE=65536 - -# Disable timeout logic and wait until process is stopped -TimeoutStopSec=0 - -# SIGTERM signal is used to stop Minio -KillSignal=SIGTERM - -SendSIGKILL=no - -SuccessExitStatus=0 - -[Install] -WantedBy=multi-user.target -EOF - -firewall-cmd --quiet --permanent --add-service=https -firewall-cmd --quiet --reload -systemctl enable minio -systemctl start minio -sleep 5 -systemctl restart minio -sleep 5 -systemctl status minio - -# install s3cmd -yum --enablerepo epel-testing install --nogpgcheck --quiet -y -e 0 s3cmd - -cat< ~/.s3cfg -host_base = minio.local -host_bucket = pgbackrest.minio.local -bucket_location = eu-west-3 -use_https = true -access_key = accessKey -secret_key = superSECRETkey -EOF - -# create "pgbackrest" bucket and sub-directory "repo1" -s3cmd mb --no-check-certificate s3://pgbackrest -mkdir /opt/minio/data/pgbackrest/repo1 -chown minio: /opt/minio/data/pgbackrest/repo1 -s3cmd ls --no-check-certificate s3://pgbackrest/repo1 \ No newline at end of file diff --git a/tests/centos7/provision/minio_http.bash b/tests/centos7/provision/minio_http.bash deleted file mode 100644 index b86f95d..0000000 --- a/tests/centos7/provision/minio_http.bash +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -# create an HTTP setup -cat<"/opt/minio/minio-http.conf" -MINIO_VOLUMES=/opt/minio/data -MINIO_DOMAIN=minio.local -MINIO_OPTS="--address :80 --compat" -MINIO_ACCESS_KEY="accessKey" -MINIO_SECRET_KEY="superSECRETkey" -EOF - -chown minio:minio "/opt/minio/minio-http.conf" - -# systemd service -cat<"/etc/systemd/system/minio-http.service" -[Unit] -Description=Minio -Documentation=https://docs.minio.io -Wants=network-online.target -After=network-online.target -AssertFileIsExecutable=/opt/minio/bin/minio - -[Service] -AmbientCapabilities=CAP_NET_BIND_SERVICE -WorkingDirectory=/opt/minio - -User=minio -Group=minio - -PermissionsStartOnly=true - -EnvironmentFile=-/opt/minio/minio-http.conf -ExecStartPre=/bin/bash -c "[ -n \\"\${MINIO_VOLUMES}\\" ] || echo \\"Variable MINIO_VOLUMES not set in /opt/minio/minio.conf\\"" - -ExecStart=/opt/minio/bin/minio server \$MINIO_OPTS \$MINIO_VOLUMES - -StandardOutput=journal -StandardError=inherit - -# Specifies the maximum file descriptor number that can be opened by this process -LimitNOFILE=65536 - -# Disable timeout logic and wait until process is stopped -TimeoutStopSec=0 - -# SIGTERM signal is used to stop Minio -KillSignal=SIGTERM - -SendSIGKILL=no - -SuccessExitStatus=0 - -[Install] -WantedBy=multi-user.target -EOF - -firewall-cmd --permanent --add-service=http -firewall-cmd --quiet --reload -systemctl enable minio-http -systemctl start minio-http -sleep 5 -systemctl status minio-http \ No newline at end of file diff --git a/tests/centos7/provision/perl_build.bash b/tests/centos7/provision/perl_build.bash deleted file mode 100755 index 9367ead..0000000 --- a/tests/centos7/provision/perl_build.bash +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -cd "$(dirname "$0")" -PERL_VERSION="perl-5.30.1" - -if [ ! -d /$PERL_VERSION ]; then - yum install -y gcc - wget https://www.cpan.org/src/5.0/$PERL_VERSION.tar.gz --directory-prefix=/tmp - tar -xzf /tmp/$PERL_VERSION.tar.gz --directory=/tmp - cd /tmp/$PERL_VERSION - ./Configure -des -Dprefix=/$PERL_VERSION - make -j 4 - make -j 4 test - make -j 4 install - echo "export PATH=/$PERL_VERSION/bin:\$PATH" >> /etc/profile - source /etc/profile - export PERL_MM_USE_DEFAULT=1 - /$PERL_VERSION/bin/cpan -i "JSON" - /$PERL_VERSION/bin/cpan -i "Net::SFTP::Foreign" - /$PERL_VERSION/bin/cpan -i "Data::Dumper" - /$PERL_VERSION/bin/cpan -i "Config::IniFiles" - - # /$PERL_VERSION/bin/cpan -i "Time::Zone" - # /$PERL_VERSION/bin/cpan -i "DateTime::Format::HTTP" - # /$PERL_VERSION/bin/cpan -i "Digest::MD5::File" - # /$PERL_VERSION/bin/cpan -i "HTTP::Date" - # /$PERL_VERSION/bin/cpan -i "HTTP::Response" - # /$PERL_VERSION/bin/cpan -i "HTTP::Status" - # /$PERL_VERSION/bin/cpan -i "LWP" - # /$PERL_VERSION/bin/cpan -i "LWP::Simple" - # /$PERL_VERSION/bin/cpan -i "LWP::UserAgent::Determined" - # /$PERL_VERSION/bin/cpan -i "MooseX::Types::DateTime::MoreCoercions" - # /$PERL_VERSION/bin/cpan -i "Test::LoadAllModules" - - # /$PERL_VERSION/bin/cpan -i "Net::Amazon::S3" -else - echo "$PERL_VERSION already installed" -fi \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_azurite_primary.bash b/tests/centos7/provision/pgbackrest_azurite_primary.bash deleted file mode 100644 index a721e06..0000000 --- a/tests/centos7/provision/pgbackrest_azurite_primary.bash +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -ENCRYPTED="$5" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -HOST_AZURE="backup-srv" -HOST_AZURE_ACCOUNT="pgbackrest" -HOST_AZURE_KEY="YXpLZXk=" -HOST_AZURE_CONTAINER="pgbackrest-container" - -cat< "/etc/pgbackrest.conf" -[global] -repo1-type=azure -repo1-azure-host=$HOST_AZURE -repo1-azure-verify-tls=n -repo1-azure-account=$HOST_AZURE_ACCOUNT -repo1-azure-key=$HOST_AZURE_KEY -repo1-azure-container=$HOST_AZURE_CONTAINER -repo1-path=/repo1 -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -$CIPHER - -[my_stanza] -pg1-path=${PGDATA} -pg1-user=${PGUSER} -pg1-port=${PGPORT} -EOC - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza stanza-create - -# archive_command setup -cat <<'EOS' | "/usr/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p'; -SELECT pg_reload_conf(); -EOS - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza check -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_azurite_standby.bash b/tests/centos7/provision/pgbackrest_azurite_standby.bash deleted file mode 100644 index 11dedcd..0000000 --- a/tests/centos7/provision/pgbackrest_azurite_standby.bash +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -PGSVC="$5" -ENCRYPTED="$6" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -HOST_AZURE="127.0.0.1" -HOST_AZURE_ACCOUNT="pgbackrest" -HOST_AZURE_KEY="YXpLZXk=" -HOST_AZURE_CONTAINER="pgbackrest-container" - -cat< "/etc/pgbackrest.conf" -[global] -repo1-type=azure -repo1-azure-host=$HOST_AZURE -repo1-azure-verify-tls=n -repo1-azure-account=$HOST_AZURE_ACCOUNT -repo1-azure-key=$HOST_AZURE_KEY -repo1-azure-container=$HOST_AZURE_CONTAINER -repo1-path=/repo1 -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -backup-standby=y -$CIPHER - -[my_stanza] -pg1-host=pgsql-srv -pg1-host-user=${PGUSER} -pg1-path=${PGDATA} -pg2-path=${PGDATA} -pg2-user=${PGUSER} -pg2-port=${PGPORT} -recovery-option=primary_conninfo=host=pgsql-srv user=${PGUSER} port=${PGPORT} -EOC - -# build streaming replication -systemctl stop ${PGSVC} -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=standby --target-timeline=latest --reset-pg1-host restore -systemctl start ${PGSVC} - -# test the backup-standby option -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=incr backup -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_gcs_primary.bash b/tests/centos7/provision/pgbackrest_gcs_primary.bash deleted file mode 100644 index 6599174..0000000 --- a/tests/centos7/provision/pgbackrest_gcs_primary.bash +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -ENCRYPTED="$5" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -HOST_GCS="backup-srv" -HOST_GCS_BUCKET="pgbackrest" -HOST_GCS_KEY="my-token" - -cat< "/etc/pgbackrest.conf" -[global] -repo1-type=gcs -repo1-storage-verify-tls=n -repo1-gcs-endpoint=$HOST_GCS -repo1-gcs-bucket=$HOST_GCS_BUCKET -repo1-gcs-key-type=token -repo1-gcs-key=$HOST_GCS_KEY -repo1-path=/repo1 -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -$CIPHER - -[my_stanza] -pg1-path=${PGDATA} -pg1-user=${PGUSER} -pg1-port=${PGPORT} -EOC - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza stanza-create - -# archive_command setup -cat <<'EOS' | "/usr/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p'; -SELECT pg_reload_conf(); -EOS - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza check -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_gcs_standby.bash b/tests/centos7/provision/pgbackrest_gcs_standby.bash deleted file mode 100644 index 784f672..0000000 --- a/tests/centos7/provision/pgbackrest_gcs_standby.bash +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -PGSVC="$5" -ENCRYPTED="$6" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -HOST_GCS="127.0.0.1" -HOST_GCS_BUCKET="pgbackrest" -HOST_GCS_KEY="my-token" - -cat< "/etc/pgbackrest.conf" -[global] -repo1-type=gcs -repo1-storage-verify-tls=n -repo1-gcs-endpoint=$HOST_GCS -repo1-gcs-bucket=$HOST_GCS_BUCKET -repo1-gcs-key-type=token -repo1-gcs-key=$HOST_GCS_KEY -repo1-path=/repo1 -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -backup-standby=y -$CIPHER - -[my_stanza] -pg1-host=pgsql-srv -pg1-host-user=${PGUSER} -pg1-path=${PGDATA} -pg2-path=${PGDATA} -pg2-user=${PGUSER} -pg2-port=${PGPORT} -recovery-option=primary_conninfo=host=pgsql-srv user=${PGUSER} port=${PGPORT} -EOC - -# build streaming replication -systemctl stop ${PGSVC} -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=standby --target-timeline=latest --reset-pg1-host restore -systemctl start ${PGSVC} - -# test the backup-standby option -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=incr backup -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_local_primary.bash b/tests/centos7/provision/pgbackrest_local_primary.bash deleted file mode 100644 index f6bbd63..0000000 --- a/tests/centos7/provision/pgbackrest_local_primary.bash +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -ENCRYPTED="$5" - -PACKAGES=( - samba - samba-client - cifs-utils -) - -yum install --nogpgcheck --quiet -y -e 0 "${PACKAGES[@]}" - -# cifs mount -groupadd --gid 2000 sambagroup -usermod -aG sambagroup ${PGUSER} - -cat<>"/etc/fstab" -//backup-srv/bckp_storage/pgbackrest /var/lib/pgbackrest cifs username=samba_user1,password=samba,uid=${PGUSER},gid=${PGUSER},dir_mode=0750,file_mode=0740 0 0 -EOF - -chmod 755 /var/lib/pgbackrest -mount /var/lib/pgbackrest - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -cat< "/etc/pgbackrest.conf" -[global] -repo1-type=cifs -repo1-path=/var/lib/pgbackrest -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -$CIPHER - -[my_stanza] -pg1-path=${PGDATA} -pg1-user=${PGUSER} -pg1-port=${PGPORT} -EOC - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza stanza-create - -# archive_command setup -cat <<'EOS' | "/usr/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p'; -SELECT pg_reload_conf(); -EOS - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza check -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_local_standby.bash b/tests/centos7/provision/pgbackrest_local_standby.bash deleted file mode 100644 index 81e7d4d..0000000 --- a/tests/centos7/provision/pgbackrest_local_standby.bash +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -PGSVC="$5" -ENCRYPTED="$6" - -cat<>"/etc/fstab" -//backup-srv/bckp_storage/pgbackrest /var/lib/pgbackrest cifs username=samba_user1,password=samba,uid=${PGUSER},gid=${PGUSER},dir_mode=0750,file_mode=0740 0 0 -EOF -mount /var/lib/pgbackrest - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -cat< "/etc/pgbackrest.conf" -[global] -repo1-type=cifs -repo1-path=/var/lib/pgbackrest -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -backup-standby=y -$CIPHER - -[my_stanza] -pg1-host=pgsql-srv -pg1-host-user=${PGUSER} -pg1-path=${PGDATA} -pg2-path=${PGDATA} -pg2-user=${PGUSER} -pg2-port=${PGPORT} -recovery-option=primary_conninfo=host=pgsql-srv user=${PGUSER} port=${PGPORT} -EOC - -# build streaming replication -systemctl stop ${PGSVC} -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=standby --target-timeline=latest --reset-pg1-host restore -systemctl start ${PGSVC} - -# test the backup-standby option -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=incr backup -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_minio_primary.bash b/tests/centos7/provision/pgbackrest_minio_primary.bash deleted file mode 100644 index 4e0dca1..0000000 --- a/tests/centos7/provision/pgbackrest_minio_primary.bash +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -ENCRYPTED="$5" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -cat< "/etc/pgbackrest.conf" -[global] -repo1-path=/repo1 -repo1-type=s3 -repo1-s3-endpoint=minio.local -repo1-s3-bucket=pgbackrest -repo1-s3-verify-tls=n -repo1-s3-key=accessKey -repo1-s3-key-secret=superSECRETkey -repo1-s3-region=eu-west-3 -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -$CIPHER - -[my_stanza] -pg1-path=${PGDATA} -pg1-user=${PGUSER} -pg1-port=${PGPORT} -EOC - -# setup DNS alias for backup-srv where minio is installed -MINIO_IP=`getent hosts backup-srv | awk '{ print $1 }'` -cat<>"/etc/hosts" -$MINIO_IP pgbackrest.minio.local minio.local s3.eu-west-3.amazonaws.com -EOF - -# create stanza -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza stanza-create - -# archive_command setup -cat <<'EOS' | "/usr/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p'; -SELECT pg_reload_conf(); -EOS - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza check -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_minio_standby.bash b/tests/centos7/provision/pgbackrest_minio_standby.bash deleted file mode 100644 index 6388445..0000000 --- a/tests/centos7/provision/pgbackrest_minio_standby.bash +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -PGSVC="$5" -ENCRYPTED="$6" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -HOST_AZURE="127.0.0.1" -HOST_AZURE_ACCOUNT="pgbackrest" -HOST_AZURE_KEY="YXpLZXk=" -HOST_AZURE_CONTAINER="pgbackrest-container" - -cat< "/etc/pgbackrest.conf" -[global] -repo1-path=/repo1 -repo1-type=s3 -repo1-s3-endpoint=minio.local -repo1-s3-bucket=pgbackrest -repo1-s3-verify-tls=n -repo1-s3-key=accessKey -repo1-s3-key-secret=superSECRETkey -repo1-s3-region=eu-west-3 -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -backup-standby=y -$CIPHER - -[my_stanza] -pg1-host=pgsql-srv -pg1-host-user=${PGUSER} -pg1-path=${PGDATA} -pg2-path=${PGDATA} -pg2-user=${PGUSER} -pg2-port=${PGPORT} -recovery-option=primary_conninfo=host=pgsql-srv user=${PGUSER} port=${PGPORT} -EOC - -# build streaming replication -systemctl stop ${PGSVC} -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=standby --target-timeline=latest --reset-pg1-host restore -systemctl start ${PGSVC} - -# test the backup-standby option -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=incr backup -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_remote_primary.bash b/tests/centos7/provision/pgbackrest_remote_primary.bash deleted file mode 100644 index 540d5ff..0000000 --- a/tests/centos7/provision/pgbackrest_remote_primary.bash +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -ENCRYPTED="$5" - -cat< "/etc/pgbackrest.conf" -[global] -repo1-host=backup-srv -repo1-host-user=${PGUSER} -process-max=2 -log-level-console=warn -log-level-file=info -delta=y - -[my_stanza] -pg1-path=${PGDATA} -pg1-user=${PGUSER} -pg1-port=${PGPORT} -EOC - -# archive_command setup -cat <<'EOS' | "/usr/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p'; -SELECT pg_reload_conf(); -EOS \ No newline at end of file diff --git a/tests/centos7/provision/pgbackrest_remote_standby.bash b/tests/centos7/provision/pgbackrest_remote_standby.bash deleted file mode 100644 index 700b171..0000000 --- a/tests/centos7/provision/pgbackrest_remote_standby.bash +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" -PGUSER="$3" -PGPORT="$4" -PGSVC="$5" -ENCRYPTED="$6" - -CIPHER= -# pgbackrest.conf setup -if [ $ENCRYPTED = "true" ]; then - CIPHER='repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd' -fi - -cat< "/etc/pgbackrest.conf" -[global] -repo1-path=/var/lib/pgbackrest -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -delta=y -start-fast=y -$CIPHER - -[my_stanza] -pg1-host=pgsql-srv -pg1-host-user=${PGUSER} -pg1-path=${PGDATA} -recovery-option=primary_conninfo=host=pgsql-srv user=${PGUSER} port=${PGPORT} -EOC - -# force proper permissions on repo1-path -chmod 755 /var/lib/pgbackrest - -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza stanza-create -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza check -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 - -# build streaming replication -systemctl stop ${PGSVC} -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --type=standby --target-timeline=latest --reset-pg1-host restore -systemctl start ${PGSVC} - -# test the backup-standby option -sudo -iu ${PGUSER} pgbackrest --stanza=my_stanza --backup-standby --pg2-path=${PGDATA} --pg2-user=${PGUSER} --pg2-port=${PGPORT} --type=incr backup \ No newline at end of file diff --git a/tests/centos7/vagrant.yml-dist b/tests/centos7/vagrant.yml-dist deleted file mode 100644 index 27abfc9..0000000 --- a/tests/centos7/vagrant.yml-dist +++ /dev/null @@ -1,6 +0,0 @@ -# pgver: "13" # PostgreSQL version to use -# pgbr_branch: "release/2.32" # pgBackRest git branch to use for builds -# vm_prefix: "check_pgbr_c7" # VM prefix -# encrypted_repo: "false" # Use aes-256-cbc cipher type to encrypt the pgBackRest repository -# edb_repository_username: "username" # EDB Repository Username -# edb_repository_password: "password" # EDB Repository Password diff --git a/tests/ci.sh b/tests/ci.sh new file mode 100644 index 0000000..51e9cf6 --- /dev/null +++ b/tests/ci.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +cd "$(dirname "$0")" + +perl config.pl --force --architecture "$ARCH" \ + --cluster-path "$CLPATH" --cluster-name "$CLNAME" \ + --db-type "$DBTYPE" --db-version "$DBVERSION" \ + --docker-image "$DOCKERI" --extra-vars "$EXTRA_VARS" +sed -i "s/pg1/$CLNAME-1/g" "$CLPATH/$CLNAME/config.yml" +sed -i "s/pg2/$CLNAME-2/g" "$CLPATH/$CLNAME/config.yml" +sed -i "s/pg3/$CLNAME-3/g" "$CLPATH/$CLNAME/config.yml" +sed -i "s/backup/$CLNAME-bck/g" "$CLPATH/$CLNAME/config.yml" +sh run.sh -c "$CLPATH/$CLNAME" "$RUN_ARGS" \ No newline at end of file diff --git a/tests/common/regress/expected/version.out b/tests/common/regress/expected/version.out deleted file mode 100644 index 32e4ef2..0000000 --- a/tests/common/regress/expected/version.out +++ /dev/null @@ -1 +0,0 @@ -check_pgbackrest version 2.1dev diff --git a/tests/common/regress/test-01.bash b/tests/common/regress/test-01.bash deleted file mode 100755 index 5bcdd67..0000000 --- a/tests/common/regress/test-01.bash +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env bash -cd "$(dirname "$0")" - -usage() { - echo "Usage:" - echo " -s Skip backups initialization step." - echo " -g Generate expected results." - echo " -P Change check_pgbackrest plugin path." - echo " -p Use local or remote profile." - echo " -h Display this help message." -} - -# vars -PLUGIN_PATH=/usr/lib64/nagios/plugins -RESULTS_DIR=/tmp/results -SKIP_INIT=false -GENERATE_EXPECTED=false -SPROFILE=local -PGUSER=postgres - -while getopts "sgP:p:h" o; do - case "${o}" in - s) - SKIP_INIT=true - ;; - g) - GENERATE_EXPECTED=true - ;; - P) - PLUGIN_PATH=${OPTARG} - ;; - p) - SPROFILE=${OPTARG} - ;; - h ) - usage - exit 0 - ;; - *) - usage 1>&2 - exit 1 - ;; - esac -done -shift $((OPTIND-1)) - -if [ -e "../configuration.profile" ]; then - echo "...Source generated configuration profile" - source ../configuration.profile -fi - -if [ "$SPROFILE" != "local" ] && [ "$SPROFILE" != "remote" ]; then - usage 1>&2 - exit 1 -fi - -echo "SKIP_INIT = $SKIP_INIT" -echo "PLUGIN_PATH = $PLUGIN_PATH" -echo "SPROFILE = $SPROFILE" -echo "PGUSER = $PGUSER" - -if $GENERATE_EXPECTED; then - RESULTS_DIR=expected -fi - -if [ ! -d $RESULTS_DIR ]; then - mkdir $RESULTS_DIR -fi - -## Tests -# Initiate backups (full, diff, incr) -if ! $SKIP_INIT; then - echo "...Initiate backups (full, diff, incr)" - if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 - sudo -iu $PGUSER pgbackrest --stanza=my_stanza backup --type=diff - sudo -iu $PGUSER pgbackrest --stanza=my_stanza backup --type=incr - else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1" - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza backup --type=diff" - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza backup --type=incr" - fi -fi - -# --list -echo "--list" -$PLUGIN_PATH/check_pgbackrest --list | tee $RESULTS_DIR/list.out - -# --version -echo "--version" -$PLUGIN_PATH/check_pgbackrest --version -$PLUGIN_PATH/check_pgbackrest --version | cut -f1 -d"," > $RESULTS_DIR/version.out - -# --service=retention --retention-full -echo "--service=retention --retention-full" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-full=1 --output=human -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-full=1 | cut -f1 -d"|" > $RESULTS_DIR/retention-full.out - -# --service=retention --retention-age -echo "--service=retention --retention-age" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-age=1h --output=human -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-age=1h | cut -f1 -d"|" > $RESULTS_DIR/retention-age.out - -# --service=retention --retention-age-to-full -echo "--service=retention --retention-age-to-full" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-age-to-full=1h --output=human -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-age-to-full=1h | cut -f1 -d"|" > $RESULTS_DIR/retention-age-to-full.out - -# --service=retention fail -echo "--service=retention fail" -sudo -iu $PGUSER psql -d postgres -c "SELECT pg_sleep(2);" > /dev/null 2>&1 -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-full=2 --retention-age=1s --retention-age-to-full=1s --output=human -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-full=2 --retention-age=1s --retention-age-to-full=1s | cut -f1 -d"|" > $RESULTS_DIR/retention-fail.out - -# --service=archives -echo "--service=archives" -sudo -iu $PGUSER psql -d postgres -c "SELECT pg_switch_xlog();" > /dev/null 2>&1 -sudo -iu $PGUSER psql -d postgres -c "SELECT pg_switch_wal();" > /dev/null 2>&1 -sudo -iu $PGUSER psql -d postgres -c "SELECT pg_sleep(1);" > /dev/null 2>&1 -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --output=human -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives | cut -f1 -d"-" > $RESULTS_DIR/archives-ok.out - -# --service=archives --ignore-archived-before -echo "--service=archives --ignore-archived-before" -sudo -iu $PGUSER psql -d postgres -c "SELECT pg_sleep(2);" > /dev/null 2>&1 -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --ignore-archived-before=1s > $RESULTS_DIR/archives-ignore-before.out - -# --service=archives --ignore-archived-after -echo "--service=archives --ignore-archived-after" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --ignore-archived-after=1h > $RESULTS_DIR/archives-ignore-after.out - -# --service=archives --latest-archive-age-alert -echo "--service=archives --latest-archive-age-alert" -sudo -iu $PGUSER psql -d postgres -c "SELECT pg_sleep(2);" > /dev/null 2>&1 -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --latest-archive-age-alert=1h | cut -f1 -d"-" > $RESULTS_DIR/archives-age-alert-ok.out -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --latest-archive-age-alert=1s --output=human -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --latest-archive-age-alert=1s | cut -f1 -d"-" > $RESULTS_DIR/archives-age-alert-ko.out - -## Results -diff -abB expected/ $RESULTS_DIR/ > /tmp/regression.diffs -if [ $(wc -l < /tmp/regression.diffs) -gt 0 ]; then - cat /tmp/regression.diffs -fi \ No newline at end of file diff --git a/tests/common/scripts/simulate-basic-activity.bash b/tests/common/scripts/simulate-basic-activity.bash deleted file mode 100755 index 28e3b13..0000000 --- a/tests/common/scripts/simulate-basic-activity.bash +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env bash -cd "$(dirname "$0")" - -usage() { - echo "Usage: `basename $0` [-s ] [-a ] [-p ]" 1>&2; - exit 1; -} - -while getopts "s:a:p:" o; do - case "${o}" in - s) - s=${OPTARG} - ;; - a) - a=${OPTARG} - ;; - p) - p=${OPTARG} - ;; - *) - usage - ;; - esac -done -shift $((OPTIND-1)) - -if [ -z "${s}" ] || [ -z "${a}" ]; then - usage -fi - -# vars -SCALE=${s} -ACTIVITY_TIME=${a} -SPROFILE=${p} -PGVER=13 -PGUSER=postgres -PGSVC="postgresql-$PGVER" - -if [ -e "../configuration.profile" ]; then - echo "--source generated configuration profile" - source ../configuration.profile -fi - -if [ "$SPROFILE" != "local" ] && [ "$SPROFILE" != "remote" ]; then - usage -fi - -echo "SCALE = $SCALE" -echo "ACTIVITY_TIME = $ACTIVITY_TIME seconds" -echo "SPROFILE = $SPROFILE" -echo "PGVER = $PGVER" -echo "PGUSER = $PGUSER" -echo "PGSVC = $PGSVC" - -# run -echo "--Create pgbench setup" -sudo -iu $PGUSER dropdb --if-exists bench -sudo -iu $PGUSER createdb bench -sudo -iu $PGUSER pgbench -i -s $SCALE --quiet --foreign-keys bench - -echo "--Take a full backup" -if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza --type=full backup -else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --type=full backup" -fi -sudo -iu $PGUSER pgbackrest --stanza=my_stanza info - -echo "--Simulate $ACTIVITY_TIME sec activity" -sudo -iu $PGUSER pgbench -T $ACTIVITY_TIME bench - -echo "--Take an incremental backup" -if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza --type=incr backup -else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --type=incr backup" -fi -sudo -iu $PGUSER pgbackrest --stanza=my_stanza info - -echo "--Simulate $ACTIVITY_TIME sec activity" -sudo -iu $PGUSER pgbench -T $ACTIVITY_TIME bench - -echo "--Take a full backup to test the purge action" -if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza --type=full backup -else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --type=full backup" -fi -sudo -iu $PGUSER pgbackrest --stanza=my_stanza info - -echo "--Simulate $ACTIVITY_TIME sec activity" -sudo -iu $PGUSER pgbench -T $ACTIVITY_TIME bench - -echo "--Create restore point RP1 and get latest pgbench history time" -sudo -iu $PGUSER psql -d postgres -c "select pg_create_restore_point('RP1');" -sudo -iu $PGUSER psql -d bench -c 'SELECT max(mtime) FROM pgbench_history;' - -echo "--Simulate $ACTIVITY_TIME sec activity and get latest pgbench history time" -sudo -iu $PGUSER pgbench -T $ACTIVITY_TIME bench -sudo -iu $PGUSER psql -d bench -c 'SELECT max(mtime) FROM pgbench_history;' - -echo "--Restore RP1 restore point and get latest pgbench history time" -systemctl stop $PGSVC -sudo -iu $PGUSER pgbackrest restore --stanza=my_stanza --delta --type=name --target=RP1 --target-action=promote -systemctl start $PGSVC -systemctl status $PGSVC - -echo "--Wait while pg_is_in_recovery" -while [ `sudo -iu $PGUSER psql -d postgres -c 'SELECT pg_is_in_recovery();' -A -t` = "t" ] -do - echo "wait..." - sleep 5 -done -sudo -iu $PGUSER psql -d bench -c 'SELECT max(mtime) FROM pgbench_history;' - -echo "--Resync standby server" -echo "----Take incremental backup" -if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza --type=incr backup -else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --type=incr backup" -fi - -echo "----Restore it on standby server" -ssh backup-srv "systemctl stop $PGSVC" -sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --reset-pg1-host --type=standby restore" -ssh backup-srv "systemctl start $PGSVC" - -echo "----Wait until standby is replicated" -while [ `sudo -iu $PGUSER psql -d postgres -At -c "SELECT count(*) FROM pg_stat_replication;"` -lt 1 ] -do - echo "wait..." - sleep 5 -done -sudo -iu $PGUSER psql -d postgres -x -c "SELECT * FROM pg_stat_replication;" - -echo "--Simulate $ACTIVITY_TIME sec activity to get archives on different time-lines" -sudo -iu $PGUSER pgbench -T $ACTIVITY_TIME bench -sudo -iu $PGUSER pgbackrest --stanza=my_stanza info \ No newline at end of file diff --git a/tests/common/scripts/simulate-extended-activity.bash b/tests/common/scripts/simulate-extended-activity.bash deleted file mode 100755 index c2d2ace..0000000 --- a/tests/common/scripts/simulate-extended-activity.bash +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env bash -cd "$(dirname "$0")" - -usage() { - echo "Usage: `basename $0` [-p ]" 1>&2; - exit 1; -} - -while getopts "p:" o; do - case "${o}" in - p) - p=${OPTARG} - ;; - *) - usage - ;; - esac -done -shift $((OPTIND-1)) - -# vars -SPROFILE=${p} -PGUSER=postgres -LOOP_NB=10 - -if [ -e "../configuration.profile" ]; then - echo "--source generated configuration profile" - source ../configuration.profile -fi - -if [ "$SPROFILE" != "local" ] && [ "$SPROFILE" != "remote" ]; then - usage -fi - -echo "SPROFILE = $SPROFILE" -echo "PGUSER = $PGUSER" -echo "LOOP_NB = $LOOP_NB" - -# run -echo "--Create test-checksums setup" -sudo -iu $PGUSER dropdb --if-exists test-checksums -sudo -iu $PGUSER createdb test-checksums -sudo -iu $PGUSER psql -d test-checksums -c "CREATE TABLE t1 (id int);INSERT INTO t1 VALUES (1);" - -echo "--Take a full backup" -if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza --type=full backup -else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --type=full backup" -fi -sudo -iu $PGUSER pgbackrest --stanza=my_stanza info - -echo "--Corrupt some data file" -yum install --nogpgcheck --quiet -y -e 0 vim-common -FILE_TO_EDIT=`sudo -iu $PGUSER psql -A -t -d test-checksums -c "SELECT current_setting('data_directory') || '/' || pg_relation_filepath('t1');"` -echo "33" |xxd > $FILE_TO_EDIT - -echo "--Take an incremental backup - checksum WARNING should be reported!" -if [ "$SPROFILE" = "local" ]; then - sudo -iu $PGUSER pgbackrest --stanza=my_stanza --type=incr backup -else - sudo -iu $PGUSER ssh backup-srv "pgbackrest --stanza=my_stanza --type=incr backup" -fi -sudo -iu $PGUSER pgbackrest --stanza=my_stanza info - -echo "--Setup asynchronous archiving" -# archive_command setup -cat <<'EOS' | "/usr/bin/psql" -U ${PGUSER} -d postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p --archive-async --archive-push-queue-max=100MB'; -SELECT pg_reload_conf(); -EOS - -echo "--Generate $LOOP_NB archives" -LOOPS=($(seq 1 1 $LOOP_NB)) -FIRST_VALUE=${LOOPS[0]} -LAST_VALUE=${LOOPS[-1]} -sudo -iu $PGUSER psql -d test-checksums -c "DROP TABLE t1; CREATE TABLE t1 (id int);" -for i in "${LOOPS[@]}" -do - echo "Run ... $i / $LOOP_NB" - sudo -iu $PGUSER psql -d test-checksums -c "INSERT INTO t1 VALUES (1);SELECT pg_switch_wal();" - sleep 1 -done \ No newline at end of file diff --git a/tests/common/ssh/authorized_keys b/tests/common/ssh/authorized_keys deleted file mode 100644 index f8f9ca5..0000000 --- a/tests/common/ssh/authorized_keys +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEr0Tu81hAelpQL5DWBNuRdoUtdRUD1dZohqe6+uROjqkvKT/QwqthNxVqCgbnles62ON2h+gjjGmYwAVwVxXVwj7UGM97BCUbTg6PiguxYzj5tM2nqM2NLTkxQXZgu1ZjftodKL+vnWCSPsUxmJQK2q/wSNMDHBWy2D2wU307EIVIexyf7fjto1KRV2eV4MKxbD0LO5rXVBkprULrjNqmkpVU6TkSvz8NBNYP9ZCEsDm+y5/WO51MEssl3fxp5Jnf4bNU7dRLxNKGShqx5F/SL5Ucj66QG840waPyP0Dvg7TvFjeKofwLRfgIg+zl98EE7eBkLX6mvoGBJ/0LnhZR root@localhost.localdomain diff --git a/tests/common/ssh/config b/tests/common/ssh/config deleted file mode 100644 index cf7772b..0000000 --- a/tests/common/ssh/config +++ /dev/null @@ -1,4 +0,0 @@ -Host * - CheckHostIP no - StrictHostKeyChecking no - diff --git a/tests/common/ssh/id_rsa b/tests/common/ssh/id_rsa deleted file mode 100644 index d8fa08f..0000000 --- a/tests/common/ssh/id_rsa +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAxK9E7vNYQHpaUC+Q1gTbkXaFLXUVA9XWaIanuvrkTo6pLyk/ -0MKrYTcVagoG55XrOtjjdofoI4xpmMAFcFcV1cI+1BjPewQlG04Oj4oLsWM4+bTN -p6jNjS05MUF2YLtWY37aHSi/r51gkj7FMZiUCtqv8EjTAxwVstg9sFN9OxCFSHsc -n+347aNSkVdnleDCsWw9Czua11QZKa1C64zappKVVOk5Er8/DQTWD/WQhLA5vsuf -1judTBLLJd38aeSZ3+GzVO3US8TShkoaseRf0i+VHI+ukBvONMGj8j9A74O07xY3 -iqH8C0X4CIPs5ffBBO3gZC1+pr6BgSf9C54WUQIDAQABAoIBADcFyUUHsqKnF+ji -xaP5y+sPuwYSgQSHp+mp8fZvBbusUUwuP/oI26Tgog7+KxxSZnIaBtg8AQcg2tGu -tlbNJgCczLLNFg4WBMN0vMIPHmJLnb7Ng9LpeEeMZTmQVKuO/QXskNwjcCyS3FdN -VCEhzBiVQS75UH7INpHHyMoxMRF6eiE1sL9SIgHMGTa5CubdJ3gPc7cHF5KqvFXR -9oncgBr2JnVZ7td7lZ+BiSq37hJahqNnEILxqVbOLI401zS0n9f1SiD8LAjzmlwY -fSeuSZICXtH5BrrYo2eDtq6t722DCPyKCNvzG6Bo0M2YX9EuozWsRWRIRgGmRMwk -n+izX7kCgYEA4lQQiyPidGfqrRZOf8bW89Z5K5ldAbP98+X6f5SxfPrADV7Gqb9i -g+a3Aybf2tIUQMfo7hbSvq1rGloI98jX1kDa37FF52bCdG7Rwi5F1dRit6/vIbkp -57OIhLT5/pUK9VdQ4a7mD1TRzb+in/JJg/52Q/XcXS+JgnqA25vvvUcCgYEA3nhQ -g4HeibCPBazS35mH4/NYG8VUcEkIW2C1omqrh1g8S8Jo/LiPoAvCBABVAe6yvxop -GP2uywJNf2rTIJbxY4TQ5l+8L4LMM0HLYYgt1s/5XijaLh2UScCn7kBOTkkffTfU -c68NcoOfLr9FXlsrQj4+Q3piv4eDGYWyjT2z+6cCgYAOzvFGKVLnyuTP7mW0do4Z -5i6Ha8FqGxzCmImLT29NfhqSxWC6Oot3leDjk+eRqa0pj+rtqRCg6TfYwYtUqw90 -NUoc2Lx6J38Rny6aRezL0Nmkqx46VqMnRdfo1u6Eebv90Xi5S3hCCIqxq5g4XuHw -gPW7/Joufq3Am8NSmyFUgQKBgGHVvWqn8UrSF4OiZjYpGaa4fHXyCNk8dO1ikV40 -1Ow3dITIoU0KiTcUFKWX08p+w6LhCVPRNE5Y2+X9/40kdFGUth2p2mN2fQDJnXxt -2+LNIVg0VQbUwULR88gGBanN5Ig3xjl9sUc79QQk34fIRjTilJUuPEEIgjH2JviQ -OxefAoGARAp5bFIw5uHdXY/ZPOXfvwEskPoMV7iIStr56aXhv9io//F2mAiowyex -jfnbd/9adGh+zWzy5d39m58AcjqmrIZ3KtTA1lcqJfbmJ7XsIJOnNKtmTrRfYMAc -dOoqHC4yOEpn5C5L7e6QvygO0lPYDkYeX63DPrUXkqJ29olsiWA= ------END RSA PRIVATE KEY----- diff --git a/tests/common/ssh/id_rsa.pub b/tests/common/ssh/id_rsa.pub deleted file mode 100644 index f8f9ca5..0000000 --- a/tests/common/ssh/id_rsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEr0Tu81hAelpQL5DWBNuRdoUtdRUD1dZohqe6+uROjqkvKT/QwqthNxVqCgbnles62ON2h+gjjGmYwAVwVxXVwj7UGM97BCUbTg6PiguxYzj5tM2nqM2NLTkxQXZgu1ZjftodKL+vnWCSPsUxmJQK2q/wSNMDHBWy2D2wU307EIVIexyf7fjto1KRV2eV4MKxbD0LO5rXVBkprULrjNqmkpVU6TkSvz8NBNYP9ZCEsDm+y5/WO51MEssl3fxp5Jnf4bNU7dRLxNKGShqx5F/SL5Ucj66QG840waPyP0Dvg7TvFjeKofwLRfgIg+zl98EE7eBkLX6mvoGBJ/0LnhZR root@localhost.localdomain diff --git a/tests/config.pl b/tests/config.pl new file mode 100644 index 0000000..ea1413d --- /dev/null +++ b/tests/config.pl @@ -0,0 +1,131 @@ +#!/usr/bin/env perl + +#################################################################################################################################### +# Perl includes +#################################################################################################################################### +use strict; +use warnings; +use File::Basename qw(dirname); +use File::Path qw(make_path); +use Getopt::Long qw(GetOptions); +use List::Util qw(any); +use Pod::Usage qw(pod2usage); +use YAML::XS qw(LoadFile DumpFile); + +#################################################################################################################################### +# Global vars +#################################################################################################################################### +my $dbTypes = { + 'PG' => ['9.6', '10', '11', '12', '13'], + 'EPAS' => ['9.6', '10', '11', '12', '13'] +}; + +my @supportedDockerImages = ('debian:9', 'debian:10', 'ubuntu:18.04', 'ubuntu:20.04', 'centos:7', 'centos:8'); + +#################################################################################################################################### +# Usage +#################################################################################################################################### + +=head1 NAME + +config.pl - generate configuration file + +=head1 SYNOPSIS + +config.pl [options] + + Cluster Options: + --cluster-name cluster name (a directory named after this name will be created in cluster path) + --cluster-path cluster path + --extra-vars additional cluster variables ('key=value key2=value2' format) + + Test Options: + --architecture target architecture + --db-type database type ('EPAS' or 'PG') + --db-version version of database + + Docker Options: + --docker-image docker base image name ('debian:9', 'debian:10', 'ubuntu:18.04', 'ubuntu:20.04', 'centos:7', 'centos:8') + + General Options: + --help display usage and exit + --force force configuration file update +=cut + +#################################################################################################################################### +# Command line parameters +#################################################################################################################################### +my $bHelp = 0; +my $bForce = 0; +my $strArchitecture; +my $strClusterName; +my $strClusterPath; +my $strExtraVars; +my $strDbType; +my $strDbVersion; +my $strDockerImage; + +GetOptions( + 'architecture=s' => \$strArchitecture, + 'cluster-name=s' => \$strClusterName, + 'cluster-path=s' => \$strClusterPath, + 'db-type=s' => \$strDbType, + 'db-version=s' => \$strDbVersion, + 'docker-image=s' => \$strDockerImage, + 'extra-vars=s' => \$strExtraVars, + 'force' => \$bForce, + 'help' => \$bHelp, +) or pod2usage( -exitval => 127 ); +pod2usage() if $bHelp; + +#################################################################################################################################### +# Run in eval block to catch errors +#################################################################################################################################### +eval{ + print("-------------------PROCESS START-------------------\n"); + print("INFO: config begin\n"); + die("cluster path must be provided") unless defined($strClusterPath); + die("db type '$strDbType' not supported") if (defined($strDbType) and !defined($dbTypes->{$strDbType})); + if(defined($strDbVersion)){ + die("db type must be provided when db version is provided") unless defined($strDbType); + die("db type '$strDbType', version '$strDbVersion' not supported") unless (any { $_ eq $strDbVersion } @{$dbTypes->{$strDbType}}); + } + die("docker image '$strDockerImage' not supported") unless !defined($strDockerImage) or (any { $_ eq $strDockerImage } @supportedDockerImages); + + # Validate architecture and load configuration file + die("architecture must be provided") unless defined($strArchitecture); + my $archConfFile = dirname($0)."/architectures/".$strArchitecture."/config.yml"; + die("architecture '$strArchitecture' not found") unless (-f $archConfFile); + print("INFO: load '$archConfFile'\n"); + my $archConfig = LoadFile($archConfFile); + + # Modify cluster configuration + $archConfig->{cluster_name} = $strClusterName if defined($strClusterName); + $archConfig->{cluster_vars}->{pg_type} = $strDbType if defined($strDbType); + $archConfig->{cluster_vars}->{pg_version} = $strDbVersion if defined($strDbVersion); + $archConfig->{docker}->{image_name} = $strDockerImage if defined($strDockerImage); + + # Add extra cluster vars + if(defined $strExtraVars and length $strExtraVars){ + $strExtraVars =~ s/^\s+|\s+$//g; + foreach(split(/\s+/, $strExtraVars)){ + my ($key, $value) = split(/=/, $_); + die("extra variables format must be 'key=value'") unless defined($key) and defined($value); + $archConfig->{cluster_vars}->{$key} = $value; + } + } + + # Create cluster directory + my $strClusterDir = $strClusterPath."/".$strClusterName; + die("cluster directory already exists") if (-e $strClusterDir and !$bForce); + if(! -e $strClusterDir){ + print("INFO: create cluster directory '$strClusterDir'\n"); + make_path($strClusterDir, { verbose => 1 }) or die("failed to create '$strClusterDir'"); + } + print("INFO: write cluster configuration file\n"); + DumpFile($strClusterDir."/config.yml", $archConfig) or die("failed to write cluster configuration file"); + + # Exit with success + exit 0; +}; +die("ERROR: test execution failed - $@\n") if $@; diff --git a/tests/debian/Makefile b/tests/debian/Makefile deleted file mode 100644 index a659b0f..0000000 --- a/tests/debian/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -all: clean create_vm pgbackrest_local - -create_vm: - vagrant up - -pgbackrest_local: - vagrant up --provision-with=pgbackrest_local - vagrant up --provision-with=check_pgbackrest - -clean: - vagrant destroy -f \ No newline at end of file diff --git a/tests/debian/Vagrantfile b/tests/debian/Vagrantfile deleted file mode 100644 index 2bec822..0000000 --- a/tests/debian/Vagrantfile +++ /dev/null @@ -1,52 +0,0 @@ -pgver = '12' # pg version to use -vm_prefix = 'c_pgbr_d10' - -Vagrant.configure(2) do |config| - - pgdata = "/var/lib/postgresql/#{pgver}/main" - - config.vm.box = "debian/buster64" - - # hardware and host settings - config.vm.provider 'libvirt' do |lv| - lv.cpus = 1 - lv.memory = 2048 - lv.default_prefix = vm_prefix - end - - # don't mind about insecure ssh key - config.ssh.insert_key = false - - # don't share the default vagrant folder - config.vm.synced_folder ".", "/vagrant", disabled: true - - # mount check_pgbackrest path for testing - config.vm.synced_folder "../..", "/check_pgbackrest", nfs_udp: false - if File.directory?(File.expand_path("../../../pgbackrest")) - config.vm.synced_folder "../../../pgbackrest", "/pgbackrest", nfs_udp: false - end - - # install PostgreSQL on all the nodes - config.vm.provision 'pgsql', type: 'shell', - path: 'provision/pgsql.bash', - args: [ pgver, pgdata ] - - # ssh configuration - config.vm.synced_folder '../common/ssh', '/root/.ssh', type: 'rsync', - owner: 'root', group: 'root', - rsync__args: [ "--verbose", "--archive", "--delete", "--copy-links", "--no-perms" ] - - config.vm.define "pgsql-srv" do |pgsql| - pgsql.vm.hostname = "pgsql-srv" - - # pgbackrest local setup - pgsql.vm.provision 'pgbackrest_local', type: 'shell', - path: 'provision/pgbackrest_local.bash', - args: [ pgver, pgdata ], - run: 'never' - - # install check_pgbackrest from PGDG repo - pgsql.vm.provision 'check_pgbackrest', type: 'shell', - path: 'provision/check_pgbackrest.bash', run: 'never' - end -end diff --git a/tests/debian/provision/check_pgbackrest.bash b/tests/debian/provision/check_pgbackrest.bash deleted file mode 100644 index 7d9b8ca..0000000 --- a/tests/debian/provision/check_pgbackrest.bash +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -# check-pgbackrest from PGDG repo -PLUGIN_PATH=/usr/bin/ -sudo apt-get -y install check-pgbackrest - -# Initiate backups (full, diff, incr) -echo "Initiate backups (full, diff, incr)" -sudo -iu postgres pgbackrest --stanza=my_stanza backup --type=full --repo1-retention-full=1 -sudo -iu postgres pgbackrest --stanza=my_stanza backup --type=diff -sudo -iu postgres pgbackrest --stanza=my_stanza backup --type=incr -sudo -iu postgres pgbackrest --stanza=my_stanza info - -echo "--list" -$PLUGIN_PATH/check_pgbackrest --list -echo "--version" -$PLUGIN_PATH/check_pgbackrest --version - -echo "--service=retention --retention-full" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-full=1 -printf "\n" -echo "--service=retention --retention-age" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-age=1h -printf "\n" -echo "--service=retention --retention-age-to-full" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=retention --retention-age-to-full=1h -printf "\n" - -echo "--service=archives --repo-path" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --repo-path=/var/lib/pgbackrest/archive -printf "\n" -echo "--service=archives --repo-path --enable-internal-pgbr-cmds --output=human --debug" -$PLUGIN_PATH/check_pgbackrest --stanza=my_stanza --service=archives --repo-path=/var/lib/pgbackrest/archive --enable-internal-pgbr-cmds --output=human --debug diff --git a/tests/debian/provision/pgbackrest_local.bash b/tests/debian/provision/pgbackrest_local.bash deleted file mode 100644 index fcac9c4..0000000 --- a/tests/debian/provision/pgbackrest_local.bash +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" - -# Install pgbackrest -sudo apt-get -y install pgbackrest - -cat< "/etc/pgbackrest.conf" -[global] -repo1-path=/var/lib/pgbackrest -repo1-retention-full=1 -process-max=2 -log-level-console=warn -log-level-file=info -start-fast=y -delta=y -repo1-cipher-type=aes-256-cbc -repo1-cipher-pass=acbd - -[my_stanza] -pg1-path=${PGDATA} -EOC - -sudo -iu postgres pgbackrest --stanza=my_stanza stanza-create - -# archive_command setup -cat <<'EOS' | psql -U postgres -ALTER SYSTEM SET "archive_command" TO 'pgbackrest --stanza=my_stanza archive-push %p'; -SELECT pg_reload_conf(); -EOS - -sudo -iu postgres pgbackrest --stanza=my_stanza check diff --git a/tests/debian/provision/pgsql.bash b/tests/debian/provision/pgsql.bash deleted file mode 100644 index cad2f05..0000000 --- a/tests/debian/provision/pgsql.bash +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -PGVER="$1" -PGDATA="$2" - -# Common system -localedef -i en_US -f UTF-8 en_US.UTF-8 -apt-get install -y gnupg2 - -# Create the file repository configuration: -sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' - -# Import the repository signing key: -wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - - -# Update the package lists: -sudo apt-get update - -# Install -sudo mkdir -p /etc/postgresql-common/createcluster.d -echo "initdb_options = '--data-checksums --auth-host=trust --auth-local=trust'" >> /etc/postgresql-common/createcluster.d/custom.conf -sudo apt-get -y install "postgresql-${PGVER}" -pg_lsclusters - -# postgresql.conf setup -cat <<'EOS' | psql -U postgres -ALTER SYSTEM SET "listen_addresses" TO '*'; -ALTER SYSTEM SET "wal_level" TO 'replica'; -ALTER SYSTEM SET "archive_mode" TO 'on'; -ALTER SYSTEM SET "archive_command" TO '/bin/true'; -EOS -sudo pg_ctlcluster 12 main restart - -# Force proper permissions on .ssh files -chmod -R 0600 /root/.ssh -chmod 0700 /root/.ssh -cp -rf /root/.ssh /var/lib/postgresql/.ssh -chown -R postgres: /var/lib/postgresql/.ssh diff --git a/tests/platforms/azure/blob-create-container.py b/tests/platforms/azure/blob-create-container.py new file mode 100755 index 0000000..d8a2d9b --- /dev/null +++ b/tests/platforms/azure/blob-create-container.py @@ -0,0 +1,29 @@ +#!/usr/bin/python +import argparse, os, urllib3 +from azure.storage.blob import BlobServiceClient, __version__ + +try: + print("Azure Blob Storage v" + __version__) + + # Parse arguments + parser = argparse.ArgumentParser() + parser.add_argument("--container_name", "-c", help="container name to create") + args = parser.parse_args() + + # Get Connection String from environment + connect_str = os.getenv('AZURE_STORAGE_CONNECTION_STRING') + urllib3.disable_warnings() + blob_service_client = BlobServiceClient.from_connection_string(connect_str, connection_verify=False) + + # Create the container + if args.container_name: + container_client = blob_service_client.get_container_client(args.container_name) + if container_client.exists(): + print("Container %s already exists..." % args.container_name) + else: + print("Container name to create: %s" % args.container_name) + container_client = blob_service_client.create_container(args.container_name) + +except Exception as ex: + print('Exception:') + print(ex) \ No newline at end of file diff --git a/tests/platforms/common/inventory/docker.j2 b/tests/platforms/common/inventory/docker.j2 new file mode 100644 index 0000000..83234e4 --- /dev/null +++ b/tests/platforms/common/inventory/docker.j2 @@ -0,0 +1,9 @@ +--- +all: + hosts: +{% for h in instances %} +{% if platform == 'docker' %} + {{ h.name }}: + ansible_connection: docker +{% endif%} +{% endfor %} \ No newline at end of file diff --git a/tests/platforms/common/inventory/inventory.j2 b/tests/platforms/common/inventory/inventory.j2 new file mode 100644 index 0000000..6b5ec1b --- /dev/null +++ b/tests/platforms/common/inventory/inventory.j2 @@ -0,0 +1,19 @@ +--- +all: + children: +{% for g in instances_groups %} + {{ g }}: + hosts: +{% for h in instances %} +{% if h.ansible_group == g %} + {{ h.name }}: +{% endif%} +{% endfor %} +{% endfor %} +{% if cluster_vars.deploy_icinga2 is defined and cluster_vars.deploy_icinga2 | bool %} + icinga2: + hosts: + {{ cluster_name }}-icinga2: + ansible_connection: docker + ansible_python_interpreter: auto +{% endif%} diff --git a/tests/platforms/common/inventory/write.yml b/tests/platforms/common/inventory/write.yml new file mode 100644 index 0000000..7af9973 --- /dev/null +++ b/tests/platforms/common/inventory/write.yml @@ -0,0 +1,89 @@ +--- +- name: Ensure that the cluster's inventory directories exist + file: + path: "{{ cluster_dir }}/{{ item }}" + state: directory + loop: + - inventory + - inventory/host_vars + - inventory/group_vars + +- name: Create host_vars subdirectories + file: + path: "{{ cluster_dir }}/inventory/host_vars/{{ item.name }}" + state: directory + loop: "{{ instances | flatten(levels=1) }}" + loop_control: + label: >- + {{ item.name }} + +- name: Get ansible groups + set_fact: + instances_groups: "{{ instances_groups | default([]) | union([ item.ansible_group ]) }}" + loop: "{{ instances | flatten(levels=1) }}" + loop_control: + label: >- + {{ item.ansible_group }} + +- name: Write docker static inventory file + template: + src: docker.j2 + dest: "{{ cluster_dir }}/inventory.docker.yml" + mode: 0644 + when: platform == 'docker' + +- name: Write inventory file + template: + src: inventory.j2 + dest: "{{ cluster_dir }}/inventory/inventory.yml" + mode: 0644 + +- name: Write group_vars + copy: + content: | + {{ group_vars|to_nice_yaml(indent=2) }} + dest: "{{ group_dir }}/{{ file_name }}" + mode: 0644 + force: yes + vars: + ansible_ssh_private_key_file: "{{ cluster_dir }}/{{ ssh_key_file }}" + file_name: "all.yml" + group_dir: "{{ cluster_dir }}/inventory/group_vars" + group_vars: > + {{ + cluster_vars|combine({ + 'cluster_name': cluster_name, + 'ansible_ssh_private_key_file': ansible_ssh_private_key_file, + }) + }} + +- name: Write instance variables for hosts + copy: + content: | + {{ host_vars|to_nice_yaml(indent=2) }} + dest: "{{ host_dir }}/{{ file_name }}" + mode: 0644 + force: yes + vars: + file_name: "instance_vars.yml" + host_dir: "{{ cluster_dir }}/inventory/host_vars/{{ item.name }}" + host_vars: "{{ item.vars }}" + loop: "{{ instance_vars|flatten(levels=1) }}" + loop_control: + label: >- + {{ item.name }} + when: item.vars | length > 0 + +- name: Transform upstream property to upstream_node_private_ip + ansible.builtin.lineinfile: + path: "{{ host_dir }}/{{ file_name }}" + regexp: '^upstream: ' + line: "upstream_node_private_ip: {{ private_ip_list[item.vars.upstream] }}" + vars: + file_name: "instance_vars.yml" + host_dir: "{{ cluster_dir }}/inventory/host_vars/{{ item.name }}" + when: item.vars.upstream is defined + loop: "{{ instance_vars|flatten(levels=1) }}" + loop_control: + label: >- + {{ item.name }} \ No newline at end of file diff --git a/tests/platforms/common/provision.yml b/tests/platforms/common/provision.yml new file mode 100644 index 0000000..e70da3c --- /dev/null +++ b/tests/platforms/common/provision.yml @@ -0,0 +1,28 @@ +--- +- name: Run ssh-keygen + command: ssh-keygen -P "" -f "{{ ssh_key_file }}" + args: + chdir: "{{ cluster_dir }}" + creates: "{{ ssh_key_file }}" + +- name: Ensure that the cluster's certs directory exist + file: + path: "{{ cluster_dir }}/certs" + state: directory + +- name: Generate an OpenSSL private key - 2048 bits + community.crypto.openssl_privatekey: + path: "{{ cluster_dir }}/certs/{{ cluster_name }}.key" + size: 2048 + +- name: Generate an OpenSSL Certificate Signing Request + community.crypto.openssl_csr: + path: "{{ cluster_dir }}/certs/{{ cluster_name }}.csr" + privatekey_path: "{{ cluster_dir }}/certs/{{ cluster_name }}.key" + +- name: Generate a Self Signed OpenSSL certificate + community.crypto.x509_certificate: + provider: selfsigned + path: "{{ cluster_dir }}/certs/{{ cluster_name }}.crt" + privatekey_path: "{{ cluster_dir }}/certs/{{ cluster_name }}.key" + csr_path: "{{ cluster_dir }}/certs/{{ cluster_name }}.csr" \ No newline at end of file diff --git a/tests/platforms/deprovision.yml b/tests/platforms/deprovision.yml new file mode 100644 index 0000000..7d82bf3 --- /dev/null +++ b/tests/platforms/deprovision.yml @@ -0,0 +1,23 @@ +--- +- name: Deprovision cluster + hosts: localhost + tasks: + - name: Require cluster directory to be specified + assert: + msg: "No cluster directory specified" + that: + - cluster_dir is defined and cluster_dir != '' + + - import_tasks: load-config.yml + + - assert: + msg: "Unsupported platform: '{{ platform }}'" + that: + - platform is defined + - platform in _available_platforms + vars: + _available_platforms: + - 'docker' + + - include_tasks: "{{ platform }}/deprovision.yml" + - include_tasks: "docker/deprovision-repository-types.yml" \ No newline at end of file diff --git a/tests/platforms/docker/build_all_images.yml b/tests/platforms/docker/build_all_images.yml new file mode 100644 index 0000000..9e746d3 --- /dev/null +++ b/tests/platforms/docker/build_all_images.yml @@ -0,0 +1,21 @@ +--- +- name: Build all systemd images + hosts: localhost + tasks: + - docker_image: + name: "systemd/{{ item.base }}:{{ item.tag }}" + state: present + source: build + build: + path: systemd + dockerfile: "{{ item.base }}.Dockerfile" + pull: no + args: + BASE_IMAGE: "{{ item.base }}:{{ item.tag }}" + loop: + - { base: 'debian', tag: '9' } + - { base: 'debian', tag: '10' } + - { base: 'ubuntu', tag: '18.04' } + - { base: 'ubuntu', tag: '20.04' } + - { base: 'centos', tag: '7' } + - { base: 'centos', tag: '8' } \ No newline at end of file diff --git a/tests/platforms/docker/deprovision-repository-types.yml b/tests/platforms/docker/deprovision-repository-types.yml new file mode 100644 index 0000000..8d628ff --- /dev/null +++ b/tests/platforms/docker/deprovision-repository-types.yml @@ -0,0 +1,30 @@ +--- +- name: Deprovision MinIO docker container + docker_container: + name: "{{ cluster_name }}-minio" + state: absent + container_default_behavior: compatibility + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "s3" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Deprovision Azurite docker container + docker_container: + name: "{{ cluster_name }}-azurite" + state: absent + container_default_behavior: compatibility + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "azure" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Deprovision Icinga2 docker container + docker_container: + name: "{{ cluster_name }}-icinga2" + state: absent + container_default_behavior: compatibility + when: cluster_vars.deploy_icinga2 is defined and cluster_vars.deploy_icinga2 | bool + +- name: Delete docker network + docker_network: + name: "network_{{ cluster_name }}" + state: absent \ No newline at end of file diff --git a/tests/platforms/docker/deprovision.yml b/tests/platforms/docker/deprovision.yml new file mode 100644 index 0000000..48c4806 --- /dev/null +++ b/tests/platforms/docker/deprovision.yml @@ -0,0 +1,15 @@ +--- +- name: Deprovision docker containers + docker_container: + name: "{{ item.name }}" + state: absent + container_default_behavior: compatibility + loop: "{{ instances | flatten(levels=1) }}" + loop_control: + label: >- + {{ item.name }} + +- name: Delete docker network + docker_network: + name: "network_{{ cluster_name }}" + state: absent \ No newline at end of file diff --git a/tests/platforms/docker/docker_container.yml b/tests/platforms/docker/docker_container.yml new file mode 100644 index 0000000..8d0018b --- /dev/null +++ b/tests/platforms/docker/docker_container.yml @@ -0,0 +1,43 @@ +--- +- name: Provision docker container "{{ item.name }}" + community.docker.docker_container: + name: "{{ item.name }}" + hostname: "{{ item.name }}" + image: "systemd/{{ docker.image_name }}" + state: started + pull: no + detach: yes + exposed_ports: "{{ _exposed_ports }}" + published_ports: "{{ _exposed_ports }}" + networks: + - name: "network_{{ cluster_name }}" + networks_cli_compatible: yes + volumes: + - "/sys/fs/cgroup:/sys/fs/cgroup:ro" + - "{{ cluster_dir }}/shared:/shared:z" + tmpfs: + - "/tmp" + - "/run" + - "/run/lock" + container_default_behavior: compatibility + network_mode: default + restart_policy: unless-stopped + vars: + _exposed_ports: "{{ docker.exposed_ports|default(['22','5432', '5444']) }}" + register: docker_container_register + +- set_fact: + docker_container_results: "{{ + docker_container_results|default([])|union([ + dc|combine({ + 'item': item|combine({ + 'private_ip': nw.Networks[nw_name].IPAddress, + 'ansible_host': nw.Networks[nw_name].IPAddress, + }) + }) + ]) + }}" + vars: + dc: "{{ docker_container_register.container }}" + nw: "{{ dc.NetworkSettings }}" + nw_name: "network_{{ cluster_name }}" \ No newline at end of file diff --git a/tests/platforms/docker/provision-repository-types.yml b/tests/platforms/docker/provision-repository-types.yml new file mode 100644 index 0000000..abde828 --- /dev/null +++ b/tests/platforms/docker/provision-repository-types.yml @@ -0,0 +1,109 @@ +--- +- name: Create docker network + docker_network: + name: "network_{{ cluster_name }}" + state: present + +- name: Ensure that the cluster's MinIO data directory exists with default bucket + file: + path: "{{ cluster_dir }}/{{ item }}" + state: directory + loop: + - "minio" + - "minio/data" + - "minio/data/bucket" + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "s3" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Provision MinIO docker container + community.docker.docker_container: + image: minio/minio + name: "{{ cluster_name }}-minio" + state: started + restart_policy: always + command: server /data --address :443 + exposed_ports: "443" + published_ports: "443" + networks: + - name: "network_{{ cluster_name }}" + volumes: + - "{{ cluster_dir }}/minio/data:/data:z" + - "{{ cluster_dir }}/certs/{{ cluster_name }}.crt:/root/.minio/certs/public.crt:z" + - "{{ cluster_dir }}/certs/{{ cluster_name }}.key:/root/.minio/certs/private.key:z" + networks_cli_compatible: yes + network_mode: default + container_default_behavior: compatibility + env: + MINIO_ACCESS_KEY: "accessKey" + MINIO_SECRET_KEY: "superSECRETkey" + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "s3" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Ensure that the cluster's Azurite data directory exists + file: + path: "{{ cluster_dir }}/{{ item }}" + state: directory + loop: + - "azurite" + - "azurite/data" + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "azure" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Provision Azurite docker container + community.docker.docker_container: + image: mcr.microsoft.com/azure-storage/azurite + name: "{{ cluster_name }}-azurite" + state: started + restart_policy: always + command: azurite-blob --blobPort 443 --blobHost 0.0.0.0 --cert=/root/public.crt --key=/root/private.key -l /workspace -d /workspace/debug.log + exposed_ports: "443" + published_ports: "443" + networks: + - name: "network_{{ cluster_name }}" + volumes: + - "{{ cluster_dir }}/azurite/data:/workspace:z" + - "{{ cluster_dir }}/certs/{{ cluster_name }}.crt:/root/public.crt:ro" + - "{{ cluster_dir }}/certs/{{ cluster_name }}.key:/root/private.key:ro" + networks_cli_compatible: yes + network_mode: default + container_default_behavior: compatibility + env: + AZURITE_ACCOUNTS: "pgbackrest:aF49wnZP" + register: azure_docker_container_register + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "azure" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Azure Blob Storage - create container + command: "python3 {{ playbook_dir }}/azure/blob-create-container.py -c container" + vars: + dc: "{{ azure_docker_container_register.container }}" + nw: "{{ dc.NetworkSettings }}" + nw_name: "network_{{ cluster_name }}" + environment: + AZURE_STORAGE_CONNECTION_STRING: "DefaultEndpointsProtocol=https;AccountName=pgbackrest;AccountKey=aF49wnZP;BlobEndpoint=https://{{nw.Networks[nw_name].IPAddress}}/pgbackrest;" + when: > + cluster_vars.pgbackrest_repo_type is defined and + (cluster_vars.pgbackrest_repo_type == "azure" or cluster_vars.pgbackrest_repo_type == "multi") + +- name: Provision Icinga2 docker container + community.docker.docker_container: + image: jordan/icinga2 + name: "{{ cluster_name }}-icinga2" + state: started + restart_policy: "no" + published_ports: + - "80:80" + - "443:443" + - "5665:5665" + networks: + - name: "network_{{ cluster_name }}" + networks_cli_compatible: yes + network_mode: default + container_default_behavior: compatibility + env: + ICINGA2_FEATURE_DIRECTOR_PASS: "anyPassWord" + when: cluster_vars.deploy_icinga2 is defined and cluster_vars.deploy_icinga2 | bool \ No newline at end of file diff --git a/tests/platforms/docker/provision.yml b/tests/platforms/docker/provision.yml new file mode 100644 index 0000000..ebf6883 --- /dev/null +++ b/tests/platforms/docker/provision.yml @@ -0,0 +1,76 @@ +--- +- assert: + msg: "Unsupported docker image_name: '{{ docker.image_name }}'" + that: docker.image_name in _available_images + vars: + _available_images: + - 'debian:9' + - 'debian:10' + - 'ubuntu:18.04' + - 'ubuntu:20.04' + - 'centos:7' + - 'centos:8' + +- name: Build systemd image {{ docker.image_name }} + docker_image: + name: "systemd/{{ _image_base }}:{{ _image_tag }}" + state: present + source: build + build: + path: docker/systemd + dockerfile: "{{ _image_base }}.Dockerfile" + pull: no + args: + BASE_IMAGE: "{{ _image_base }}:{{ _image_tag }}" + vars: + _parts: "{{ docker.image_name.split(':') }}" + _image_base: "{{ _parts[0] }}" + _image_tag: "{{ _parts[1] }}" + +- name: Create docker network + docker_network: + name: "network_{{ cluster_name }}" + state: present + +- name: Ensure that the cluster's default shared directory exist + file: + path: "{{ cluster_dir }}/shared" + state: directory + owner: root + group: root + mode: '1777' + become: yes + +- name: Provision docker containers + include_tasks: docker_container.yml + loop: "{{ instances | flatten(levels=1) }}" + loop_control: + label: >- + {{ item.name }} + +- name: Set instance variables + set_fact: + instance_vars: "{{ + instance_vars | default([]) | union([ + { + 'name': item.item.name, + 'vars': item.item + } + ]) + }}" + with_items: + "{{ docker_container_results }}" + loop_control: + label: >- + {{ item.item.name }} + +- name: Create private ip list + set_fact: + private_ip_list: "{{ + private_ip_list | default({}) | combine({ item.name: item.vars.private_ip }) + }}" + when: item.vars.private_ip is defined + loop: "{{ instance_vars|flatten(levels=1) }}" + loop_control: + label: >- + {{ item.name }} \ No newline at end of file diff --git a/tests/platforms/docker/systemd/centos.Dockerfile b/tests/platforms/docker/systemd/centos.Dockerfile new file mode 100644 index 0000000..68eadea --- /dev/null +++ b/tests/platforms/docker/systemd/centos.Dockerfile @@ -0,0 +1,19 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} + +ENV container docker + +RUN cd /lib/systemd/system/sysinit.target.wants/; \ + for i in *; do [ $i = systemd-tmpfiles-setup.service ] || rm -f $i; done + +RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ + /etc/systemd/system/*.wants/* \ + /lib/systemd/system/local-fs.target.wants/* \ + /lib/systemd/system/sockets.target.wants/*udev* \ + /lib/systemd/system/sockets.target.wants/*initctl* \ + /lib/systemd/system/basic.target.wants/* \ + /lib/systemd/system/anaconda.target.wants/* + +VOLUME [ "/sys/fs/cgroup" ] + +CMD ["/usr/sbin/init"] \ No newline at end of file diff --git a/tests/platforms/docker/systemd/debian.Dockerfile b/tests/platforms/docker/systemd/debian.Dockerfile new file mode 100644 index 0000000..c558f78 --- /dev/null +++ b/tests/platforms/docker/systemd/debian.Dockerfile @@ -0,0 +1,23 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} + +ENV container docker +ENV LC_ALL C +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update \ + && apt-get install -y python3 systemd systemd-sysv \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ + /etc/systemd/system/*.wants/* \ + /lib/systemd/system/local-fs.target.wants/* \ + /lib/systemd/system/sockets.target.wants/*udev* \ + /lib/systemd/system/sockets.target.wants/*initctl* \ + /lib/systemd/system/sysinit.target.wants/systemd-tmpfiles-setup* \ + /lib/systemd/system/systemd-update-utmp* + +VOLUME [ "/sys/fs/cgroup" ] + +CMD ["/lib/systemd/systemd"] diff --git a/tests/platforms/docker/systemd/ubuntu.Dockerfile b/tests/platforms/docker/systemd/ubuntu.Dockerfile new file mode 100644 index 0000000..9241ca7 --- /dev/null +++ b/tests/platforms/docker/systemd/ubuntu.Dockerfile @@ -0,0 +1,30 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} + +ENV container docker +ENV LC_ALL C +ENV DEBIAN_FRONTEND noninteractive + +RUN sed -i 's/# deb/deb/g' /etc/apt/sources.list + +RUN apt-get update \ + && apt-get install -y systemd systemd-sysv \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN cd /lib/systemd/system/sysinit.target.wants/ \ + && ls | grep -v systemd-tmpfiles-setup | xargs rm -f $1 + +RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ + /etc/systemd/system/*.wants/* \ + /lib/systemd/system/local-fs.target.wants/* \ + /lib/systemd/system/sockets.target.wants/*udev* \ + /lib/systemd/system/sockets.target.wants/*initctl* \ + /lib/systemd/system/basic.target.wants/* \ + /lib/systemd/system/anaconda.target.wants/* \ + /lib/systemd/system/plymouth* \ + /lib/systemd/system/systemd-update-utmp* + +VOLUME [ "/sys/fs/cgroup" ] + +CMD ["/lib/systemd/systemd"] \ No newline at end of file diff --git a/tests/platforms/load-config.yml b/tests/platforms/load-config.yml new file mode 100644 index 0000000..8c31166 --- /dev/null +++ b/tests/platforms/load-config.yml @@ -0,0 +1,24 @@ +--- +- name: Set full path to cluster_dir and config_file + set_fact: + config_file: "{{ cluster_dir }}/{{ file }}" + vars: + file: >- + {{ config|default('config.yml') }} + +- name: Load cluster configuration file + include_vars: "{{ config_file }}" + +- name: Ensure cluster_name is specified + assert: + msg: "Please define cluster_name in {{ config_file }}" + that: + - cluster_name is defined + - cluster_name != '' + +- name: Set ssh_key_file + set_fact: + ssh_key_file: >- + {{ ssh_key_file|default(_default) }} + vars: + _default: "id_{{ cluster_name|lower }}" \ No newline at end of file diff --git a/tests/platforms/provision.yml b/tests/platforms/provision.yml new file mode 100644 index 0000000..d545758 --- /dev/null +++ b/tests/platforms/provision.yml @@ -0,0 +1,25 @@ +--- +- name: Provision cluster + hosts: localhost + tasks: + - name: Require cluster directory to be specified + assert: + msg: "No cluster directory specified" + that: + - cluster_dir is defined and cluster_dir != '' + + - import_tasks: load-config.yml + + - assert: + msg: "Unsupported platform: '{{ platform }}'" + that: + - platform is defined + - platform in _available_platforms + vars: + _available_platforms: + - 'docker' + + - include_tasks: "common/provision.yml" + - include_tasks: "{{ platform }}/provision.yml" + - include_tasks: "docker/provision-repository-types.yml" + - include_tasks: common/inventory/write.yml \ No newline at end of file diff --git a/tests/platforms/system-config.yml b/tests/platforms/system-config.yml new file mode 100644 index 0000000..3d1711b --- /dev/null +++ b/tests/platforms/system-config.yml @@ -0,0 +1,15 @@ +--- +- name: Apply default system configuration + hosts: all + tasks: + - name: Require cluster directory to be specified + assert: + msg: "No cluster directory specified" + that: + - cluster_dir is defined and cluster_dir != '' + run_once: true + + - import_tasks: load-config.yml + + - include_role: + name: 'sys' \ No newline at end of file diff --git a/tests/playbooks/activity.yml b/tests/playbooks/activity.yml new file mode 100644 index 0000000..6bda68c --- /dev/null +++ b/tests/playbooks/activity.yml @@ -0,0 +1,79 @@ +--- +- name: Simulate activity + hosts: all + any_errors_fatal: true + tasks: + - name: Copy regression tests to remote host + copy: + src: regress/ + dest: /tmp/regress/ + directory_mode: yes + mode: '0755' + when: > + 'primary' in group_names and + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) + + - name: Run check_pgbackrest regression tests + command: /usr/bin/env bash /tmp/regress/regression-tests.bash -P /usr/bin 2>&1 |tee /var/log/regression-tests.log + environment: + PGBIN: "{{ cluster_vars['pg_bin_path'] }}" + PGDATABASE: "{{ cluster_vars['pg_database'] }}" + PGUNIXSOCKET: "{{ cluster_vars['pg_unix_socket'] }}" + PGUSER: "{{ cluster_vars['pg_owner'] }}" + STANZA: "{{ cluster_vars['cluster_name'] }}" + PGBR_HOST: "{{ cluster_vars['pgbackrest_repo_host'] | default(None) }}" + PGBR_USER: "{{ cluster_vars['pgbackrest_user'] }}" + PGBR_REPO_TYPE: "{{ cluster_vars['pgbackrest_repo_type'] }}" + SCRIPT_PROFILE: "" + vars: + cluster_vars: "{{ ansible_local['profile']['global'] }}" + register: regress_output + when: > + 'primary' in group_names and + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) + + - name: Regression tests output + debug: var=regress_output.stdout_lines + when: regress_output.changed + + - name: Copy activity script to remote host + copy: + src: scripts/simulate-activity-basic.bash + dest: /tmp/simulate-activity-basic.bash + mode: '0755' + when: > + 'primary' in group_names and + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) + + - name: Simulate basic activity + command: /usr/bin/env bash /tmp/simulate-activity-basic.bash -s 10 -a 10 2>&1 |tee /var/log/simulate-activity-basic.log + environment: + PGBIN: "{{ cluster_vars['pg_bin_path'] }}" + PGDATABASE: "{{ cluster_vars['pg_database'] }}" + PGSVC: "{{ cluster_vars['pg_service'] }}" + PGUNIXSOCKET: "{{ cluster_vars['pg_unix_socket'] }}" + PGUSER: "{{ cluster_vars['pg_owner'] }}" + STANZA: "{{ cluster_vars['cluster_name'] }}" + PGBR_HOST: "{{ cluster_vars['pgbackrest_repo_host'] | default(None) }}" + PGBR_STANDBIES: "{{ cluster_vars['pgbackrest_standbies'] | default(None) }}" + PGBR_USER: "{{ cluster_vars['pgbackrest_user'] }}" + PGBR_REPO_TYPE: "{{ cluster_vars['pgbackrest_repo_type'] }}" + SCRIPT_PROFILE: "" + vars: + cluster_vars: "{{ ansible_local['profile']['global'] }}" + register: basic_activity_output + when: > + 'primary' in group_names and + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) + + - name: Basic activity output + debug: var=basic_activity_output.stdout_lines + when: basic_activity_output.changed + + - name: Check Icinga2 services + include_role: + name: setup_check_pgbackrest + tasks_from: icinga2-check.yml + vars: + reschedule_check_icinga2: true + when: deploy_icinga2 is defined and deploy_icinga2 | bool diff --git a/tests/playbooks/deploy.yml b/tests/playbooks/deploy.yml new file mode 100644 index 0000000..3bc5f02 --- /dev/null +++ b/tests/playbooks/deploy.yml @@ -0,0 +1,81 @@ +--- +- name: Deploy cluster + hosts: all + any_errors_fatal: true + tasks: + - name: Require cluster directory to be specified + assert: + msg: "No cluster directory specified" + that: + - cluster_dir is defined and cluster_dir != '' + run_once: true + + - name: Check EDB repository credentials + assert: + msg: "Missing credentials" + that: + - lookup('env', 'EDB_REPO_USERNAME') != '' + - lookup('env', 'EDB_REPO_PASSWORD') != '' + run_once: true + + # Install PGDG and EDB repositories + - include_role: + name: edb_devops.edb_postgres.setup_repo + vars: + pg_type: "PG" + repo_username: "{{ lookup('env', 'EDB_REPO_USERNAME') }}" + repo_password: "{{ lookup('env', 'EDB_REPO_PASSWORD') }}" + when: "'icinga2' not in group_names" + + - include_role: + name: edb_devops.edb_postgres.setup_repo + vars: + pg_type: "EPAS" + repo_username: "{{ lookup('env', 'EDB_REPO_USERNAME') }}" + repo_password: "{{ lookup('env', 'EDB_REPO_PASSWORD') }}" + when: "'icinga2' not in group_names" + + # Install db server and setup replication + - include_role: + name: edb_devops.edb_postgres.install_dbserver + when: "'primary' in group_names or 'standby' in group_names" + + - include_role: + name: edb_devops.edb_postgres.init_dbserver + vars: + use_replication_slots: false + use_hostname: false + when: "'primary' in group_names" + + - include_role: + name: edb_devops.edb_postgres.setup_replication + vars: + use_replication_slots: false + use_hostname: false + when: "'standby' in group_names" + + # Install pgBackRest and check_pgbackrest + - include_role: + name: setup_pgbackrest + when: > + 'pgbackrest_repo_host' in group_names or + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) + + - include_role: + name: setup_check_pgbackrest + when: > + 'pgbackrest_repo_host' in group_names or + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) or + 'icinga2' in group_names + + # Save facts locally for other playbooks + - name: Ensure local facts directory exists + file: state=directory path="/etc/ansible/facts.d" + + - name: Save local facts + template: + src: "profile.fact.j2" + dest: "/etc/ansible/facts.d/profile.fact" + when: > + 'primary' in group_names and + (hostvars[inventory_hostname].pgbackrest is defined and hostvars[inventory_hostname].pgbackrest == true) \ No newline at end of file diff --git a/tests/common/regress/expected/archives-age-alert-ko.out b/tests/playbooks/regress/expected/archives-age-alert-ko.out similarity index 100% rename from tests/common/regress/expected/archives-age-alert-ko.out rename to tests/playbooks/regress/expected/archives-age-alert-ko.out diff --git a/tests/common/regress/expected/archives-age-alert-ok.out b/tests/playbooks/regress/expected/archives-age-alert-ok.out similarity index 100% rename from tests/common/regress/expected/archives-age-alert-ok.out rename to tests/playbooks/regress/expected/archives-age-alert-ok.out diff --git a/tests/common/regress/expected/archives-ignore-after.out b/tests/playbooks/regress/expected/archives-ignore-after.out similarity index 100% rename from tests/common/regress/expected/archives-ignore-after.out rename to tests/playbooks/regress/expected/archives-ignore-after.out diff --git a/tests/common/regress/expected/archives-ignore-before.out b/tests/playbooks/regress/expected/archives-ignore-before.out similarity index 100% rename from tests/common/regress/expected/archives-ignore-before.out rename to tests/playbooks/regress/expected/archives-ignore-before.out diff --git a/tests/common/regress/expected/archives-ok.out b/tests/playbooks/regress/expected/archives-ok.out similarity index 100% rename from tests/common/regress/expected/archives-ok.out rename to tests/playbooks/regress/expected/archives-ok.out diff --git a/tests/common/regress/expected/list.out b/tests/playbooks/regress/expected/list.out similarity index 100% rename from tests/common/regress/expected/list.out rename to tests/playbooks/regress/expected/list.out diff --git a/tests/common/regress/expected/retention-age-to-full.out b/tests/playbooks/regress/expected/retention-age-to-full.out similarity index 100% rename from tests/common/regress/expected/retention-age-to-full.out rename to tests/playbooks/regress/expected/retention-age-to-full.out diff --git a/tests/common/regress/expected/retention-age.out b/tests/playbooks/regress/expected/retention-age.out similarity index 100% rename from tests/common/regress/expected/retention-age.out rename to tests/playbooks/regress/expected/retention-age.out diff --git a/tests/common/regress/expected/retention-fail.out b/tests/playbooks/regress/expected/retention-fail.out similarity index 100% rename from tests/common/regress/expected/retention-fail.out rename to tests/playbooks/regress/expected/retention-fail.out diff --git a/tests/common/regress/expected/retention-full.out b/tests/playbooks/regress/expected/retention-full.out similarity index 100% rename from tests/common/regress/expected/retention-full.out rename to tests/playbooks/regress/expected/retention-full.out diff --git a/tests/playbooks/regress/regression-tests.bash b/tests/playbooks/regress/regression-tests.bash new file mode 100755 index 0000000..05b15c3 --- /dev/null +++ b/tests/playbooks/regress/regression-tests.bash @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +set -o nounset +cd "$(dirname "$0")" + +# vars +PLUGIN_PATH=/usr/lib64/nagios/plugins +RESULTS_DIR=/tmp/results +SKIP_INIT=false + +usage() { + echo "Usage:" + echo " -s Skip backups initialization step." + echo " -P Change check_pgbackrest plugin path." + echo " -p Use local or remote profile." +} + +while getopts "sP:p:" o; do + case "${o}" in + s) + SKIP_INIT=true + ;; + P) + PLUGIN_PATH=${OPTARG} + ;; + p) + SCRIPT_PROFILE=${OPTARG} + ;; + *) + usage 1>&2 + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +if [ -z "$SCRIPT_PROFILE" ]; then + SCRIPT_PROFILE="local" + if [ ! -z $PGBR_HOST ]; then + SCRIPT_PROFILE="remote" + fi +fi + +if [ "$SCRIPT_PROFILE" != "local" ] && [ "$SCRIPT_PROFILE" != "remote" ]; then + usage +fi + +PYTHON="python3" +command -v $PYTHON >/dev/null 2>&1 || { PYTHON="python"; } +SSH_ARGS='-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no' +echo "SKIP_INIT = $SKIP_INIT" +echo "PLUGIN_PATH = $PLUGIN_PATH" +echo "SCRIPT_PROFILE = $SCRIPT_PROFILE" +echo "PGBIN = $PGBIN" +echo "PGDATABASE = $PGDATABASE" +echo "PGUNIXSOCKET = $PGUNIXSOCKET" +echo "PGUSER = $PGUSER" +echo "STANZA = $STANZA" +if [ ! -z "$PGBR_HOST" ]; then + echo "PGBR_USER = $PGBR_USER" + echo "PGBR_HOST = $PGBR_HOST" + PGBR_HOST=(`$PYTHON -c "print(' '.join($PGBR_HOST))"`) +fi +echo "PGBR_REPO_TYPE = $PGBR_REPO_TYPE" + +if [ ! -d $RESULTS_DIR ]; then + mkdir $RESULTS_DIR +fi + +## Tests +# Initiate backups (full, diff, incr) +if ! $SKIP_INIT; then + echo "...Initiate backups (full, diff, incr)" + if [ "$SCRIPT_PROFILE" = "local" ]; then + sudo -iu $PGUSER pgbackrest --stanza=$STANZA backup --type=full --repo1-retention-full=1 + sudo -iu $PGUSER pgbackrest --stanza=$STANZA backup --type=diff + sudo -iu $PGUSER pgbackrest --stanza=$STANZA backup --type=incr + else + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA backup --type=full --repo1-retention-full=1" + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA backup --type=diff" + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA backup --type=incr" + fi +fi + +# --list +echo "--list" +$PLUGIN_PATH/check_pgbackrest --list | tee $RESULTS_DIR/list.out + +# --version +echo "--version" +$PLUGIN_PATH/check_pgbackrest --version + +REPO="" +if [ "$PGBR_REPO_TYPE" = "multi" ]; then + REPO="--repo=1" + echo "...multi repo support, defaulting to repo1" +fi + +# --service=retention --retention-full +echo "--service=retention --retention-full" +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-full=1 --output=human +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-full=1 | cut -f1 -d"|" > $RESULTS_DIR/retention-full.out + +# --service=retention --retention-age +echo "--service=retention --retention-age" +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-age=1h --output=human +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-age=1h | cut -f1 -d"|" > $RESULTS_DIR/retention-age.out + +# --service=retention --retention-age-to-full +echo "--service=retention --retention-age-to-full" +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-age-to-full=1h --output=human +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-age-to-full=1h | cut -f1 -d"|" > $RESULTS_DIR/retention-age-to-full.out + +# --service=retention fail +echo "--service=retention fail" +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "SELECT pg_sleep(2);" > /dev/null 2>&1 +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-full=2 --retention-age=1s --retention-age-to-full=1s --output=human +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=retention --retention-full=2 --retention-age=1s --retention-age-to-full=1s | cut -f1 -d"|" > $RESULTS_DIR/retention-fail.out + +# --service=archives +echo "--service=archives" +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "SELECT pg_switch_xlog();" > /dev/null 2>&1 +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "SELECT pg_switch_wal();" > /dev/null 2>&1 +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "SELECT pg_sleep(1);" > /dev/null 2>&1 +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives --output=human +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives | cut -f1 -d"-" > $RESULTS_DIR/archives-ok.out + +# --service=archives --ignore-archived-before +echo "--service=archives --ignore-archived-before" +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "SELECT pg_sleep(2);" > /dev/null 2>&1 +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives --ignore-archived-before=1s > $RESULTS_DIR/archives-ignore-before.out + +# --service=archives --ignore-archived-after +echo "--service=archives --ignore-archived-after" +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives --ignore-archived-after=1h > $RESULTS_DIR/archives-ignore-after.out + +# --service=archives --latest-archive-age-alert +echo "--service=archives --latest-archive-age-alert" +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "SELECT pg_sleep(2);" > /dev/null 2>&1 +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives --latest-archive-age-alert=1h | cut -f1 -d"-" > $RESULTS_DIR/archives-age-alert-ok.out +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives --latest-archive-age-alert=1s --output=human +$PLUGIN_PATH/check_pgbackrest --prefix="sudo -u $PGUSER" --stanza=$STANZA $REPO --service=archives --latest-archive-age-alert=1s | cut -f1 -d"-" > $RESULTS_DIR/archives-age-alert-ko.out + +## Results +diff -abB expected/ $RESULTS_DIR/ > /tmp/regression.diffs +if [ $(wc -l < /tmp/regression.diffs) -gt 0 ]; then + cat /tmp/regression.diffs + exit 1 +fi +exit 0 \ No newline at end of file diff --git a/tests/playbooks/scripts/simulate-activity-basic.bash b/tests/playbooks/scripts/simulate-activity-basic.bash new file mode 100644 index 0000000..55973c2 --- /dev/null +++ b/tests/playbooks/scripts/simulate-activity-basic.bash @@ -0,0 +1,159 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +cd "$(dirname "$0")" + +usage() { + echo "Usage:" + echo " -s " + echo " -a " + echo " -p " +} + +while getopts "s:a:p:" o; do + case "${o}" in + s) + SCALE=${OPTARG} + ;; + a) + ACTIVITY_TIME=${OPTARG} + ;; + p) + SCRIPT_PROFILE=${OPTARG} + ;; + *) + usage 1>&2 + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +if [ -z "$SCRIPT_PROFILE" ]; then + SCRIPT_PROFILE="local" + if [ ! -z $PGBR_HOST ]; then + SCRIPT_PROFILE="remote" + fi +fi + +if [ "$SCRIPT_PROFILE" != "local" ] && [ "$SCRIPT_PROFILE" != "remote" ]; then + usage +fi + +PYTHON="python3" +command -v $PYTHON >/dev/null 2>&1 || { PYTHON="python"; } +SSH_ARGS='-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no' +echo "SCALE = $SCALE" +echo "ACTIVITY_TIME = $ACTIVITY_TIME seconds" +echo "SCRIPT_PROFILE = $SCRIPT_PROFILE" +echo "PGBIN = $PGBIN" +echo "PGDATABASE = $PGDATABASE" +echo "PGSVC = $PGSVC" +echo "PGUNIXSOCKET = $PGUNIXSOCKET" +echo "PGUSER = $PGUSER" +echo "STANZA = $STANZA" +if [ ! -z "$PGBR_HOST" ]; then + echo "PGBR_USER = $PGBR_USER" + echo "PGBR_HOST = $PGBR_HOST" + PGBR_HOST=(`$PYTHON -c "print(' '.join($PGBR_HOST))"`) +fi +if [ ! -z "$PGBR_STANDBIES" ]; then + echo "PGBR_STANDBIES = $PGBR_STANDBIES" + PGBR_STANDBIES=(`$PYTHON -c "print(' '.join($PGBR_STANDBIES))"`) +fi +echo "PGBR_REPO_TYPE = $PGBR_REPO_TYPE" +REPO="" +if [ "$PGBR_REPO_TYPE" = "multi" ]; then + REPO="--repo=1" + echo "...multi repo support, defaulting to repo1" +fi + +# run +echo "-------------------PROCESS START-------------------" +echo "--Create pgbench setup" +sudo -iu $PGUSER $PGBIN/dropdb -h $PGUNIXSOCKET --if-exists bench +sudo -iu $PGUSER $PGBIN/createdb -h $PGUNIXSOCKET bench +sudo -iu $PGUSER $PGBIN/pgbench -h $PGUNIXSOCKET -i -s $SCALE --quiet --foreign-keys bench + +echo "--Take a full backup" +if [ "$SCRIPT_PROFILE" = "local" ]; then + sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO --type=full backup +else + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA $REPO --type=full backup" +fi +sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO info + +echo "--Simulate $ACTIVITY_TIME sec activity" +sudo -iu $PGUSER $PGBIN/pgbench -h $PGUNIXSOCKET -T $ACTIVITY_TIME bench + +echo "--Take an incremental backup" +if [ "$SCRIPT_PROFILE" = "local" ]; then + sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO --type=incr backup +else + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA $REPO --type=incr backup" +fi +sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO info + +echo "--Simulate $ACTIVITY_TIME sec activity" +sudo -iu $PGUSER $PGBIN/pgbench -h $PGUNIXSOCKET -T $ACTIVITY_TIME bench + +echo "--Take a full backup to test the purge action" +if [ "$SCRIPT_PROFILE" = "local" ]; then + sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO --type=full backup +else + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA $REPO --type=full backup" +fi +sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO info + +echo "--Simulate $ACTIVITY_TIME sec activity" +sudo -iu $PGUSER $PGBIN/pgbench -h $PGUNIXSOCKET -T $ACTIVITY_TIME bench + +echo "--Create restore point RP1 and get latest pgbench history time" +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c "select pg_create_restore_point('RP1');" +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d bench -c 'SELECT max(mtime) FROM pgbench_history;' + +echo "--Simulate $ACTIVITY_TIME sec activity and get latest pgbench history time" +sudo -iu $PGUSER $PGBIN/pgbench -h $PGUNIXSOCKET -T $ACTIVITY_TIME bench +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d bench -c 'SELECT max(mtime) FROM pgbench_history;' + +echo "--Restore RP1 restore point and get latest pgbench history time" +systemctl stop $PGSVC +sudo -iu $PGUSER pgbackrest restore --stanza=$STANZA $REPO --delta --type=name --target=RP1 --target-action=promote +systemctl start $PGSVC +systemctl status $PGSVC + +echo "--Wait while pg_is_in_recovery" +while [ `sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -c 'SELECT pg_is_in_recovery();' -A -t` = "t" ] +do + echo "wait..." + sleep 5 +done +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d bench -c 'SELECT max(mtime) FROM pgbench_history;' + +echo "--Resync standby server(s)" +echo "----Take incremental backup" +if [ "$SCRIPT_PROFILE" = "local" ]; then + sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO --type=incr backup +else + sudo -iu $PGUSER ssh ${SSH_ARGS} ${PGBR_USER}@${PGBR_HOST} "pgbackrest --stanza=$STANZA $REPO --type=incr backup" +fi + +for i in "${PGBR_STANDBIES[@]}"; do + echo "----Restore on standby server - $i" + ssh ${SSH_ARGS} "$i" "systemctl stop $PGSVC" + ssh ${SSH_ARGS} "$i" "sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO --reset-pg2-host --type=standby restore" + ssh ${SSH_ARGS} "$i" "systemctl start $PGSVC" +done + +echo "----Wait until at least 1 standby is replicated" +while [ `sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -At -c "SELECT count(*) FROM pg_stat_replication;"` -lt 1 ] +do + echo "wait..." + sleep 5 +done +sudo -iu $PGUSER $PGBIN/psql -h $PGUNIXSOCKET -d $PGDATABASE -x -c "SELECT * FROM pg_stat_replication;" + +echo "--Simulate $ACTIVITY_TIME sec activity to get archives on different time-lines" +sudo -iu $PGUSER $PGBIN/pgbench -h $PGUNIXSOCKET -T $ACTIVITY_TIME bench +sudo -iu $PGUSER pgbackrest --stanza=$STANZA $REPO info +echo "-------------------PROCESS END-------------------" \ No newline at end of file diff --git a/tests/playbooks/templates/profile.fact.j2 b/tests/playbooks/templates/profile.fact.j2 new file mode 100644 index 0000000..bb3cad1 --- /dev/null +++ b/tests/playbooks/templates/profile.fact.j2 @@ -0,0 +1,18 @@ +[global] +cluster_name={{ cluster_name }} +pg_bin_path={{ pg_bin_path }} +pg_data={{ pg_data }} +pg_database={{ pg_database }} +pg_owner={{ pg_owner }} +pg_port={{ pg_port }} +pg_service={{ pg_service }} +pg_unix_socket={{ pg_unix_socket_directories[0] }} +pg_version={{ pg_version }} +pgbackrest_user={{ pgbackrest_user }} +pgbackrest_repo_type={{ pgbackrest_repo_type }} +{% if repository_server|length > 0 %} +pgbackrest_repo_host={{ repository_server }} +{% endif %} +{% if pgbackrest_standbies|length > 0 %} +pgbackrest_standbies={{ pgbackrest_standbies }} +{% endif %} diff --git a/tests/profile.d/c7epas.profile b/tests/profile.d/c7epas.profile new file mode 100644 index 0000000..b2a9e66 --- /dev/null +++ b/tests/profile.d/c7epas.profile @@ -0,0 +1,4 @@ +export CLNAME="c7epas" +export DBTYPE="EPAS" +export DBVERSION="13" +export DOCKERI="centos:7" diff --git a/tests/profile.d/c7pg.profile b/tests/profile.d/c7pg.profile new file mode 100644 index 0000000..48325ed --- /dev/null +++ b/tests/profile.d/c7pg.profile @@ -0,0 +1,4 @@ +export CLNAME="c7pg" +export DBTYPE="PG" +export DBVERSION="13" +export DOCKERI="centos:7" diff --git a/tests/profile.d/d10epas.profile b/tests/profile.d/d10epas.profile new file mode 100644 index 0000000..b73aa26 --- /dev/null +++ b/tests/profile.d/d10epas.profile @@ -0,0 +1,4 @@ +export CLNAME="d10epas" +export DBTYPE="EPAS" +export DBVERSION="13" +export DOCKERI="debian:10" diff --git a/tests/profile.d/d10pg.profile b/tests/profile.d/d10pg.profile new file mode 100644 index 0000000..033a6d4 --- /dev/null +++ b/tests/profile.d/d10pg.profile @@ -0,0 +1,4 @@ +export CLNAME="d10pg" +export DBTYPE="PG" +export DBVERSION="13" +export DOCKERI="debian:10" diff --git a/tests/profile.d/u20epas.profile b/tests/profile.d/u20epas.profile new file mode 100644 index 0000000..9e11d76 --- /dev/null +++ b/tests/profile.d/u20epas.profile @@ -0,0 +1,4 @@ +export CLNAME="u20epas" +export DBTYPE="EPAS" +export DBVERSION="13" +export DOCKERI="ubuntu:20.04" diff --git a/tests/profile.d/u20pg.profile b/tests/profile.d/u20pg.profile new file mode 100644 index 0000000..7b652f2 --- /dev/null +++ b/tests/profile.d/u20pg.profile @@ -0,0 +1,4 @@ +export CLNAME="u20pg" +export DBTYPE="PG" +export DBVERSION="13" +export DOCKERI="ubuntu:20.04" diff --git a/tests/profile.d/vagrant.profile b/tests/profile.d/vagrant.profile new file mode 100644 index 0000000..94f5ae9 --- /dev/null +++ b/tests/profile.d/vagrant.profile @@ -0,0 +1,7 @@ +# Vagrant settings +export CLPATH="/home/vagrant/clusters" +# Ansible settings +export ANSIBLE_ROLES_PATH=${ANSIBLE_ROLES_PATH:+$ANSIBLE_ROLES_PATH:}$(pwd)/roles +export ANSIBLE_HOST_KEY_CHECKING=False +export ANSIBLE_REMOTE_USER="root" +export EXTRA_VARS="" diff --git a/tests/roles/setup_check_pgbackrest/defaults/main.yml b/tests/roles/setup_check_pgbackrest/defaults/main.yml new file mode 100644 index 0000000..dbbe45d --- /dev/null +++ b/tests/roles/setup_check_pgbackrest/defaults/main.yml @@ -0,0 +1,15 @@ +--- +check_pgbackrest_build: false +deploy_icinga2: false +reschedule_check_icinga2: false + +build_packages: + common: + - git + Debian: + - libjson-perl + - libdata-dump-perl + RedHat: + - nagios-plugins + - perl-JSON + - perl-Data-Dumper \ No newline at end of file diff --git a/tests/roles/setup_check_pgbackrest/tasks/build.yml b/tests/roles/setup_check_pgbackrest/tasks/build.yml new file mode 100644 index 0000000..e4114a9 --- /dev/null +++ b/tests/roles/setup_check_pgbackrest/tasks/build.yml @@ -0,0 +1,43 @@ +--- +- name: Install build requirements + package: + name: > + {{ query('flattened', package_lists) }} + state: latest + vars: + package_lists: + - "{{ build_packages['common'] }}" + - "{{ build_packages[ansible_os_family] }}" + +- name: Check if development file exists on controller + local_action: stat path="/check_pgbackrest/check_pgbackrest" + register: dev_file + +- name: Ensure src directory exists + file: state=directory path="{{ check_pgbackrest_src_dir }}" + when: not dev_file.stat.exists | bool + +- name: Fetch check_pgbackrest from Github + git: + repo: "https://github.com/pgstef/check_pgbackrest" + dest: "{{ check_pgbackrest_src_dir }}" + version: "master" + depth: 1 + accept_hostkey: yes + when: not dev_file.stat.exists | bool + +- name: Install check_pgbackrest + copy: + src: "{{ check_pgbackrest_src_dir }}/check_pgbackrest" + remote_src: yes + dest: /usr/bin/check_pgbackrest + mode: '0755' + when: not dev_file.stat.exists | bool + +- name: Install development check_pgbackrest + copy: + src: "/check_pgbackrest/check_pgbackrest" + remote_src: no + dest: /usr/bin/check_pgbackrest + mode: '0755' + when: dev_file.stat.exists | bool \ No newline at end of file diff --git a/tests/roles/setup_check_pgbackrest/tasks/icinga2-check.yml b/tests/roles/setup_check_pgbackrest/tasks/icinga2-check.yml new file mode 100644 index 0000000..c8a0d1f --- /dev/null +++ b/tests/roles/setup_check_pgbackrest/tasks/icinga2-check.yml @@ -0,0 +1,48 @@ +--- +- set_fact: + icinga_api_url: "https://localhost:5665/v1" + icinga_api_user: "icinga2-director" + icinga_api_pass: "anyPassWord" + when: "'icinga2' in group_names" + +- name: Reschedule-check on all check_pgbackrest services + uri: + url: "{{ icinga_api_url }}/actions/reschedule-check" + validate_certs: no + user: "{{ icinga_api_user }}" + password: "{{ icinga_api_pass }}" + method: POST + headers: + Accept: "application/json" + body_format: json + body: '{ "type": "Service", "filter": "match(pattern,service.name)", "filter_vars": { "pattern": "pgbackrest*" } }' + when: > + 'icinga2' in group_names and reschedule_check_icinga2 + +- name: Get services status + uri: + url: "{{ icinga_api_url }}/objects/services" + validate_certs: no + user: "{{ icinga_api_user }}" + password: "{{ icinga_api_pass }}" + method: GET + return_content: yes + headers: + Content-Type: "application/json" + body_format: json + body: '{ "filter": "match(pattern,service.name)", "filter_vars": { "pattern": "pgbackrest*" } }' + register: icinga2_services_status + when: "'icinga2' in group_names" + +- name: Verify services status + debug: + msg: + - "Check {{ item.attrs.host_name }} - {{ item.attrs.name }}" + - " State: {{ item.attrs.state }}" + - " Last check time: {{ '%Y-%m-%d %H:%M:%S %Z' | strftime(item.attrs.last_check) }}" + - " Output: {{ item.attrs.last_check_result.output }}" + failed_when: "item.attrs.state != 0" + loop: "{{ icinga2_services_status.json.results | sort(attribute='name') }}" + loop_control: + label: "{{ item.name }}" + when: "'icinga2' in group_names" \ No newline at end of file diff --git a/tests/roles/setup_check_pgbackrest/tasks/icinga2-config.yml b/tests/roles/setup_check_pgbackrest/tasks/icinga2-config.yml new file mode 100644 index 0000000..1ff3c2e --- /dev/null +++ b/tests/roles/setup_check_pgbackrest/tasks/icinga2-config.yml @@ -0,0 +1,268 @@ +--- +# -------------------- +# SSH connection setup +# -------------------- +- name: Generate Icinga2 SSH keys + community.crypto.openssh_keypair: + path: "{{ cluster_dir }}/keys/id_icinga2" + delegate_to: localhost + when: "'icinga2' in group_names" + +- name: Ensure that .ssh exists on Icinga2 server + file: + path: "~nagios/.ssh" + state: directory + mode: '0700' + become_user: "nagios" + become: yes + when: "'icinga2' in group_names" + +- name: Install keypair on Icinga2 server + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + with_items: + - src: "{{ cluster_dir }}/keys/id_icinga2" + dest: "~nagios/.ssh/id_rsa" + mode: '0600' + - src: "{{ cluster_dir }}/keys/id_icinga2.pub" + dest: "~nagios/.ssh/id_rsa.pub" + mode: '0640' + become_user: "nagios" + become: yes + when: "'icinga2' in group_names" + +- name: Setup user accessed_by_ssh on db and repo hosts + user: + name: accessed_by_ssh + groups: wheel + append: yes + when: > + ( inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers ) + and ansible_os_family == 'RedHat' + +- name: Setup user accessed_by_ssh on db and repo hosts + user: + name: accessed_by_ssh + groups: sudo + append: yes + when: > + ( inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers ) + and ansible_os_family == 'Debian' + +- name: Add user to sudoers file on db and repo hosts + lineinfile: + path: /etc/sudoers + regexp: '^accessed_by_ssh' + line: 'accessed_by_ssh ALL=(ALL) NOPASSWD:ALL' + validate: 'visudo -cf %s' + when: inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers + +- name: Authorise SSH connection on db and repo hosts + authorized_key: + user: accessed_by_ssh + key: "{{ lookup('file', cluster_dir+'/keys/id_icinga2.pub') }}" + when: inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers + +- name: Test SSH connection from Icinga2 server to db hosts + shell: "/usr/bin/ssh {{ssh_args}} {{ user }}@{{ host }} uname -a" + vars: + host: "{{ hostvars[item].private_ip }}" + user: "accessed_by_ssh" + ssh_args: "-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no" + loop: "{{ pgbackrest_servers }}" + become_user: "nagios" + become: yes + when: "'icinga2' in group_names" + +- name: Test SSH connection from Icinga2 server to repo host + shell: "/usr/bin/ssh {{ssh_args}} {{ user }}@{{ host }} uname -a" + vars: + host: "{{ hostvars[item].private_ip }}" + user: "accessed_by_ssh" + ssh_args: "-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no" + loop: "{{ repository_server }}" + become_user: "nagios" + become: yes + when: "'icinga2' in group_names" + +# ------------------------------------ +# Configure Icinga2 hosts and services +# ------------------------------------ +- set_fact: + icinga_url: "http://127.0.0.1/icingaweb2" + icinga_user: "icingaadmin" + icinga_pass: "icinga" + when: "'icinga2' in group_names" + +- name: Create Icinga2 host template + t_systems_mms.icinga_director.icinga_host_template: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: host-template + check_command: hostalive + when: "'icinga2' in group_names" + +- name: Create Icinga2 service template + t_systems_mms.icinga_director.icinga_service_template: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: service-template + max_check_attempts: "5" + check_interval: "1m" + retry_interval: "30s" + when: "'icinga2' in group_names" + +- name: Add db hosts to Icinga2 + t_systems_mms.icinga_director.icinga_host: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "{{ item }}" + address: "{{ hostvars[item].private_ip }}" + imports: + - "host-template" + vars: + os: "Linux" + loop: "{{ pgbackrest_servers }}" + when: "'icinga2' in group_names" + +- name: Add repo hosts to Icinga2 + t_systems_mms.icinga_director.icinga_host: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "{{ item }}" + address: "{{ hostvars[item].private_ip }}" + imports: + - "host-template" + vars: + os: "Linux" + loop: "{{ repository_server }}" + when: "'icinga2' in group_names" + +- name: Set default repo when multiple repositories are defined + set_fact: + repo_option: "--repo=1" + when: "pgbackrest_repo_type is defined and pgbackrest_repo_type == 'multi'" + +- name: Create Icinga2 check retention command + t_systems_mms.icinga_director.icinga_command: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "by_ssh_pgbackrest_retention" + imports: + - "by_ssh" + vars: + by_ssh_command: "check_pgbackrest --stanza=$stanza$ --service=retention --retention-full=$retention_full$ --prefix=\"$prefix$\" {{ repo_option | default(None) }}" + when: "'icinga2' in group_names" + +- name: Create Icinga2 check archives command + t_systems_mms.icinga_director.icinga_command: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "by_ssh_pgbackrest_archives" + imports: + - "by_ssh" + vars: + by_ssh_command: "check_pgbackrest --stanza=$stanza$ --service=archives --prefix=\"$prefix$\" {{ repo_option | default(None) }}" + when: "'icinga2' in group_names" + +- name: Create Icinga2 check retention services for db hosts + t_systems_mms.icinga_director.icinga_service: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "pgbackrest_retention" + imports: + - "service-template" + check_command: "by_ssh_pgbackrest_retention" + host: "{{ item }}" + vars: + by_ssh_logname: "accessed_by_ssh" + stanza: "{{ cluster_name }}" + retention_full: "{{ hostvars[item].pgbackrest_repo_retention_full }}" + prefix: "sudo -u {{ hostvars[item].pg_owner }}" + loop: "{{ pgbackrest_servers }}" + when: "'icinga2' in group_names" + +- name: Create Icinga2 check retention services for repo host + t_systems_mms.icinga_director.icinga_service: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "pgbackrest_retention" + imports: + - "service-template" + check_command: "by_ssh_pgbackrest_retention" + host: "{{ item }}" + vars: + by_ssh_logname: "accessed_by_ssh" + stanza: "{{ cluster_name }}" + retention_full: "{{ hostvars[item].pgbackrest_repo_retention_full }}" + prefix: "sudo -u {{ hostvars[item].pgbackrest_user }}" + loop: "{{ repository_server }}" + when: "'icinga2' in group_names" + +- name: Create Icinga2 check archives services for db hosts + t_systems_mms.icinga_director.icinga_service: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "pgbackrest_archives" + imports: + - "service-template" + check_command: "by_ssh_pgbackrest_archives" + host: "{{ item }}" + vars: + by_ssh_logname: "accessed_by_ssh" + stanza: "{{ cluster_name }}" + prefix: "sudo -u {{ hostvars[item].pg_owner }}" + loop: "{{ pgbackrest_servers }}" + when: "'icinga2' in group_names" + +- name: Create Icinga2 check retention services for repo host + t_systems_mms.icinga_director.icinga_service: + state: present + url: "{{ icinga_url }}" + url_username: "{{ icinga_user }}" + url_password: "{{ icinga_pass }}" + object_name: "pgbackrest_archives" + imports: + - "service-template" + check_command: "by_ssh_pgbackrest_archives" + host: "{{ item }}" + vars: + by_ssh_logname: "accessed_by_ssh" + stanza: "{{ cluster_name }}" + prefix: "sudo -u {{ hostvars[item].pgbackrest_user }}" + loop: "{{ repository_server }}" + when: "'icinga2' in group_names" + +- name: Deploy Icinga2 config + uri: + url: "{{ icinga_url }}/director/config/deploy" + user: "{{ icinga_user }}" + password: "{{ icinga_pass }}" + method: POST + headers: + Accept: "application/json" + when: "'icinga2' in group_names" + +- name: Check Icinga2 services + include_tasks: icinga2-check.yml + when: "'icinga2' in group_names" \ No newline at end of file diff --git a/tests/roles/setup_check_pgbackrest/tasks/main.yml b/tests/roles/setup_check_pgbackrest/tasks/main.yml new file mode 100644 index 0000000..538661e --- /dev/null +++ b/tests/roles/setup_check_pgbackrest/tasks/main.yml @@ -0,0 +1,63 @@ +--- +- name: Create a list of primary and standby instances using pgbackrest + set_fact: + pgbackrest_servers: "{{ + pgbackrest_servers | default([]) | union([ item ]) + }}" + when: "hostvars[item].pgbackrest == true" + loop: + "{{ groups['primary'] | list | union (groups['standby'] | default([]) | list) }}" + loop_control: + label: >- + {{ item }} + +- name: Identify repository server + set_fact: + repository_server: "{{ groups['pgbackrest_repo_host']| default([]) | list }}" + +- name: Install check_pgbackrest package + package: + name: + - check-pgbackrest + state: latest + when: > + (inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers) + and not check_pgbackrest_build | bool and ansible_os_family == 'Debian' + +- name: Install check_pgbackrest package + package: + name: + - nagios-plugins-pgbackrest + state: latest + when: > + (inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers) + and not check_pgbackrest_build | bool and ansible_os_family == 'RedHat' + +- name: Create a symbolic link + file: + src: /usr/lib64/nagios/plugins/check_pgbackrest + dest: /usr/bin/check_pgbackrest + state: link + when: > + (inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers) + and not check_pgbackrest_build | bool and ansible_os_family == 'RedHat' + +- name: Build check_pgbackrest from sources + include_tasks: build.yml + vars: + check_pgbackrest_src_dir: /opt/check_pgbackrest/src + when: > + (inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers) + and check_pgbackrest_build | bool + +- shell: check_pgbackrest --version | cut -f1 -d"," | awk '{print $3}' + register: version + when: inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers + +- name: check_pgbackrest installed version + debug: var=version.stdout + when: inventory_hostname in repository_server or inventory_hostname in pgbackrest_servers + +- name: Deploy Icinga2 check services + include_tasks: icinga2-config.yml + when: deploy_icinga2 | bool \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/defaults/main.yml b/tests/roles/setup_pgbackrest/defaults/main.yml new file mode 100644 index 0000000..f58bd91 --- /dev/null +++ b/tests/roles/setup_pgbackrest/defaults/main.yml @@ -0,0 +1,37 @@ +--- +pgbackrest_build: false +pgbackrest_configuration_file: "/etc/pgbackrest.conf" +pgbackrest_excpected_release: "" +pgbackrest_force_backup: false +pgbackrest_git_url: "https://github.com/pgbackrest/pgbackrest.git" +pgbackrest_git_branch: "master" +pgbackrest_repo_path: "/var/lib/pgbackrest" +pgbackrest_repo_retention_full: 1 +pgbackrest_repo_type: "posix" +pgbackrest_repo_s3_endpoint: "{{ cluster_name }}-minio" +pgbackrest_repo_azure_host: "{{ cluster_name }}-azurite" +pgbackrest_repo_cipher_pass: "it3BF2WqbFCNbY4KkSbvUsRybHyJkvcmQYAOB46x3qXfrc0EKqGGClsh42Q1g91O" +pgbackrest_user: "pgbackrest" + +build_packages: + common: + - git + - make + - gcc + Debian: + - libpq-dev + - libssl-dev + - libxml2-dev + - pkg-config + - liblz4-dev + - libzstd-dev + - libbz2-dev + - libz-dev + - libyaml-dev + RedHat: + - openssl-devel + - libxml2-devel + - lz4-devel + - libzstd-devel + - bzip2-devel + - libyaml-devel \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/backup.yml b/tests/roles/setup_pgbackrest/tasks/backup.yml new file mode 100644 index 0000000..300a65f --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/backup.yml @@ -0,0 +1,66 @@ +--- +- name: Take full backup on repository server + command: > + pgbackrest backup --type=full --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server and pgbackrest_force_backup + +- name: Take diff backup on repository server + command: > + pgbackrest backup --type=diff --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server and pgbackrest_force_backup + +- name: Take incr backup on repository server + command: > + pgbackrest backup --type=incr --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server and pgbackrest_force_backup + +- name: Take incr backup from standby on repository server + command: > + pgbackrest backup --type=incr --backup-standby --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server and pgbackrest_force_backup and (pgbackrest_servers|length > 1) + +- name: Take full backup on primary server + command: > + pgbackrest backup --type=full --stanza="{{ cluster_name }}" + become_user: "{{ postgres_user }}" + become: yes + when: pgbackrest_force_backup and (not repository_server|length > 0) and + (inventory_hostname in pgbackrest_servers) and + ('primary' in group_names) + +- name: Take diff backup on primary server + command: > + pgbackrest backup --type=diff --stanza="{{ cluster_name }}" + become_user: "{{ postgres_user }}" + become: yes + when: pgbackrest_force_backup and (not repository_server|length > 0) and + (inventory_hostname in pgbackrest_servers) and + ('primary' in group_names) + +- name: Take incr backup on primary server + command: > + pgbackrest backup --type=incr --stanza="{{ cluster_name }}" + become_user: "{{ postgres_user }}" + become: yes + when: pgbackrest_force_backup and (not repository_server|length > 0) and + (inventory_hostname in pgbackrest_servers) and + ('primary' in group_names) + +- name: Take backup on standby from primary server using ssh + command: "/usr/bin/ssh {{ host }} pgbackrest backup --type=incr --backup-standby --stanza={{ cluster_name }}" + vars: + host: "{{ hostvars[item].private_ip }}" + loop: "{{ pgbackrest_standbies }}" + become_user: "{{ postgres_user }}" + become: yes + when: pgbackrest_force_backup and (not repository_server|length > 0) and + (inventory_hostname in pgbackrest_servers) and + ('primary' in group_names) \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/build.yml b/tests/roles/setup_pgbackrest/tasks/build.yml new file mode 100644 index 0000000..0254d4e --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/build.yml @@ -0,0 +1,67 @@ +--- +- name: Install build requirements + package: + name: > + {{ query('flattened', package_lists) }} + state: latest + vars: + package_lists: + - "{{ build_packages['common'] }}" + - "{{ build_packages[ansible_os_family] }}" + +- name: Install PG devel package + package: + name: "postgresql-devel" + state: latest + when: pg_type == 'PG' and ansible_os_family == 'RedHat' + +- name: Install EPAS devel package + package: + name: "edb-as{{ pg_version }}-server-devel" + state: latest + when: pg_type == 'EPAS' and ansible_os_family == 'RedHat' + +- name: Ensure src directory exists + file: state=directory path="{{ pgbackrest_src_dir }}" + +- name: Fetch pgbackrest from {{ pgbackrest_git_url }}, {{ pgbackrest_git_branch }} + git: + repo: "{{ pgbackrest_git_url }}" + dest: "{{ pgbackrest_src_dir }}" + version: "{{ pgbackrest_git_branch }}" + depth: 1 + accept_hostkey: yes + +- name: Fetch currently checked-out branch in {{ pgbackrest_src_dir }} + shell: git branch | sed -n 's/^\* //p' + args: + chdir: "{{ pgbackrest_src_dir }}" + register: git_branch + +- name: pgbackrest source branch to build + debug: var=git_branch.stdout + +- name: Remove old build directory + file: state=absent path="{{ pgbackrest_build_dir }}" force=yes + +- name: Ensure build directory exists + file: state=directory path="{{ pgbackrest_build_dir }}" + +- set_fact: + cppflags: "CPPFLAGS='-I /usr/edb/as{{ pg_version }}/include' LDFLAGS='-L/usr/edb/as{{ pg_version }}/lib'" + when: pg_type == 'EPAS' + +- name: Configure pgbackrest + shell: "{{ pgbackrest_src_dir }}/src/configure {{ cppflags | default('', true) }} --prefix={{ pgbackrest_build_prefix }} --bindir={{ pgbackrest_build_prefix }}/bin" + args: + chdir: "{{ pgbackrest_build_dir }}" + +- name: Build pgbackrest + shell: "make" + args: + chdir: "{{ pgbackrest_build_dir }}" + +- name: Install pgbackrest + shell: "make install" + args: + chdir: "{{ pgbackrest_build_dir }}" \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/client.yml b/tests/roles/setup_pgbackrest/tasks/client.yml new file mode 100644 index 0000000..a59832d --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/client.yml @@ -0,0 +1,27 @@ +--- +- name: Build configuration file {{ pgbackrest_configuration_file }} + template: + src: "pgbackrest-dbserver.conf.j2" + dest: "{{ pgbackrest_configuration_file }}" + owner: "{{ postgres_user }}" + group: "{{ postgres_user }}" + mode: 0640 + become: true + register: pgbackrest_config + +- name: Record if a new backup is needed + set_fact: + pgbackrest_force_backup: true + when: pgbackrest_config.changed + +- name: Ensure pgbackrest directories exist with the right ownership and permissions + file: + name: "{{ item }}" + state: directory + owner: "{{ postgres_user }}" + group: "{{ postgres_user }}" + mode: 0770 + loop: + - /var/log/pgbackrest + - /var/spool/pgbackrest + become: yes \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/create_user.yml b/tests/roles/setup_pgbackrest/tasks/create_user.yml new file mode 100644 index 0000000..19dfa9b --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/create_user.yml @@ -0,0 +1,25 @@ +--- +- name: Ensure pgbackrest group exists + group: + name: "{{ pgbackrest_user }}" + state: present + become: yes + +- name: Ensure pgbackrest system user {{ pgbackrest_user }} exists + user: + name: "{{ pgbackrest_user }}" + group: "{{ pgbackrest_user }}" + state: present + become: yes + +- name: Ensure pgbackrest directories exist with the right ownership and permissions + file: + name: "{{ item }}" + state: directory + owner: "{{ pgbackrest_user }}" + group: "{{ pgbackrest_user }}" + mode: 0770 + loop: + - /var/log/pgbackrest + - "{{ pgbackrest_repo_path }}" + become: yes \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/info.yml b/tests/roles/setup_pgbackrest/tasks/info.yml new file mode 100644 index 0000000..9a7e069 --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/info.yml @@ -0,0 +1,18 @@ +--- +- name: Info command on repository server + command: > + pgbackrest info --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server + register: info + +- name: Info command on database server + command: > + pgbackrest info --stanza="{{ cluster_name }}" + become_user: "{{ postgres_user }}" + become: yes + when: inventory_hostname in pgbackrest_servers + register: info + +- debug: var=info.stdout_lines \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/main.yml b/tests/roles/setup_pgbackrest/tasks/main.yml new file mode 100644 index 0000000..d765987 --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/main.yml @@ -0,0 +1,96 @@ +--- +- name: Create a list of primary and standby instances using pgbackrest + set_fact: + pgbackrest_servers: "{{ + pgbackrest_servers | default([]) | union([ item ]) + }}" + when: "hostvars[item].pgbackrest == true" + loop: + "{{ groups['primary'] | list | union (groups['standby'] | default([]) | list) }}" + loop_control: + label: >- + {{ item }} + +- name: Create a list of standby instances using pgbackrest + set_fact: + pgbackrest_standbies: "{{ + pgbackrest_standbies | default([]) | union([ item ]) + }}" + when: "hostvars[item].pgbackrest == true" + loop: + "{{ groups['standby'] | default([]) | list }}" + loop_control: + label: >- + {{ item }} + +- name: Identify repository server + set_fact: + repository_server: "{{ groups['pgbackrest_repo_host']| default([]) | list }}" + +- set_fact: + postgres_user: "{{ pg_owner }}" + when: inventory_hostname in pgbackrest_servers + +- set_fact: + pgbackrest_user: "{{ pgbackrest_user }}" + pgbackrest_repo_retention_full: "{{ pgbackrest_repo_retention_full }}" + pgbackrest_repo_type: "{{ pgbackrest_repo_type }}" + +- name: Ensure repository type is valid + assert: + msg: "Unsupported repository type: '{{ pgbackrest_repo_type }}'" + that: + - pgbackrest_repo_type in _available_repo_types + vars: + _available_repo_types: + - 'azure' + - 'multi' + - 'posix' + - 's3' + +- name: Build pgbackrest from sources + include_tasks: build.yml + vars: + pgbackrest_src_dir: /opt/pgbackrest/src + pgbackrest_build_dir: /opt/pgbackrest/build + pgbackrest_build_prefix: /usr + when: pgbackrest_build | bool + +- name: Install pgbackrest package + package: + name: + - pgbackrest + state: latest + when: not pgbackrest_build | bool + +- shell: pgbackrest version | awk '{print $2}' + register: version + +- name: pgbackrest installed version + debug: var=version.stdout + +- name: Ensure the pgbackrest installed version match {{ pgbackrest_excpected_release }} + assert: + that: + - "'{{ pgbackrest_excpected_release }}' in version.stdout" + +- include_tasks: server.yml + when: inventory_hostname in repository_server + +- include_tasks: ssh_setup.yml + +- include_tasks: client.yml + when: inventory_hostname in pgbackrest_servers + +- name: Configure archive_command + include_role: + name: edb_devops.edb_postgres.manage_dbserver + vars: + pg_postgres_conf_params: + - name: archive_command + value: "pgbackrest --stanza={{ cluster_name }} --log-level-console=debug archive-push %p" + when: inventory_hostname in pgbackrest_servers + +- include_tasks: stanza-create.yml +- include_tasks: backup.yml +- include_tasks: info.yml \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/server.yml b/tests/roles/setup_pgbackrest/tasks/server.yml new file mode 100644 index 0000000..fd6cf13 --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/server.yml @@ -0,0 +1,17 @@ +--- +- include_tasks: create_user.yml + +- name: Build configuration file {{ pgbackrest_configuration_file }} + template: + src: "pgbackrest-repository.conf.j2" + dest: "{{ pgbackrest_configuration_file }}" + owner: "{{ pgbackrest_user }}" + group: "{{ pgbackrest_user }}" + mode: 0640 + become: true + register: pgbackrest_config + +- name: Record if a new backup is needed + set_fact: + pgbackrest_force_backup: true + when: pgbackrest_config.changed \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/ssh_setup.yml b/tests/roles/setup_pgbackrest/tasks/ssh_setup.yml new file mode 100644 index 0000000..1a8bba0 --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/ssh_setup.yml @@ -0,0 +1,118 @@ +--- +- name: Ensure the localhost keys directory exists + file: + state: directory + path: "{{ cluster_dir }}/keys" + delegate_to: localhost + +- name: Generate {{ pgbackrest_user }} SSH keys + community.crypto.openssh_keypair: + path: "{{ cluster_dir }}/keys/id_pgbackrest" + delegate_to: localhost + when: inventory_hostname in repository_server + +- name: Generate db hosts SSH keys + community.crypto.openssh_keypair: + path: "{{ cluster_dir }}/keys/id_postgres" + delegate_to: localhost + when: inventory_hostname in pgbackrest_servers + +- name: Authorise SSH connection from {{ pgbackrest_user }} + authorized_key: + user: "{{ postgres_user }}" + key: "{{ lookup('file', cluster_dir+'/keys/id_pgbackrest.pub') }}" + when: inventory_hostname in pgbackrest_servers and repository_server|length > 0 + +- name: Authorise SSH connection between db hosts + authorized_key: + user: "{{ postgres_user }}" + key: "{{ lookup('file', cluster_dir+'/keys/id_postgres.pub') }}" + when: inventory_hostname in pgbackrest_servers + +- name: Authorise SSH connection to {{ pgbackrest_user }} + authorized_key: + user: "{{ pgbackrest_user }}" + key: "{{ lookup('file', cluster_dir+'/keys/id_postgres.pub') }}" + when: inventory_hostname in repository_server + +- name: Ensure that .ssh exists on db hosts + file: + path: "~{{ postgres_user }}/.ssh" + state: directory + mode: '0700' + become_user: "{{ postgres_user }}" + become: yes + when: inventory_hostname in pgbackrest_servers + +- name: Install keypair on db hosts + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + with_items: + - src: "{{ cluster_dir }}/keys/id_postgres" + dest: "~{{ postgres_user }}/.ssh/id_rsa" + mode: '0600' + - src: "{{ cluster_dir }}/keys/id_postgres.pub" + dest: "~{{ postgres_user }}/.ssh/id_rsa.pub" + mode: '0640' + become_user: "{{ postgres_user }}" + become: yes + when: inventory_hostname in pgbackrest_servers + +- name: Ensure that .ssh exists on repo host + file: + path: "~{{ pgbackrest_user }}/.ssh" + state: directory + mode: '0700' + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server + +- name: Install keypair on repo host + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + with_items: + - src: "{{ cluster_dir }}/keys/id_pgbackrest" + dest: "~{{ pgbackrest_user }}/.ssh/id_rsa" + mode: '0600' + - src: "{{ cluster_dir }}/keys/id_pgbackrest.pub" + dest: "~{{ pgbackrest_user }}/.ssh/id_rsa.pub" + mode: '0640' + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server + +- name: Test SSH connection from repo host + shell: "/usr/bin/ssh {{ssh_args}} {{ user }}@{{ host }} uname -a" + vars: + host: "{{ hostvars[item].private_ip }}" + user: "{{ hostvars[item].pg_owner }}" + ssh_args: "-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no" + loop: "{{ pgbackrest_servers }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server + +- name: Test SSH connection to repo host + shell: "/usr/bin/ssh {{ssh_args}} {{ user }}@{{ host }} uname -a" + vars: + host: "{{ hostvars[pgbackrest_repo_host].private_ip }}" + user: "{{ pgbackrest_user }}" + ssh_args: "-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no" + become_user: "{{ postgres_user }}" + become: yes + when: inventory_hostname in pgbackrest_servers and repository_server|length > 0 + +- name: Test SSH connection to db hosts + shell: "/usr/bin/ssh {{ssh_args}} {{ user }}@{{ host }} uname -a" + vars: + host: "{{ hostvars[item].private_ip }}" + user: "{{ hostvars[item].pg_owner }}" + ssh_args: "-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no" + loop: "{{ pgbackrest_servers }}" + become_user: "{{ postgres_user }}" + become: yes + when: inventory_hostname in pgbackrest_servers \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/tasks/stanza-create.yml b/tests/roles/setup_pgbackrest/tasks/stanza-create.yml new file mode 100644 index 0000000..653624f --- /dev/null +++ b/tests/roles/setup_pgbackrest/tasks/stanza-create.yml @@ -0,0 +1,28 @@ +--- +- name: Initialise the stanza on repository server + command: > + pgbackrest stanza-create --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server + +- name: check cluster configuration on repository server + command: > + pgbackrest check --stanza="{{ cluster_name }}" + become_user: "{{ pgbackrest_user }}" + become: yes + when: inventory_hostname in repository_server + +- name: Initialise the stanza on primary server + command: > + pgbackrest stanza-create --stanza="{{ cluster_name }}" + become_user: "{{ postgres_user }}" + become: yes + when: (not repository_server|length > 0) and (inventory_hostname in pgbackrest_servers) and ('primary' in group_names) + +- name: check cluster configuration on primary server + command: > + pgbackrest check --stanza="{{ cluster_name }}" + become_user: "{{ postgres_user }}" + become: yes + when: (not repository_server|length > 0) and (inventory_hostname in pgbackrest_servers) and ('primary' in group_names) \ No newline at end of file diff --git a/tests/roles/setup_pgbackrest/templates/pgbackrest-dbserver.conf.j2 b/tests/roles/setup_pgbackrest/templates/pgbackrest-dbserver.conf.j2 new file mode 100644 index 0000000..d669892 --- /dev/null +++ b/tests/roles/setup_pgbackrest/templates/pgbackrest-dbserver.conf.j2 @@ -0,0 +1,83 @@ +[global] +{% if repository_server|length > 0 %} +repo1-host={{ hostvars[pgbackrest_repo_host].private_ip }} +repo1-host-user={{ pgbackrest_user }} +{% if pgbackrest_repo_type == "multi" %} +repo2-host={{ hostvars[pgbackrest_repo_host].private_ip }} +repo2-host-user={{ pgbackrest_user }} +{% endif %} +{% elif pgbackrest_repo_type == "s3" %} +repo1-type=s3 +repo1-path=/repo1 +repo1-s3-endpoint={{ pgbackrest_repo_s3_endpoint }} +repo1-s3-region=eu-west-2 +repo1-s3-bucket=bucket +repo1-s3-key=accessKey +repo1-s3-key-secret=superSECRETkey +repo1-s3-uri-style=path +repo1-storage-verify-tls=n +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +start-fast=y +{% elif pgbackrest_repo_type == "azure" %} +repo1-type=azure +repo1-path=/repo1 +repo1-storage-host={{ pgbackrest_repo_azure_host }} +repo1-azure-account=pgbackrest +repo1-azure-key=aF49wnZP +repo1-azure-container=container +repo1-storage-verify-tls=n +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +start-fast=y +{% elif pgbackrest_repo_type == "multi" %} +repo1-type=s3 +repo1-path=/repo1 +repo1-s3-endpoint={{ pgbackrest_repo_s3_endpoint }} +repo1-s3-region=eu-west-2 +repo1-s3-bucket=bucket +repo1-s3-key=accessKey +repo1-s3-key-secret=superSECRETkey +repo1-s3-uri-style=path +repo1-storage-verify-tls=n +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +repo2-type=azure +repo2-path=/repo2 +repo2-storage-host={{ pgbackrest_repo_azure_host }} +repo2-azure-account=pgbackrest +repo2-azure-key=aF49wnZP +repo2-azure-container=container +repo2-storage-verify-tls=n +repo2-retention-full={{ pgbackrest_repo_retention_full }} +repo2-cipher-type=aes-256-cbc +repo2-cipher-pass={{ pgbackrest_repo_cipher_pass }} +start-fast=y +{% else %} +repo1-type=posix +repo1-path={{ pgbackrest_repo_path }} +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +start-fast=y +{% endif %} +log-level-console=warn +log-level-file=info +delta=y +process-max=2 + +[{{ cluster_name }}] +pg1-path={{ pg_data }} +pg1-user={{ postgres_user }} +pg1-port={{ pg_port }} +pg1-socket-path={{ pg_unix_socket_directories[0] }} +{% if 'standby' in group_names %} +backup-standby=y +pg2-host={{ upstream_node_private_ip }} +pg2-host-user={{ postgres_user }} +pg2-path={{ pg_data }} +recovery-option=primary_conninfo=host={{ upstream_node_private_ip }} user={{ pg_replication_user }} port={{ pg_port }} application_name={{ inventory_hostname }} +{% endif %} diff --git a/tests/roles/setup_pgbackrest/templates/pgbackrest-repository.conf.j2 b/tests/roles/setup_pgbackrest/templates/pgbackrest-repository.conf.j2 new file mode 100644 index 0000000..cbe5cc2 --- /dev/null +++ b/tests/roles/setup_pgbackrest/templates/pgbackrest-repository.conf.j2 @@ -0,0 +1,69 @@ +[global] +{% if pgbackrest_repo_type == "s3" %} +repo1-type=s3 +repo1-path=/repo1 +repo1-s3-endpoint={{ pgbackrest_repo_s3_endpoint }} +repo1-s3-region=eu-west-2 +repo1-s3-bucket=bucket +repo1-s3-key=accessKey +repo1-s3-key-secret=superSECRETkey +repo1-s3-uri-style=path +repo1-storage-verify-tls=n +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +{% elif pgbackrest_repo_type == "azure" %} +repo1-type=azure +repo1-path=/repo1 +repo1-storage-host={{ pgbackrest_repo_azure_host }} +repo1-azure-account=pgbackrest +repo1-azure-key=aF49wnZP +repo1-azure-container=container +repo1-storage-verify-tls=n +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +{% elif pgbackrest_repo_type == "multi" %} +repo1-type=s3 +repo1-path=/repo1 +repo1-s3-endpoint={{ pgbackrest_repo_s3_endpoint }} +repo1-s3-region=eu-west-2 +repo1-s3-bucket=bucket +repo1-s3-key=accessKey +repo1-s3-key-secret=superSECRETkey +repo1-s3-uri-style=path +repo1-storage-verify-tls=n +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +repo2-type=azure +repo2-path=/repo2 +repo2-storage-host={{ pgbackrest_repo_azure_host }} +repo2-azure-account=pgbackrest +repo2-azure-key=aF49wnZP +repo2-azure-container=container +repo2-storage-verify-tls=n +repo2-retention-full={{ pgbackrest_repo_retention_full }} +repo2-cipher-type=aes-256-cbc +repo2-cipher-pass={{ pgbackrest_repo_cipher_pass }} +{% else %} +repo1-type=posix +repo1-path={{ pgbackrest_repo_path }} +repo1-retention-full={{ pgbackrest_repo_retention_full }} +repo1-cipher-type=aes-256-cbc +repo1-cipher-pass={{ pgbackrest_repo_cipher_pass }} +{% endif %} +log-level-console=warn +log-level-file=info +start-fast=y +delta=y +process-max=2 + +[{{ cluster_name }}] +{% for server in pgbackrest_servers %} +{% set v = hostvars[server] %} +pg{{ loop.index }}-host={{ v.private_ip }} +pg{{ loop.index }}-host-user={{ v.pg_owner }} +pg{{ loop.index }}-path={{ v.pg_data }} +pg{{ loop.index }}-socket-path={{ v.pg_unix_socket_directories[0] }} +{% endfor %} diff --git a/tests/roles/sys/pkg/defaults/main.yml b/tests/roles/sys/pkg/defaults/main.yml new file mode 100644 index 0000000..5cbd65d --- /dev/null +++ b/tests/roles/sys/pkg/defaults/main.yml @@ -0,0 +1,16 @@ +--- +default_packages: + common: + - openssh-server + - openssl + - sudo + - wget + Debian: + - openssh-client + - iproute2 + - gnupg + - xxd + RedHat: + - openssh-clients + - iproute + - vim-common \ No newline at end of file diff --git a/tests/roles/sys/pkg/tasks/main.yml b/tests/roles/sys/pkg/tasks/main.yml new file mode 100644 index 0000000..4ba0d64 --- /dev/null +++ b/tests/roles/sys/pkg/tasks/main.yml @@ -0,0 +1,10 @@ +--- +- name: Install required packages + package: + name: > + {{ query('flattened', package_lists) }} + state: latest + vars: + package_lists: + - "{{ default_packages['common'] }}" + - "{{ default_packages[ansible_os_family] }}" \ No newline at end of file diff --git a/tests/roles/sys/tasks/main.yml b/tests/roles/sys/tasks/main.yml new file mode 100644 index 0000000..8ca7b0c --- /dev/null +++ b/tests/roles/sys/tasks/main.yml @@ -0,0 +1,72 @@ +--- +- include_role: + name: sys/pkg + +- name: Start ssh server + service: + name: "{{ ssh_service_name }}" + state: started + vars: + ssh_service_name: "{{ + (ansible_os_family == 'RedHat')|ternary('sshd', 'ssh') + }}" + +- name: Ensure authorized_keys allows admin access + authorized_key: + user: root + state: present + key: "{{ lookup('file', ssh_key_file_pub) }}" + vars: + ssh_key_file_pub: "{{ cluster_dir }}/{{ ssh_key_file }}.pub" + +- name: Ensure that .ssh exists on all hosts + file: + path: "~/.ssh" + state: directory + mode: '0700' + +- name: Install keypair on all hosts + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + with_items: + - src: "{{ cluster_dir }}/{{ ssh_key_file }}" + dest: "~/.ssh/id_rsa" + mode: '0600' + - src: "{{ cluster_dir }}/{{ ssh_key_file }}.pub" + dest: "~/.ssh/id_rsa.pub" + mode: '0640' + +- name: Update network facts + ansible.builtin.setup: + gather_subset: + - network + +- name: Set main /etc/hosts entry + set_fact: + my_hosts_lines: "{{ [main_hosts_line] }}" + vars: + main_hosts_line: >- + {{ ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0]) }} + {{ [inventory_hostname, inventory_hostname_short]|unique|join(' ') }} + +- name: Aggregate /etc/hosts lines across hosts + set_fact: + etc_hosts_lines: "{{ + etc_hosts_lines|default([])|union(hostvars[item].my_hosts_lines) + }}" + with_items: "{{ groups['all'] }}" + +- name: Add entries to /etc/hosts + lineinfile: + path: /etc/hosts + line: "{{ item }}" + loop: "{{ etc_hosts_lines }}" + when: platform != 'docker' + +- name: Ensure /run/nologin does not exist + file: + path: /run/nologin + state: absent + when: platform in ['docker'] \ No newline at end of file diff --git a/tests/run.sh b/tests/run.sh new file mode 100644 index 0000000..4df226a --- /dev/null +++ b/tests/run.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +cd "$(dirname "$0")" + +usage() { + echo "Usage:" + echo " -A Activity step only." + echo " -c Cluster directory." + echo " -C Cleaning step only." + echo " -h Display this help message." + echo " -i Initial step only." +} + +INIT_ONLY=false +CLEAN_ONLY=false +PROVISION=true +DEPLOY=true +while getopts "Ac:Chi" o; do + case "${o}" in + A) + INIT_ONLY=false + CLEAN_ONLY=false + PROVISION=false + DEPLOY=false + ACTIVITY=true + ;; + c) + CLUSTER_DIR=${OPTARG} + ;; + C) + CLEAN_ONLY=true + ;; + h ) + usage + exit 0 + ;; + i) + INIT_ONLY=true + ;; + *) + usage 1>&2 + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +if $INIT_ONLY; then + #------------------------------------------------------------------------------------------------------------------- + echo '-------------------- Init --------------------' && date + #------------------------------------------------------------------------------------------------------------------- + # This section is intended to update the GitHub Action Runner (Ubuntu) + echo 'Update apt' + sudo apt-get update + echo '--------------------' + echo 'Whoami?' + whoami + echo '--------------------' + echo 'Docker installed?' + docker version + echo '--------------------' + echo 'Ansible installed?' + ansible --version + echo '--------------------' + echo 'Install ansible dependencies' + pipx inject ansible-base docker-py + ansible-galaxy collection install community.docker + ansible-galaxy collection install edb_devops.edb_postgres + ansible-galaxy collection install t_systems_mms.icinga_director + echo '--------------------' + echo 'Install Azure Storage Blobs client library for Python' + pip install azure-storage-blob + + # Exit with success + exit 0; +fi + +if $CLEAN_ONLY; then + #------------------------------------------------------------------------------------------------------------------- + echo '-------------------- Clean --------------------' && date + #------------------------------------------------------------------------------------------------------------------- + if [ -e $CLUSTER_DIR ]; then + ansible-playbook platforms/deprovision.yml -e cluster_dir=$CLUSTER_DIR + sudo rm --force --preserve-root --recursive $CLUSTER_DIR + fi + + # Exit with success + exit 0; +fi + +if $PROVISION; then + #----------------------------------------------------------------------------------------------------------------------- + echo '-------------------- Provision --------------------' && date + #----------------------------------------------------------------------------------------------------------------------- + export ANSIBLE_ROLES_PATH=${ANSIBLE_ROLES_PATH:+$ANSIBLE_ROLES_PATH:}$(pwd)/roles + : "${CLUSTER_DIR:?Variable not set or empty}" + echo "CLUSTER_DIR=$CLUSTER_DIR" + ansible-playbook platforms/provision.yml -e cluster_dir=$CLUSTER_DIR + ansible-playbook platforms/system-config.yml -i "$CLUSTER_DIR/inventory.docker.yml" -e cluster_dir=$CLUSTER_DIR +fi + +if $DEPLOY; then + #----------------------------------------------------------------------------------------------------------------------- + echo '-------------------- Deploy --------------------' && date + #----------------------------------------------------------------------------------------------------------------------- + : "${EDB_REPO_USERNAME:?Variable not set or empty}" + : "${EDB_REPO_PASSWORD:?Variable not set or empty}" + export ANSIBLE_HOST_KEY_CHECKING=False + export ANSIBLE_REMOTE_USER="root" + ansible-playbook playbooks/deploy.yml -i "$CLUSTER_DIR/inventory" -e cluster_dir=$CLUSTER_DIR +fi + +if $ACTIVITY; then + #----------------------------------------------------------------------------------------------------------------------- + echo '-------------------- Simulate basic activity --------------------' && date + #----------------------------------------------------------------------------------------------------------------------- + ansible-playbook playbooks/activity.yml -i "$CLUSTER_DIR/inventory" +fi diff --git a/tests/vagrant.sh b/tests/vagrant.sh new file mode 100755 index 0000000..b25a2cd --- /dev/null +++ b/tests/vagrant.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset + +cd /vagrant +export RUN_ARGS="" +if [ "$ACTIVITY" == "only" ]; then + export ACTIVITY=true + export RUN_ARGS="-A" +fi +echo "ACTIVITY = '$ACTIVITY'" +echo "ARCH = '$ARCH'" +echo "PGBR_BUILD = '$PGBR_BUILD'" +echo "PGBR_REPO_TYPE = '$PGBR_REPO_TYPE'" +echo "PROFILE = '$PROFILE'" +source profile.d/$PROFILE.profile +source profile.d/vagrant.profile + +if [ ! -z "$EXTRA" ]; then + export EXTRA_VARS="$EXTRA_VARS $EXTRA" +fi + +if $PGBR_BUILD; then + export EXTRA_VARS="$EXTRA_VARS pgbackrest_build=true" +fi + +if [ ! -z "$PGBR_REPO_TYPE" ]; then + export EXTRA_VARS="$EXTRA_VARS pgbackrest_repo_type=$PGBR_REPO_TYPE" + [ "$PGBR_REPO_TYPE" = "posix" ] && export EXTRA_VARS="$EXTRA_VARS pgbackrest_repo_path=/shared/repo1" +fi + +[ ! -z "$edb_repository_username" ] && export EDB_REPO_USERNAME=$edb_repository_username +[ ! -z "$edb_repository_password" ] && export EDB_REPO_PASSWORD=$edb_repository_password +[ ! -z "$pgbackrest_git_url" ] && export EXTRA_VARS="$EXTRA_VARS pgbackrest_git_url=$pgbackrest_git_url" +[ ! -z "$pgbackrest_git_branch" ] && export EXTRA_VARS="$EXTRA_VARS pgbackrest_git_branch=$pgbackrest_git_branch" + +echo "EXTRA_VARS = '$EXTRA_VARS'" +echo "CLNAME=$CLNAME" +sh ci.sh \ No newline at end of file diff --git a/tests/vagrant.yml-dist b/tests/vagrant.yml-dist new file mode 100644 index 0000000..610770e --- /dev/null +++ b/tests/vagrant.yml-dist @@ -0,0 +1,9 @@ +# EDB repositories personal credential +# https://www.enterprisedb.com/repository-access-thank-you-page +# edb_repository_username: "username" +# edb_repository_password: "password" + +# When building pgBackRest from sources, define which Github repository and branch to use +# pgbackrest_git_url: "https://github.com/pgbackrest/pgbackrest.git" +# pgbackrest_git_branch: "master" +