podman load: support downloading files

Support downloading files, for instance via
`podman load -i server.com/image.tar`.  The specified URL is downloaded
in the frontend and stored as a temp file that gets passed down to the
backend.

Also vendor in c/common@main to use the new `pkg/download`.

Fixes: #11970
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2021-11-10 15:39:29 +01:00
parent 5437568fcd
commit 1ef66d6d7f
18 changed files with 276 additions and 78 deletions

View File

@ -1,46 +0,0 @@
package libimage
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"github.com/pkg/errors"
)
// tmpdir returns a path to a temporary directory.
func tmpdir() string {
tmpdir := os.Getenv("TMPDIR")
if tmpdir == "" {
tmpdir = "/var/tmp"
}
return tmpdir
}
// downloadFromURL downloads an image in the format "https:/example.com/myimage.tar"
// and temporarily saves in it $TMPDIR/importxyz, which is deleted after the image is imported
func (r *Runtime) downloadFromURL(source string) (string, error) {
fmt.Printf("Downloading from %q\n", source)
outFile, err := ioutil.TempFile(r.systemContext.BigFilesTemporaryDir, "import")
if err != nil {
return "", errors.Wrap(err, "error creating file")
}
defer outFile.Close()
response, err := http.Get(source) // nolint:noctx
if err != nil {
return "", errors.Wrapf(err, "error downloading %q", source)
}
defer response.Body.Close()
_, err = io.Copy(outFile, response.Body)
if err != nil {
return "", errors.Wrapf(err, "error saving %s to %s", source, outFile.Name())
}
return outFile.Name(), nil
}

View File

@ -2,9 +2,11 @@ package libimage
import (
"context"
"fmt"
"net/url"
"os"
"github.com/containers/common/pkg/download"
storageTransport "github.com/containers/image/v5/storage"
tarballTransport "github.com/containers/image/v5/tarball"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
@ -61,7 +63,8 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption
u, err := url.ParseRequestURI(path)
if err == nil && u.Scheme != "" {
// If source is a URL, download the file.
file, err := r.downloadFromURL(path)
fmt.Printf("Downloading from %q\n", path)
file, err := download.FromURL(r.systemContext.BigFilesTemporaryDir, path)
if err != nil {
return "", err
}

View File

@ -21,6 +21,16 @@ import (
// Faster than the standard library, see https://github.com/json-iterator/go.
var json = jsoniter.ConfigCompatibleWithStandardLibrary
// tmpdir returns a path to a temporary directory.
func tmpdir() string {
tmpdir := os.Getenv("TMPDIR")
if tmpdir == "" {
tmpdir = "/var/tmp"
}
return tmpdir
}
// RuntimeOptions allow for creating a customized Runtime.
type RuntimeOptions struct {
// The base system context of the runtime which will be used throughout