-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Created image scp feature #10828
Created image scp feature #10828
Conversation
99ca323
to
9c02a95
Compare
Podman push can already do almost all of the functionality you have. What podman image scp alpine REMOTESERVER: |
Yes, you would do the equivalent of podman save image /tmp/TMPFILE |
That's not entirely correct. So I think that |
Correct. podman -load would be doing the ssh stuff under the covers. |
Actually the code will end up doing the equivalent of podman save $image | podman-remote load |
👍 limiting to storage SGTM |
@vrothberg @rhatdan so is the load I am doing in conjunction with I also had an idea if we really wanted to do a proper ssh I could mimic some of the connection behavior in add.go validating that the connection the user gave is one that exists in |
I have not looked at the underlying code, I am just trying to come to an understanding of the functionality. If you have podman-remote load code in here, then it SGTM. |
@rhatdan figured out a pretty interesting way to provide both --remote support and native ssh. |
34f3237
to
2b5c08e
Compare
Just to weigh in with the experience of an old, old programmer: bugs deferred "for later" are never fixed. You move on to other things; review comments are misplaced and forgotten. It is painful to get everything just-right at the beginning, but it is exponentially more painful to find and fix them afterward. @cdoern your work on this and your responsiveness have been outstanding. @mtrmac you know I always admire your review skills, in this case it's amazing: you're catching subtle but serious issues, and doing so despite constant churn. I don't know how you do it. If I may humbly offer some advice to both of you, it would be: take your time. Wait for each other to finish writing/resolving comments, then wait a little longer, even a day maybe, and then reiterate. That will give time for each issue to get digested. There is no hurry on this. Thanks to both of you for your hard work. |
Ok I agree with what both of you are saying @edsantiago @mtrmac lets hold off on merging until we get it right!!! I am confident we are getting close. I just implemented the shared |
4f523dd
to
174fcd7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitHub doesn’t like long PR discussions…
I have copied outstanding comments from the previous partial reviews here, so that my reviews before #10828 (review) can be ignored. Hopefully that’s helpful.
Podman maintainers, two outstanding functional issues:
- The use of
ParseNormalizedNamed
probably interferes with short-name lookup - Copy from a remote server leaves around a large temporary file
The rest is style/corner cases.
0934f78
to
dc07f4f
Compare
cmd/podman/images/scp.go
Outdated
cliConnections = append(cliConnections, args[0]) | ||
cliConnections = append(cliConnections, args[1]) | ||
} else if len(strings.Split(args[0], "::")[1]) > 1 && len(strings.Split(args[1], "::")[0]) > 1 { | ||
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot specify an image rename") | ||
} else { // else its a load save (order of args) | ||
cliConnections = append(cliConnections, args[1]) | ||
cliConnections = append(cliConnections, args[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t see how the switching of order of arguments works — later the createConnection
function assumes that the index in .Connections
depends only on direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is so fed::alpine fed::
and fed:: fed::alpine
both mean the same thing. cliConnections/scpOpts.Connections always has the first entry be the from
location and the second be the to
location
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case of copying from/to the same host, sure, that works, but for src::alpine dest::
and src:: dest::alpine
this breaks, AFAICS, switching src
and dest
, exactly because “the first entry is the from location”.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how the example using different hosts makes a difference. the ordering paradigm of first entry in array = from location
and second entry in array = to location
still holds
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might have misunderstood the design, see elsewhere. Anyway, assuming my previous interpretation:
image scp a:: b::alpine
:- My expectation of what this means: load from connection
a
, save to connectionb
. - I think the code does: The
// is save->load w/ one image name or save-load w/ two image names
code path, setscliConnections
to["a::alpine", "b::"]
, i.e.scpOpts.URI
is set to[aConnection, bConnection]
, i.e. from=a
, to=b
- i.e. works as I thought it is designed to
- My expectation of what this means: load from connection
image scp a::alpine b::
:- My expectation of what this means: load from connection
a
, save to connectionb
. - I think the code does: The
// else its a load save (order of args)
code path, setscliConnections
to["b::" ,"a::alpine"]
, i.e.scpOpts.URI
is set to[bConnection, aConnection]
, i.e. from=b
, to=a
- i.e. works contrary to my expectations
- My expectation of what this means: load from connection
if strings.Contains(args[0], "::") { | ||
if !(strings.Contains(args[1], "::")) && len(strings.Split(args[0], "::")[1]) <= 1 { // if an image is specified, this mean we are loading from our client | ||
cliConnections = append(cliConnections, args[0]) | ||
scpOpts.ToRemote = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t this image scp foo:: bar
? Why is that ToRemote
? What sets SourceImageName
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to this this ensures that both image scp foo:: bar
is the same as image scp bar foo::
order of arguments shouldn't make a difference if they are valid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a setting for SourceImageName
I had never tested that path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to this this ensures that both
image scp foo:: bar
is the same asimage scp bar foo::
order of arguments shouldn't make a difference if they are valid
I don’t understand. How can the order of arguments not make a difference? One of the two means “copy remote file to local”, and the other to “copy local to remote”, doesn’t it? At least that I would expect based on the more generic case image scp host1::image1 host2::image2
.
Or is this designed so that image scp foo::bar
is remote→local, and a two-argument version is local→remote? If so, what will be the future syntax for remote→local while saving under a different name?
(The man page does not explain the meaning of the syntax either; it just shows the syntax.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a setting for SourceImageName I had never tested that path.
(That’s ultimately what unit tests are for, but that might truly be a later PR.)
scpOpts.ToRemote = true | ||
if len(strings.Split(args[0], "::")[1]) <= 1 { // is save->load w/ one image name or save-load w/ two image names | ||
cliConnections = append(cliConnections, args[0]) | ||
cliConnections = append(cliConnections, args[1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does anything guarantee at least one image name on this path? We only know that args[0]
is …::
, nothing about args[1]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validated below in the cliConnections loop, this part just gets the connections in the right place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop only validates image name if it is not empty; it does nothing in the image scp host1:: host2::
case AFAICS.
Both resolved now. There might be some argument parsing issues but those would quickly show up in practical usage. |
Ok @mtrmac thank you again for all of the semantic and structural help. I really needed some practice with code elegance. |
if strings.Contains(args[0], "::") { | ||
if !(strings.Contains(args[1], "::")) && len(strings.Split(args[0], "::")[1]) <= 1 { // if an image is specified, this mean we are loading from our client | ||
cliConnections = append(cliConnections, args[0]) | ||
scpOpts.ToRemote = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to this this ensures that both
image scp foo:: bar
is the same asimage scp bar foo::
order of arguments shouldn't make a difference if they are valid
I don’t understand. How can the order of arguments not make a difference? One of the two means “copy remote file to local”, and the other to “copy local to remote”, doesn’t it? At least that I would expect based on the more generic case image scp host1::image1 host2::image2
.
Or is this designed so that image scp foo::bar
is remote→local, and a two-argument version is local→remote? If so, what will be the future syntax for remote→local while saving under a different name?
(The man page does not explain the meaning of the syntax either; it just shows the syntax.)
scpOpts.ToRemote = true | ||
if len(strings.Split(args[0], "::")[1]) <= 1 { // is save->load w/ one image name or save-load w/ two image names | ||
cliConnections = append(cliConnections, args[0]) | ||
cliConnections = append(cliConnections, args[1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop only validates image name if it is not empty; it does nothing in the image scp host1:: host2::
case AFAICS.
if strings.Contains(args[0], "::") { | ||
if !(strings.Contains(args[1], "::")) && len(strings.Split(args[0], "::")[1]) <= 1 { // if an image is specified, this mean we are loading from our client | ||
cliConnections = append(cliConnections, args[0]) | ||
scpOpts.ToRemote = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a setting for SourceImageName I had never tested that path.
(That’s ultimately what unit tests are for, but that might truly be a later PR.)
@cdoern Thanks for all your work, it’s been an enormous amount. At this point the code LGTM, though I realize that we might not actually be agreeing on what the CLI design is :) I’ll happily leave that part to others. Note to self/others: outstanding: |
added functionality for image secure copying from local to remote. Also moved system connection add code around a bit so functions within that file can be used by scp. Signed-off-by: cdoern <[email protected]>
Just made small doc changes and the suggested sematic changes above. Looking forward to showing this off at the community meeting 😀 |
/lgtm |
using scp has been discouraged since openssh 8.0 and should be replaced with sftp or rsync. See https://www.openssh.com/txt/release-8.0 Although recent 8.8 update mentions, so expect potential breaking changes:
|
I don't believe we are actually using scp to copy the files between containers/storage. We are using the ssh protocol to copy them though and we called the command scp, to make it clearer what is happening, Calling this sftp or rsync would not have made that clear. But if you would like to rename it to some other command, I am all ears. |
Created image scp feature for secure image copy
added functionality for image secure copying from local to remote.
Signed-off-by: cdoern [email protected]