mirror of
https://github.com/containers/podman.git
synced 2025-06-21 01:19:15 +08:00
Merge pull request #18563 from vrothberg/fix-15897
remote-save: fix permissions and dir formats
This commit is contained in:
@ -23,9 +23,13 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/domain/infra/abi"
|
"github.com/containers/podman/v4/pkg/domain/infra/abi"
|
||||||
domainUtils "github.com/containers/podman/v4/pkg/domain/utils"
|
domainUtils "github.com/containers/podman/v4/pkg/domain/utils"
|
||||||
"github.com/containers/podman/v4/pkg/errorhandling"
|
"github.com/containers/podman/v4/pkg/errorhandling"
|
||||||
|
"github.com/containers/podman/v4/pkg/rootless"
|
||||||
"github.com/containers/podman/v4/pkg/util"
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
utils2 "github.com/containers/podman/v4/utils"
|
utils2 "github.com/containers/podman/v4/utils"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
|
"github.com/containers/storage/pkg/archive"
|
||||||
|
"github.com/containers/storage/pkg/chrootarchive"
|
||||||
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/gorilla/schema"
|
"github.com/gorilla/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -266,16 +270,6 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// if format is dir, server will save to an archive
|
|
||||||
// the client will unArchive after receive the archive file
|
|
||||||
// so must convert is at here
|
|
||||||
switch query.Format {
|
|
||||||
case define.OCIManifestDir:
|
|
||||||
query.Format = define.OCIArchive
|
|
||||||
case define.V2s2ManifestDir:
|
|
||||||
query.Format = define.V2s2Archive
|
|
||||||
}
|
|
||||||
|
|
||||||
switch query.Format {
|
switch query.Format {
|
||||||
case define.V2s2Archive, define.OCIArchive:
|
case define.V2s2Archive, define.OCIArchive:
|
||||||
tmpfile, err := os.CreateTemp("", "api.tar")
|
tmpfile, err := os.CreateTemp("", "api.tar")
|
||||||
@ -316,6 +310,9 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we already produced a tar archive, let's stream that directly.
|
||||||
|
switch query.Format {
|
||||||
|
case define.V2s2Archive, define.OCIArchive:
|
||||||
rdr, err := os.Open(output)
|
rdr, err := os.Open(output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to read the exported tarfile: %w", err))
|
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to read the exported tarfile: %w", err))
|
||||||
@ -323,6 +320,21 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer rdr.Close()
|
defer rdr.Close()
|
||||||
utils.WriteResponse(w, http.StatusOK, rdr)
|
utils.WriteResponse(w, http.StatusOK, rdr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tarOptions := &archive.TarOptions{
|
||||||
|
ChownOpts: &idtools.IDPair{
|
||||||
|
UID: rootless.GetRootlessUID(),
|
||||||
|
GID: rootless.GetRootlessGID(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
tar, err := chrootarchive.Tar(output, tarOptions, output)
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to read the exported tarfile: %w", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteResponse(w, http.StatusOK, tar)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ImagesLoad(w http.ResponseWriter, r *http.Request) {
|
func ImagesLoad(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/domain/entities/reports"
|
"github.com/containers/podman/v4/pkg/domain/entities/reports"
|
||||||
"github.com/containers/podman/v4/pkg/domain/utils"
|
"github.com/containers/podman/v4/pkg/domain/utils"
|
||||||
"github.com/containers/podman/v4/pkg/errorhandling"
|
"github.com/containers/podman/v4/pkg/errorhandling"
|
||||||
utils2 "github.com/containers/podman/v4/utils"
|
"github.com/containers/storage/pkg/archive"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) {
|
func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) {
|
||||||
@ -329,7 +329,8 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string,
|
|||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return utils2.UntarToFileSystem(opts.Output, f, nil)
|
|
||||||
|
return archive.Untar(f, opts.Output, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) {
|
func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) {
|
||||||
|
@ -66,31 +66,30 @@ var _ = Describe("Podman save", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman save to directory with oci format", func() {
|
It("podman save to directory with oci format", func() {
|
||||||
if isRootless() {
|
|
||||||
Skip("Requires a fix in containers image for chown/lchown")
|
|
||||||
}
|
|
||||||
outdir := filepath.Join(podmanTest.TempDir, "save")
|
outdir := filepath.Join(podmanTest.TempDir, "save")
|
||||||
|
|
||||||
save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
|
save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
|
||||||
save.WaitWithDefaultTimeout()
|
save.WaitWithDefaultTimeout()
|
||||||
Expect(save).Should(Exit(0))
|
Expect(save).Should(Exit(0))
|
||||||
|
|
||||||
|
// Smoke test if it looks like an OCI dir
|
||||||
|
Expect(filepath.Join(outdir, "oci-layout")).Should(BeAnExistingFile())
|
||||||
|
Expect(filepath.Join(outdir, "index.json")).Should(BeAnExistingFile())
|
||||||
|
Expect(filepath.Join(outdir, "blobs")).Should(BeAnExistingFile())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman save to directory with v2s2 docker format", func() {
|
It("podman save to directory with v2s2 docker format", func() {
|
||||||
if isRootless() {
|
|
||||||
Skip("Requires a fix in containers image for chown/lchown")
|
|
||||||
}
|
|
||||||
outdir := filepath.Join(podmanTest.TempDir, "save")
|
outdir := filepath.Join(podmanTest.TempDir, "save")
|
||||||
|
|
||||||
save := podmanTest.Podman([]string{"save", "--format", "docker-dir", "-o", outdir, ALPINE})
|
save := podmanTest.Podman([]string{"save", "--format", "docker-dir", "-o", outdir, ALPINE})
|
||||||
save.WaitWithDefaultTimeout()
|
save.WaitWithDefaultTimeout()
|
||||||
Expect(save).Should(Exit(0))
|
Expect(save).Should(Exit(0))
|
||||||
|
|
||||||
|
// Smoke test if it looks like a docker dir
|
||||||
|
Expect(filepath.Join(outdir, "version")).Should(BeAnExistingFile())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman save to directory with docker format and compression", func() {
|
It("podman save to directory with docker format and compression", func() {
|
||||||
if isRootless() && podmanTest.RemoteTest {
|
|
||||||
Skip("Requires a fix in containers image for chown/lchown")
|
|
||||||
}
|
|
||||||
outdir := filepath.Join(podmanTest.TempDir, "save")
|
outdir := filepath.Join(podmanTest.TempDir, "save")
|
||||||
|
|
||||||
save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE})
|
save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE})
|
||||||
@ -99,9 +98,6 @@ var _ = Describe("Podman save", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman save to directory with --compress but not use docker-dir and oci-dir", func() {
|
It("podman save to directory with --compress but not use docker-dir and oci-dir", func() {
|
||||||
if isRootless() && podmanTest.RemoteTest {
|
|
||||||
Skip("Requires a fix in containers image for chown/lchown")
|
|
||||||
}
|
|
||||||
outdir := filepath.Join(podmanTest.TempDir, "save")
|
outdir := filepath.Join(podmanTest.TempDir, "save")
|
||||||
|
|
||||||
save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-archive", "-o", outdir, ALPINE})
|
save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-archive", "-o", outdir, ALPINE})
|
||||||
|
Reference in New Issue
Block a user