Skip to content

Commit

Permalink
Merge pull request #2397 from saschagrunert/sign-stage
Browse files Browse the repository at this point in the history
Integrate container image signing in `krel stage`
  • Loading branch information
k8s-ci-robot authored Mar 13, 2022
2 parents ae76869 + 0825de4 commit d8437e3
Show file tree
Hide file tree
Showing 7 changed files with 1,820 additions and 62 deletions.
1 change: 1 addition & 0 deletions gcb/release/cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ steps:
- "K8S_ORG=${_K8S_ORG}"
- "K8S_REPO=${_K8S_REPO}"
- "K8S_REF=${_K8S_REF}"
- GOOGLE_SERVICE_ACCOUNT_NAME=krel-staging@k8s-releng-prod.iam.gserviceaccount.com
secretEnv:
- GITHUB_TOKEN
args:
Expand Down
1 change: 1 addition & 0 deletions gcb/stage/cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ steps:
- "K8S_ORG=${_K8S_ORG}"
- "K8S_REPO=${_K8S_REPO}"
- "K8S_REF=${_K8S_REF}"
- GOOGLE_SERVICE_ACCOUNT_NAME=krel-staging@k8s-releng-prod.iam.gserviceaccount.com
secretEnv:
- GITHUB_TOKEN
- DOCKERHUB_TOKEN
Expand Down
272 changes: 234 additions & 38 deletions go.mod

Large diffs are not rendered by default.

1,360 changes: 1,338 additions & 22 deletions go.sum

Large diffs are not rendered by default.

41 changes: 39 additions & 2 deletions pkg/release/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"

"sigs.k8s.io/release-sdk/sign"
"sigs.k8s.io/release-utils/command"
)

// Images is a wrapper around container image related functionality.
type Images struct {
imageImpl
signer *sign.Signer
}

// NewImages creates a new Images instance
func NewImages() *Images {
return &Images{&defaultImageImpl{}}
return &Images{
imageImpl: &defaultImageImpl{},
signer: sign.New(sign.Default()),
}
}

// SetImpl can be used to set the internal image implementation.
Expand All @@ -51,6 +56,8 @@ type imageImpl interface {
Execute(cmd string, args ...string) error
ExecuteOutput(cmd string, args ...string) (string, error)
RepoTagFromTarball(path string) (string, error)
SignImage(*sign.Signer, string) error
VerifyImage(*sign.Signer, string) error
}

type defaultImageImpl struct{}
Expand Down Expand Up @@ -78,6 +85,16 @@ func (*defaultImageImpl) RepoTagFromTarball(path string) (string, error) {
return tagOutput.OutputTrimNL(), nil
}

func (*defaultImageImpl) SignImage(signer *sign.Signer, reference string) error {
_, err := signer.SignImage(reference)
return err
}

func (*defaultImageImpl) VerifyImage(signer *sign.Signer, reference string) error {
_, err := signer.VerifyImage(reference)
return err
}

var tagRegex = regexp.MustCompile(`^.+/(.+):.+$`)

// PublishImages releases container images to the provided target registry
Expand Down Expand Up @@ -113,6 +130,10 @@ func (i *Images) Publish(registry, version, buildPath string) error {
return errors.Wrap(err, "push container image")
}

if err := i.SignImage(i.signer, newTagWithArch); err != nil {
return errors.Wrap(err, "sign container image")
}

if err := i.Execute(
"docker", "rmi", origTag, newTagWithArch,
); err != nil {
Expand Down Expand Up @@ -166,6 +187,10 @@ func (i *Images) Publish(registry, version, buildPath string) error {
); err != nil {
return errors.Wrap(err, "push manifest")
}

if err := i.SignImage(i.signer, imageVersion); err != nil {
return errors.Wrap(err, "sign manifest list")
}
}

return nil
Expand All @@ -178,7 +203,14 @@ func (i *Images) Validate(registry, version, buildPath string) error {
version = i.normalizeVersion(version)

manifestImages, err := i.GetManifestImages(
registry, version, buildPath, nil,
registry, version, buildPath,
func(_, _, image string) error {
logrus.Infof("Verifying that image is signed: %s", image)
return errors.Wrap(
i.VerifyImage(i.signer, image),
"verify signed image",
)
},
)
if err != nil {
return errors.Wrap(err, "get manifest images")
Expand All @@ -195,6 +227,11 @@ func (i *Images) Validate(registry, version, buildPath string) error {
)
}

logrus.Info("Verifying that image manifest list is signed")
if err := i.VerifyImage(i.signer, imageVersion); err != nil {
return errors.Wrap(err, "verify signed manifest list")
}

manifest := string(manifestBytes)
manifestFile, err := os.CreateTemp("", "manifest-")
if err != nil {
Expand Down
53 changes: 53 additions & 0 deletions pkg/release/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,32 @@ func TestPublish(t *testing.T) {
},
shouldError: true,
},
{ // failure on sign image
prepare: func(mock *releasefakes.FakeImageImpl) (string, func()) {
tempDir := newImagesPath(t)
prepareImages(t, tempDir, mock)

mock.SignImageReturns(errors.New(""))

return tempDir, func() {
require.Nil(t, os.RemoveAll(tempDir))
}
},
shouldError: true,
},
{ // failure on sign manifest
prepare: func(mock *releasefakes.FakeImageImpl) (string, func()) {
tempDir := newImagesPath(t)
prepareImages(t, tempDir, mock)

mock.SignImageReturnsOnCall(10, errors.New(""))

return tempDir, func() {
require.Nil(t, os.RemoveAll(tempDir))
}
},
shouldError: true,
},
} {
sut := release.NewImages()
clientMock := &releasefakes.FakeImageImpl{}
Expand Down Expand Up @@ -285,6 +311,33 @@ func TestValidate(t *testing.T) {
},
shouldError: true,
},
{ // failure on signature verify of image
prepare: func(mock *releasefakes.FakeImageImpl) (string, func()) {
tempDir := newImagesPath(t)
prepareImages(t, tempDir, mock)

mock.VerifyImageReturns(errors.New(""))

return tempDir, func() {
require.Nil(t, os.RemoveAll(tempDir))
}
},
shouldError: true,
},
{ // failure on signature verify of manifest
prepare: func(mock *releasefakes.FakeImageImpl) (string, func()) {
tempDir := newImagesPath(t)
prepareImages(t, tempDir, mock)

mock.ExecuteOutputReturns("digest", nil)
mock.VerifyImageReturnsOnCall(10, errors.New(""))

return tempDir, func() {
require.Nil(t, os.RemoveAll(tempDir))
}
},
shouldError: true,
},
} {
sut := release.NewImages()
clientMock := &releasefakes.FakeImageImpl{}
Expand Down
154 changes: 154 additions & 0 deletions pkg/release/releasefakes/fake_image_impl.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d8437e3

Please sign in to comment.