Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Podman Image SCP transfer patch #12224

Merged
merged 1 commit into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions cmd/podman/images/scp.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,15 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
scpOpts.Save.Format = "oci-archive"
abiErr := abiEng.Save(context.Background(), scpOpts.SourceImageName, []string{}, scpOpts.Save) // save the image locally before loading it on remote, local, or ssh
if abiErr != nil {
errors.Wrapf(abiErr, "could not save image as specified")
return errors.Wrapf(abiErr, "could not save image as specified")
}
if !rootless.IsRootless() && scpOpts.Rootless {
if scpOpts.User == "" {
scpOpts.User = os.Getenv("SUDO_USER")
if scpOpts.User == "" {
return errors.New("could not obtain root user, make sure the environmental variable SUDO_USER is set, and that this command is being run as root")
}
}
err := abiEng.Transfer(context.Background(), scpOpts)
if err != nil {
return err
Expand Down Expand Up @@ -274,7 +280,13 @@ func parseArgs(args []string, cfg *config.Config) (map[string]config.Destination
cliConnections := []string{}
switch len(args) {
case 1:
if strings.Contains(args[0], "::") {
if strings.Contains(args[0], "localhost") {
if strings.Split(args[0], "@")[0] != "root" {
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot transfer images from any user besides root using sudo")
}
scpOpts.Rootless = true
scpOpts.SourceImageName = strings.Split(args[0], "::")[1]
} else if strings.Contains(args[0], "::") {
scpOpts.FromRemote = true
cliConnections = append(cliConnections, args[0])
} else {
Expand All @@ -286,11 +298,15 @@ func parseArgs(args []string, cfg *config.Config) (map[string]config.Destination
}
case 2:
if strings.Contains(args[0], "localhost") || strings.Contains(args[1], "localhost") { // only supporting root to local using sudo at the moment
scpOpts.Rootless = true
scpOpts.User = strings.Split(args[1], "@")[0]
scpOpts.SourceImageName = strings.Split(args[0], "::")[1]
if strings.Split(args[0], "@")[0] != "root" {
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot transfer images from any user besides root using sudo")
return nil, errors.Wrapf(define.ErrInvalidArg, "currently, transferring images to a user account is not supported")
}
if len(strings.Split(args[0], "::")) > 1 {
scpOpts.Rootless = true
scpOpts.User = strings.Split(args[1], "@")[0]
scpOpts.SourceImageName = strings.Split(args[0], "::")[1]
} else {
return nil, errors.Wrapf(define.ErrInvalidArg, "currently, you cannot rename images during the transfer or transfer them to a user account")
}
} else if strings.Contains(args[0], "::") {
if !(strings.Contains(args[1], "::")) && remoteArgLength(args[0], 1) == 0 { // if an image is specified, this mean we are loading to our client
Expand Down
16 changes: 14 additions & 2 deletions docs/source/markdown/podman-image-scp.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ Copying blob e2eb06d8af82 done
Copying config 696d33ca15 done
Writing manifest to image destination
Storing signatures
Run Directory Obtained: /run/user/1000/
[Run Root: /var/tmp/containers-user-1000/containers Graph Root: /root/.local/share/containers/storage DB Path: /root/.local/share/containers/storage/libpod/bolt_state.db]
Getting image source signatures
Copying blob 5eb901baf107 skipped: already exists
Copying config 696d33ca15 done
Expand All @@ -78,6 +76,20 @@ Storing signatures
Loaded image(s): docker.io/library/alpine:latest
```

```
$ sudo podman image scp root@localhost::alpine
Copying blob e2eb06d8af82 done
Copying config 696d33ca15 done
Writing manifest to image destination
Storing signatures
Getting image source signatures
Copying blob 5eb901baf107
Copying config 696d33ca15 done
Writing manifest to image destination
Storing signatures
Loaded image(s): docker.io/library/alpine:latest
```

## SEE ALSO
podman(1), podman-load(1), podman-save(1), podman-remote(1), podman-system-connection-add(1), containers.conf(5), containers-transports(5)

Expand Down
4 changes: 4 additions & 0 deletions test/e2e/image_scp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ var _ = Describe("podman image scp", func() {
list.WaitWithDefaultTimeout()
Expect(list).To(Exit(0))
Expect(list.LineInOutputStartsWith("quay.io/libpod/alpine")).To(BeTrue())

scp = podmanTest.PodmanAsUser([]string{"image", "scp", "root@localhost::" + ALPINE}, 0, 0, "", env) //transfer from root to rootless (us)
scp.WaitWithDefaultTimeout()
Expect(scp).To(Exit(0))
})

It("podman image scp bogus image", func() {
Expand Down