container export: implement file-write with atomicwriter
Same functionality, but implemented with atomicwriter. There's a slight difference in error-messages produced (but can be adjusted if we want). Before: docker container export -o ./no/such/foo mycontainer failed to export container: invalid output path: directory "no/such" does not exist docker container export -o /no/permissions mycontainer failed to export container: stat /no/permissions: permission denied After: docker container export -o ./no/such/foo mycontainer failed to export container: invalid file path: stat no/such: no such file or directory docker container export -o /no/permissions mycontainer failed to export container: failed to stat output path: lstat /no/permissions: permission denied Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
d47d2338b7
commit
b8bcf6f5ad
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
|
"github.com/moby/sys/atomicwriter"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -41,27 +42,28 @@ func NewExportCommand(dockerCli command.Cli) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) error {
|
func runExport(ctx context.Context, dockerCLI command.Cli, opts exportOptions) error {
|
||||||
if opts.output == "" && dockerCli.Out().IsTerminal() {
|
var output io.Writer
|
||||||
return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect")
|
if opts.output == "" {
|
||||||
|
if dockerCLI.Out().IsTerminal() {
|
||||||
|
return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect")
|
||||||
|
}
|
||||||
|
output = dockerCLI.Out()
|
||||||
|
} else {
|
||||||
|
writer, err := atomicwriter.New(opts.output, 0o600)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to export container")
|
||||||
|
}
|
||||||
|
defer writer.Close()
|
||||||
|
output = writer
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := command.ValidateOutputPath(opts.output); err != nil {
|
responseBody, err := dockerCLI.Client().ContainerExport(ctx, opts.container)
|
||||||
return errors.Wrap(err, "failed to export container")
|
|
||||||
}
|
|
||||||
|
|
||||||
clnt := dockerCli.Client()
|
|
||||||
|
|
||||||
responseBody, err := clnt.ContainerExport(ctx, opts.container)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer responseBody.Close()
|
defer responseBody.Close()
|
||||||
|
|
||||||
if opts.output == "" {
|
_, err = io.Copy(output, responseBody)
|
||||||
_, err := io.Copy(dockerCli.Out(), responseBody)
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return command.CopyToFile(opts.output, responseBody)
|
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,6 @@ func TestContainerExportOutputToIrregularFile(t *testing.T) {
|
|||||||
cmd.SetErr(io.Discard)
|
cmd.SetErr(io.Discard)
|
||||||
cmd.SetArgs([]string{"-o", "/dev/random", "container"})
|
cmd.SetArgs([]string{"-o", "/dev/random", "container"})
|
||||||
|
|
||||||
err := cmd.Execute()
|
const expected = `failed to export container: cannot write to a character device file`
|
||||||
assert.Assert(t, err != nil)
|
assert.Error(t, cmd.Execute(), expected)
|
||||||
expected := `"/dev/random" must be a directory or a regular file`
|
|
||||||
assert.ErrorContains(t, err, expected)
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user