-
Notifications
You must be signed in to change notification settings - Fork 488
[image-save-load]: support for stdin/stdout #734
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
base: main
Are you sure you want to change the base?
[image-save-load]: support for stdin/stdout #734
Conversation
0ac3b6b
to
3029055
Compare
3029055
to
b0de0e0
Compare
URL(fileURLWithPath: str, relativeTo: .currentDirectory()).absoluteURL.path(percentEncoded: false) | ||
}) | ||
var input: String | ||
var input: String? |
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 fine but what you'll want to do is change L35 to something like this so input = nil
is transformed properly:
str.map { URL(fileURLWithPath: $0, relativeTo: .currentDirectory()).absoluteURL.path(percentEncoded: false) }
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.
Not really sure why we need to do this 🤔 .
Also getting an error with that change Cannot convert value of type 'String.Element' (aka 'Character') to expected argument type 'String'
public func run() async throws { | ||
guard FileManager.default.fileExists(atPath: input) else { | ||
print("File does not exist \(input)") | ||
var filePath = "" |
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 isn't quite what #559 is asking for. If input == nil
we don't want to prompt the user for a pathname. What image load
needs to do in this case is:
- Create a temporary file, using
defer {}
to delete the file once we're done using it. - Read binary data from the standard input, writing it to the temp file.
- Use the path to the temporary file as the path to load.
This allows us to do things like moving images between Docker and container
without having to mess with intermediate files explicitly:
docker save foo:latest bar:latest | container image load
container save baz:latest qux:latest | docker image load
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.
Ahhh, I was unsure why the issue was talking about stdout
.
How is the binary data coming from the standard input? Are we prompting anything from the user (would it be the path to the temporary file or the path from the file to read the binary data from)?
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.
@saehejkang no prompting whatsoever.
The idea behind the save and load commands is that without any filename, you can use them the same way you'd use many other standard unix commands. Take tar
for example. If I run it with just the -t
option:
% tar -t
I type in some stuff and then type CTRL-D!
^D
tar: Error opening archive: Unrecognized archive format
%
In this instance the command will just sit there, because it's reading its input from the standard input. I type some stuff in, hit return, then type ^D (EOF), and I get an error message because what I inputted wasn't a tar archive.
To do something more useful, I could run the command to create an archive file containing foo
, writing the standard output and redirecting it to foo.tar
:
% touch foo
% tar -c -v -f foo.tar foo
a foo
/Users/john/Documents/projects/vessel/vessel main % tar -c foo > foo.tar
% ls foo*
foo foo.tar
And then I can print the table of contents of the archive by running with the -t
option and hooking up the standard input to the foo.tar
file:
/Users/john/Documents/projects/vessel/vessel main % tar -t < foo.tar
foo
On the load side you will stream data from stdin
into a temporary file, and then give the temporary file to the API.
On the save side, you will use the API to save into a temporary file, and then stream the data to stdout
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.
@saehejkang Continuing...
Try a LLM prompt like:
How do I write something like
cat
in Swift, except it doesn't need to deal with filename arguments, and I want to write stdin to a temporary file, and then read the file out to stdout. It should stream rather than slurp data.
LOL you might want to also ask it to use Swift Foundation APIs instead of low level calls 😄
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.
Funny enough, I only remember how to do this using C
. I have never worked with Swift
before, but it was 10000x easier lol.
URL(fileURLWithPath: str, relativeTo: .currentDirectory()).absoluteURL.path(percentEncoded: false) | ||
}) | ||
var output: String | ||
var output: String? |
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.
Same as above, map String?
to get the absolute path.
} | ||
try await ClientImage.save(references: references, out: output, platform: p) | ||
|
||
let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent("temp-file.tar") |
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 was thinking we create the tempFile
no matter the --output
flag is enabled, so we don't have to do another check after the ClientImage.save
call. It is going to be deleted anyway with the defer
, no matter it is read from or not.
Type of Change
Motivation and Context
Closes #559
Testing
Example Commands with Outputs
Save the docker image to the
test.tar
fileUse the
test.tar
file to load the imagecontainer image load < test.tar Loaded images: docker.io/library/nginx:latest