diff --git a/internal/cmd/exec.go b/internal/cmd/exec.go index 1d7d6ef..9688b47 100644 --- a/internal/cmd/exec.go +++ b/internal/cmd/exec.go @@ -39,6 +39,23 @@ func (exec Executor) pgBackRestInfo(output, repoNum string) (string, string, err return stdout.String(), stderr.String(), err } +// bashCommand defines a one-line bash command to exec in a container +func (exec Executor) bashCommand(command string) (string, string, error) { + var stdout, stderr bytes.Buffer + err := exec(nil, &stdout, &stderr, "bash", "-ceu", "--", command) + return stdout.String(), stderr.String(), err +} + +// pgBackRestCheck defines a pgBackRest check command +// Force log-level-console=detail to override if set elsewhere +func (exec Executor) pgBackRestCheck() (string, string, error) { + var stdout, stderr bytes.Buffer + command := "pgbackrest check --log-level-console=detail" + err := exec(nil, &stdout, &stderr, "bash", "-ceu", "--", command) + + return stdout.String(), stderr.String(), err +} + // postgresqlListLogFiles returns the full path of numLogs log files. func (exec Executor) listPGLogFiles(numLogs int) (string, string, error) { var stdout, stderr bytes.Buffer diff --git a/internal/cmd/export.go b/internal/cmd/export.go index b27b6f4..f9ca1a2 100644 --- a/internal/cmd/export.go +++ b/internal/cmd/export.go @@ -1107,6 +1107,45 @@ func gatherPostgresLogsAndConfigs(ctx context.Context, } } + // We will execute several bash commands in the DB container + // text is command to execute and desc is a short description + type Command struct { + path string + description string + } + + commands := []Command{ + {path: "pg_controldata", description: "pg_controldata"}, + } + + var buf bytes.Buffer + + for _, command := range commands { + stdout, stderr, err := Executor(exec).bashCommand(command.path) + if err != nil { + if apierrors.IsForbidden(err) { + writeInfo(cmd, err.Error()) + return nil + } + writeDebug(cmd, fmt.Sprintf("Error executing %s\n", command.path)) + writeDebug(cmd, fmt.Sprintf("%s\n", err.Error())) + writeDebug(cmd, "This is acceptable in some configurations.\n") + continue + } + buf.Write([]byte(fmt.Sprintf("%s\n", command.description))) + buf.Write([]byte(stdout)) + if stderr != "" { + buf.Write([]byte(stderr)) + } + buf.Write([]byte("\n\n")) + } + + // Write the buffer to a file + path := clusterName + fmt.Sprintf("/pods/%s/%s", pod.Name, "postgres-info") + if err := writeTar(tw, buf.Bytes(), path, cmd); err != nil { + return err + } + } return nil } @@ -1518,6 +1557,21 @@ func gatherPgBackRestInfo(ctx context.Context, buf.Write([]byte(stderr)) } + buf.Write([]byte("pgbackrest check\n")) + stdout, stderr, err = Executor(exec).pgBackRestCheck() + 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) }