Skip to content

Commit

Permalink
Merge pull request #7956 from QiWang19/save-rm-sig
Browse files Browse the repository at this point in the history
Allow save image remove-signatures
  • Loading branch information
openshift-merge-robot authored Oct 22, 2020
2 parents 5d70f46 + b898f91 commit 513c261
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 10 deletions.
8 changes: 4 additions & 4 deletions libpod/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile
// SaveImages stores one more images in a multi-image archive.
// Note that only `docker-archive` supports storing multiple
// image.
func (ir *Runtime) SaveImages(ctx context.Context, namesOrIDs []string, format string, outputFile string, quiet bool) (finalErr error) {
func (ir *Runtime) SaveImages(ctx context.Context, namesOrIDs []string, format string, outputFile string, quiet, removeSignatures bool) (finalErr error) {
if format != DockerArchive {
return errors.Errorf("multi-image archives are only supported in in the %q format", DockerArchive)
}
Expand Down Expand Up @@ -264,7 +264,7 @@ func (ir *Runtime) SaveImages(ctx context.Context, namesOrIDs []string, format s
}

img := imageMap[id]
copyOptions := getCopyOptions(sys, writer, nil, nil, SigningOptions{}, "", img.tags)
copyOptions := getCopyOptions(sys, writer, nil, nil, SigningOptions{RemoveSignatures: removeSignatures}, "", img.tags)
copyOptions.DestinationCtx.SystemRegistriesConfPath = registries.SystemRegistriesConfPath()

// For copying, we need a source reference that we can create
Expand Down Expand Up @@ -1584,7 +1584,7 @@ func (i *Image) Comment(ctx context.Context, manifestType string) (string, error
}

// Save writes a container image to the filesystem
func (i *Image) Save(ctx context.Context, source, format, output string, moreTags []string, quiet, compress bool) error {
func (i *Image) Save(ctx context.Context, source, format, output string, moreTags []string, quiet, compress, removeSignatures bool) error {
var (
writer io.Writer
destRef types.ImageReference
Expand Down Expand Up @@ -1636,7 +1636,7 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag
return err
}
}
if err := i.PushImageToReference(ctx, destRef, manifestType, "", "", "", writer, compress, SigningOptions{}, &DockerRegistryOptions{}, additionaltags); err != nil {
if err := i.PushImageToReference(ctx, destRef, manifestType, "", "", "", writer, compress, SigningOptions{RemoveSignatures: removeSignatures}, &DockerRegistryOptions{}, additionaltags); err != nil {
return errors.Wrapf(err, "unable to save %q", source)
}
i.newImageEvent(events.Save)
Expand Down
4 changes: 2 additions & 2 deletions pkg/api/handlers/compat/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
return
}
if err := newImage.Save(r.Context(), name, "docker-archive", tmpfile.Name(), []string{}, false, false); err != nil {
if err := newImage.Save(r.Context(), name, "docker-archive", tmpfile.Name(), []string{}, false, false, true); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to save image"))
return
}
Expand Down Expand Up @@ -429,7 +429,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
return
}
if err := runtime.ImageRuntime().SaveImages(r.Context(), images, "docker-archive", tmpfile.Name(), false); err != nil {
if err := runtime.ImageRuntime().SaveImages(r.Context(), images, "docker-archive", tmpfile.Name(), false, true); err != nil {
utils.InternalServerError(w, err)
return
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/api/handlers/libpod/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "unknown format", http.StatusInternalServerError, errors.Errorf("unknown format %q", query.Format))
return
}
if err := newImage.Save(r.Context(), name, query.Format, output, []string{}, false, query.Compress); err != nil {
if err := newImage.Save(r.Context(), name, query.Format, output, []string{}, false, query.Compress, true); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
Expand Down Expand Up @@ -284,6 +284,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
Format: query.Format,
MultiImageArchive: true,
Output: output,
RemoveSignatures: true,
}

imageEngine := abi.ImageEngine{Libpod: runtime}
Expand Down
2 changes: 2 additions & 0 deletions pkg/domain/entities/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ type ImageSaveOptions struct {
MultiImageArchive bool
// Output - write image to the specified path.
Output string
// Do not save the signature from the source image
RemoveSignatures bool
// Quiet - suppress output when copying images
Quiet bool
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/domain/infra/abi/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,13 +482,13 @@ func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOpti
func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, options entities.ImageSaveOptions) error {
if options.MultiImageArchive {
nameOrIDs := append([]string{nameOrID}, tags...)
return ir.Libpod.ImageRuntime().SaveImages(ctx, nameOrIDs, options.Format, options.Output, options.Quiet)
return ir.Libpod.ImageRuntime().SaveImages(ctx, nameOrIDs, options.Format, options.Output, options.Quiet, true)
}
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
if err != nil {
return err
}
return newImage.Save(ctx, nameOrID, options.Format, options.Output, tags, options.Quiet, options.Compress)
return newImage.Save(ctx, nameOrID, options.Format, options.Output, tags, options.Quiet, options.Compress, true)
}

func (ir *ImageEngine) Diff(_ context.Context, nameOrID string, _ entities.DiffOptions) (*entities.DiffReport, error) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/varlinkapi/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ func (i *VarlinkAPI) ImageSave(call iopodman.VarlinkCall, options iopodman.Image
saveOutput := bytes.NewBuffer([]byte{})
c := make(chan error)
go func() {
err := newImage.Save(getContext(), options.Name, options.Format, output, options.MoreTags, options.Quiet, options.Compress)
err := newImage.Save(getContext(), options.Name, options.Format, output, options.MoreTags, options.Quiet, options.Compress, true)
c <- err
close(c)
}()
Expand Down
69 changes: 69 additions & 0 deletions test/e2e/save_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package integration

import (
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"

"github.com/containers/podman/v2/pkg/rootless"
. "github.com/containers/podman/v2/test/utils"
Expand Down Expand Up @@ -116,6 +120,71 @@ var _ = Describe("Podman save", func() {
Expect(save).To(ExitWithError())
})

It("podman save remove signature", func() {
SkipIfRootless("FIXME: Need get in rootless push sign")
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
tempGNUPGHOME := filepath.Join(podmanTest.TempDir, "tmpGPG")
err := os.Mkdir(tempGNUPGHOME, os.ModePerm)
Expect(err).To(BeNil())
origGNUPGHOME := os.Getenv("GNUPGHOME")
err = os.Setenv("GNUPGHOME", tempGNUPGHOME)
Expect(err).To(BeNil())
defer os.Setenv("GNUPGHOME", origGNUPGHOME)

port := 5000
session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "docker.io/registry:2.6"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
Skip("Cannot start docker registry.")
}

cmd := exec.Command("gpg", "--import", "sign/secret-key.asc")
err = cmd.Run()
Expect(err).To(BeNil())

cmd = exec.Command("cp", "/etc/containers/registries.d/default.yaml", "default.yaml")
if err = cmd.Run(); err != nil {
Skip("no signature store to verify")
}
defer func() {
cmd = exec.Command("cp", "default.yaml", "/etc/containers/registries.d/default.yaml")
cmd.Run()
}()

cmd = exec.Command("cp", "sign/key.gpg", "/tmp/key.gpg")
Expect(cmd.Run()).To(BeNil())
sigstore := `
default-docker:
sigstore: file:///var/lib/containers/sigstore
sigstore-staging: file:///var/lib/containers/sigstore
`
Expect(ioutil.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil())

session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

session = podmanTest.Podman([]string{"push", "--tls-verify=false", "--sign-by", "[email protected]", "localhost:5000/alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

session = podmanTest.Podman([]string{"rmi", ALPINE, "localhost:5000/alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

session = podmanTest.Podman([]string{"pull", "--tls-verify=false", "--signature-policy=sign/policy.json", "localhost:5000/alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))

outfile := filepath.Join(podmanTest.TempDir, "temp.tar")
save := podmanTest.Podman([]string{"save", "remove-signatures=true", "-o", outfile, "localhost:5000/alpine"})
save.WaitWithDefaultTimeout()
Expect(save).To(ExitWithError())
})

It("podman save image with digest reference", func() {
// pull a digest reference
session := podmanTest.PodmanNoCache([]string{"pull", ALPINELISTDIGEST})
Expand Down
30 changes: 30 additions & 0 deletions test/e2e/sign/key.gpg
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQENBF8kNqwBCAC0x3Kog+WlDNwcR6rWIP8Gj2T6LrQ2/3knSyAWzTgC/OBB6Oh0
KAokXLjy8J3diG3EaSltE7erGG/bZCz8jYvMiwDJScON4zzidotqjoY80E+NeRDg
CC0gqvqmh0ftJIjYNBHzSxqrGRQwzwZU+u6ezlE8+0dvsHcHY+MRnxXJQrdM07EP
Prp85kKckChDlJ1tyGUB/YHieFQmOW5+TERA7ZqQOAQ12Vviv6V4kNfEJJq3MS2c
csZpO323tcHt3oebqsZCIElhX7uVw6GAeCw1tm4NZXs4g1yIC21Of/hzPeC18F72
splCgKaAOiE9w/nMGLNEYy2NzgEclZLs2Y7jABEBAAG0FGZvb2JhciA8Zm9vQGJh
ci5jb20+iQFUBBMBCAA+FiEERyT4ac7LLibByeabqaoHAy6P2bIFAl8kNqwCGwMF
CQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQqaoHAy6P2bKtuggAgv54
/F8wgi+uMrtFr8rqNtZMDyXRxfXaXUy5uGNfqHD83yqxweEqxiA8lmFkRHixPWtg
Z2MniFXMVc9kVmg8GNIIuzewXrPqtXztvuURQo9phK68v8fXEqqT6K25wtq8TiQZ
0J3mQIJPPTMe3pCCOyR6+W3iMtQp2AmitxKbzLP3J3GG2i0rG5S147A2rPnzTeMY
hds819+JE7jNMD7FkV+TcQlOVl4wyOQhNEJcjb6rA6EUe5+s85pIFTBSyPMJpJ03
Y0dLdcSGpKdncGTK2X9+hS96G1+FP/t8hRIDblqUHtBRXe3Ozz6zSqpqu1DbAQSM
bIrLYxXfnZEN+ro0dLkBDQRfJDasAQgAncvLLZUHZkJWDPka3ocysJ7+/lmrXyAj
T3D4r7UM4oaLBOMKjvaKSDw1uW5qYmTxnnsqFDI0O5+XJxD1/0qEf6l2oUpnILdx
Vruf28FuvymbsyhDgs+MBoHz0jLWWPHUW2oWLIqcvaF0BePQ1GS6UoZlmZejsLww
cSpbaAHJng7An/iLuqOBr5EdUA5XMXqmdMFDrjh0uZezImJ2Eacu/hshBdu3IY49
J5XP18GWrSdUnP27cv3tOii9j5Lfl8QAvCN89vkALIU3eZtnMlWZqLgl5o6COVFm
zpyx+iHOoCznQBt0aGoSNmE/dAqWIQS/xCSFqMHI6kNd9N0oR0rEHwARAQABiQE8
BBgBCAAmFiEERyT4ac7LLibByeabqaoHAy6P2bIFAl8kNqwCGwwFCQPCZwAACgkQ
qaoHAy6P2bJfjQgAje6YR+p1QaNlTN9l4t2kGzy9RhkfYMrTgI2fEqbS9bFJUy3Y
3mH+vj/r2gN/kaN8LHH4K1d7fAohBsFqSI0flzHHIx2rfti9zAlbXcAErbnG+f0f
k0AaqU7KelU35vjPfNe6Vn7ky6G9CC6jW04NkLZDNFA2GusdYf1aM0LWew5t4WZa
quLVFhL36q9eHaogO/fcPR/quvQefHokk+b541ytwMN9l/g43rTbCvAjrUDHwipb
Gbw91Wg2XjbecRiCXDKWds2M149BpxUzY5xHFtD5t5WSEE/SkkryGTMmTxS3tuQZ
9PdtCPGrNDO6Ts/amORF04Tf+YMJgfv3IWxMeQ==
=y0uZ
-----END PGP PUBLIC KEY BLOCK-----
18 changes: 18 additions & 0 deletions test/e2e/sign/policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports": {
"docker": {
"localhost:5000": [
{
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "/tmp/key.gpg"
}
]
}
}
}

0 comments on commit 513c261

Please sign in to comment.