Skip to content

Commit 1161218

Browse files
committed
fix: recognize errors from external tools and mention them in logs (#293)
1 parent 569dc27 commit 1161218

File tree

4 files changed

+25
-17
lines changed

4 files changed

+25
-17
lines changed

Diff for: internal/retrieval/engine/postgres/logical/dump.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ func (d *DumpJob) buildLogicalDumpCommand(dbName string, tables []string) []stri
643643

644644
func (d *DumpJob) buildLogicalRestoreCommand(dbName string) []string {
645645
restoreCmd := []string{"|", "pg_restore", "--username", d.globalCfg.Database.User(), "--dbname", defaults.DBName,
646-
"--no-privileges", "--no-owner"}
646+
"--no-privileges", "--no-owner", "--exit-on-error"}
647647

648648
if dbName != defaults.DBName {
649649
// To avoid recreating of the default database.

Diff for: internal/retrieval/engine/postgres/logical/restore.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ func (r *RestoreJob) buildPlainTextCommand(dumpName string, definition DumpDefin
709709

710710
func (r *RestoreJob) buildPGRestoreCommand(dumpName string, definition DumpDefinition) []string {
711711
restoreCmd := []string{"pg_restore", "--username", r.globalCfg.Database.User(), "--dbname", defaults.DBName,
712-
"--no-privileges", "--no-owner"}
712+
"--no-privileges", "--no-owner", "--exit-on-error"}
713713

714714
if definition.dbName != defaults.DBName {
715715
// To avoid recreating of the default database.

Diff for: internal/retrieval/engine/postgres/logical/restore_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ func TestRestoreCommandBuilding(t *testing.T) {
4242
},
4343
DumpLocation: "/tmp/db.dump",
4444
},
45-
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--create", "--jobs", "1", "/tmp/db.dump"},
45+
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--exit-on-error", "--create", "--jobs", "1", "/tmp/db.dump"},
4646
},
4747
{
4848
copyOptions: RestoreOptions{
4949
ParallelJobs: 4,
5050
ForceInit: true,
5151
},
52-
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--create", "--clean", "--if-exists", "--jobs", "4", ""},
52+
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--exit-on-error", "--create", "--clean", "--if-exists", "--jobs", "4", ""},
5353
},
5454
{
5555
copyOptions: RestoreOptions{
@@ -58,7 +58,7 @@ func TestRestoreCommandBuilding(t *testing.T) {
5858
Databases: map[string]DumpDefinition{"testDB": {}},
5959
DumpLocation: "/tmp/db.dump",
6060
},
61-
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--create", "--jobs", "2", "/tmp/db.dump/testDB"},
61+
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--exit-on-error", "--create", "--jobs", "2", "/tmp/db.dump/testDB"},
6262
},
6363
{
6464
copyOptions: RestoreOptions{
@@ -71,7 +71,7 @@ func TestRestoreCommandBuilding(t *testing.T) {
7171
},
7272
DumpLocation: "/tmp/db.dump",
7373
},
74-
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--create", "--jobs", "1", "--table", "test", "--table", "users", "/tmp/db.dump/testDB"},
74+
command: []string{"pg_restore", "--username", "john", "--dbname", "postgres", "--no-privileges", "--no-owner", "--exit-on-error", "--create", "--jobs", "1", "--table", "test", "--table", "users", "/tmp/db.dump/testDB"},
7575
},
7676
{
7777
copyOptions: RestoreOptions{

Diff for: internal/retrieval/engine/postgres/tools/tools.go

+19-11
Original file line numberDiff line numberDiff line change
@@ -473,42 +473,50 @@ func ExecCommandWithOutput(ctx context.Context, dockerClient *client.Client, con
473473

474474
defer attachResponse.Close()
475475

476-
wb := new(bytes.Buffer)
476+
output, err := processAttachResponse(ctx, attachResponse.Reader)
477+
if err != nil {
478+
return string(output), errors.Wrap(err, "failed to read response of exec command")
479+
}
477480

478-
if err := processAttachResponse(ctx, attachResponse.Reader, wb); err != nil {
479-
return "", errors.Wrap(err, "failed to read response of exec command")
481+
inspection, err := dockerClient.ContainerExecInspect(ctx, execCommand.ID)
482+
if err != nil {
483+
return "", fmt.Errorf("failed to inspect an exec process: %w", err)
480484
}
481485

482-
return string(bytes.TrimSpace(wb.Bytes())), nil
486+
if inspection.ExitCode != 0 {
487+
err = fmt.Errorf("exit code: %d", inspection.ExitCode)
488+
}
489+
490+
return string(output), err
483491
}
484492

485493
// processAttachResponse reads and processes the cmd output.
486-
func processAttachResponse(ctx context.Context, reader io.Reader, output io.Writer) error {
487-
var errBuf bytes.Buffer
494+
func processAttachResponse(ctx context.Context, reader io.Reader) ([]byte, error) {
495+
var outBuf, errBuf bytes.Buffer
488496

489497
outputDone := make(chan error)
490498

491499
go func() {
492500
// StdCopy de-multiplexes the stream into two writers.
493-
_, err := stdcopy.StdCopy(output, &errBuf, reader)
501+
_, err := stdcopy.StdCopy(&outBuf, &errBuf, reader)
494502
outputDone <- err
495503
}()
496504

497505
select {
498506
case err := <-outputDone:
499507
if err != nil {
500-
return errors.Wrap(err, "failed to copy output")
508+
return nil, errors.Wrap(err, "failed to copy output")
501509
}
502510

503511
break
504512

505513
case <-ctx.Done():
506-
return ctx.Err()
514+
return nil, ctx.Err()
507515
}
508516

509517
if errBuf.Len() > 0 {
510-
return errors.New(errBuf.String())
518+
return nil, errors.New(errBuf.String())
511519
}
512520

513-
return nil
521+
return bytes.TrimSpace(outBuf.Bytes()), nil
514522
}

0 commit comments

Comments
 (0)