From b258f9c5f2c3faf36c0705abdf82421b619d47ed Mon Sep 17 00:00:00 2001 From: Benjamin Blattberg Date: Thu, 2 Nov 2023 15:37:53 -0500 Subject: [PATCH] Add pgbackrest info to support export (#81) * Add pgbackrest info to support export Issue: PGO-648 --- docs/content/reference/pgo_support_export.md | 1 + internal/cmd/export.go | 66 ++++++++++++++++++- .../support-export/01--support_export.yaml | 49 +++++++------- 3 files changed, 88 insertions(+), 28 deletions(-) diff --git a/docs/content/reference/pgo_support_export.md b/docs/content/reference/pgo_support_export.md index fbc6e89c..20c03910 100644 --- a/docs/content/reference/pgo_support_export.md +++ b/docs/content/reference/pgo_support_export.md @@ -96,6 +96,7 @@ Collecting Postgres logs... Collecting PostgresCluster pod logs... Collecting monitoring pod logs... Collecting Patroni info... +Collecting pgBackRest info... Collecting processes... Collecting system times from containers... Collecting PGO CLI logs... diff --git a/internal/cmd/export.go b/internal/cmd/export.go index bc5a8638..bf11bf7e 100644 --- a/internal/cmd/export.go +++ b/internal/cmd/export.go @@ -259,6 +259,7 @@ Collecting Postgres logs... Collecting PostgresCluster pod logs... Collecting monitoring pod logs... Collecting Patroni info... +Collecting pgBackRest info... Collecting processes... Collecting system times from containers... Collecting PGO CLI logs... @@ -434,6 +435,10 @@ Collecting PGO CLI logs... err = gatherPatroniInfo(ctx, clientset, restConfig, namespace, clusterName, tw, cmd) } + if err == nil { + err = gatherPgBackRestInfo(ctx, clientset, restConfig, namespace, clusterName, tw, cmd) + } + // Exec to get Container processes if err == nil { err = gatherProcessInfo(ctx, clientset, restConfig, namespace, clusterName, tw, cmd) @@ -994,7 +999,7 @@ func gatherPodLogs(ctx context.Context, return nil } -// gatherExecInfo takes a client and buffer +// gatherPatroniInfo takes a client and buffer // execs into relevant pods to grab information func gatherPatroniInfo(ctx context.Context, clientset *kubernetes.Clientset, @@ -1072,6 +1077,65 @@ func gatherPatroniInfo(ctx context.Context, return nil } +// gatherPgBackRestInfo takes a client and buffer +// execs into relevant pods to grab information +func gatherPgBackRestInfo(ctx context.Context, + clientset *kubernetes.Clientset, + config *rest.Config, + namespace string, + clusterName string, + tw *tar.Writer, + cmd *cobra.Command, +) error { + writeInfo(cmd, "Collecting pgBackRest info...") + // Get the primary instance Pod by its labels + pods, err := clientset.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: util.PrimaryInstanceLabels(clusterName), + }) + if err != nil { + if apierrors.IsForbidden(err) { + writeInfo(cmd, err.Error()) + return nil + } + return err + } + if len(pods.Items) < 1 { + writeInfo(cmd, "No pod found for pgBackRest info") + return nil + } + + podExec, err := util.NewPodExecutor(config) + if err != nil { + return err + } + + exec := func(stdin io.Reader, stdout, stderr io.Writer, command ...string, + ) error { + return podExec(namespace, pods.Items[0].GetName(), util.ContainerDatabase, + stdin, stdout, stderr, command...) + } + + var buf bytes.Buffer + + buf.Write([]byte("pgbackrest info\n")) + stdout, stderr, err := Executor(exec).pgBackRestInfo("text", "") + if err != nil { + if apierrors.IsForbidden(err) { + writeInfo(cmd, err.Error()) + return nil + } + return err + } + + buf.Write([]byte(stdout)) + if stderr != "" { + buf.Write([]byte(stderr)) + } + + path := clusterName + "/pgbackrest-info" + return writeTar(tw, buf.Bytes(), path, cmd) +} + // gatherSystemTime takes a client and buffer and collects system time // in each Pod and calculates the delta against client system time. func gatherSystemTime(ctx context.Context, diff --git a/testing/kuttl/e2e/support-export/01--support_export.yaml b/testing/kuttl/e2e/support-export/01--support_export.yaml index 1adc81fd..311846ab 100644 --- a/testing/kuttl/e2e/support-export/01--support_export.yaml +++ b/testing/kuttl/e2e/support-export/01--support_export.yaml @@ -8,6 +8,16 @@ commands: #!/bin/bash CLEANUP="rm -r ./kuttl-support-cluster ./crunchy_k8s_support_export_*.tar.gz" + check_file() { + if [[ ! -s ./kuttl-support-cluster/"${1}" ]] + then + echo "Expected ${1} file to not be empty" + eval "$CLEANUP" + exit 1 + else + echo "Found ${1}" + fi + } # check that the PGO CLI version is recorded VER=$(cat ./kuttl-support-cluster/pgo-cli-version) @@ -19,28 +29,19 @@ commands: } # check that the cluster-names file exists and is not empty - if [[ ! -s ./kuttl-support-cluster/cluster-names ]] - then - echo "Expected cluster-names file to not be empty" - eval "$CLEANUP" - exit 1 - fi + check_file "cluster-names" # check that the system-time file exists and is not empty - if [[ ! -s ./kuttl-support-cluster/system-time ]] - then - echo "Expected system-time file to not be empty" - eval "$CLEANUP" - exit 1 - fi + check_file "system-time" - # check that the context file exist and is not empty - if [[ ! -s ./kuttl-support-cluster/current-context ]] - then - echo "Expected context file to not be empty" - eval "$CLEANUP" - exit 1 - fi + # check that the context file exists and is not empty + check_file "current-context" + + # check that the patroni info file exists and is not empty + check_file "patroni-info" + + # check that the pgbackrest info file exists and is not empty + check_file "pgbackrest-info" # check for expected gzip compression level FILE_INFO=$(file ./crunchy_k8s_support_export_*.tar.gz) @@ -76,15 +77,9 @@ commands: fi # check that the events file exist and is not empty - EVENTS="./kuttl-support-cluster/events" - - if [[ ! -s $EVENTS ]] - then - echo "Expected Events file to not be empty" - eval "$CLEANUP" - exit 1 - fi + check_file "events" + EVENTS="./kuttl-support-cluster/events" # check that the events file contains the expected string if ! grep -Fq "Created container postgres-startup" $EVENTS then