Skip to content
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

Controller for automatic image signature import #16293

Merged
merged 4 commits into from
Sep 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions Godeps/Godeps.json

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

11 changes: 9 additions & 2 deletions pkg/cmd/server/origin/controller/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ type OpenshiftControllerConfig struct {
DeploymentConfigControllerConfig DeploymentConfigControllerConfig
DeploymentTriggerControllerConfig DeploymentTriggerControllerConfig

ImageTriggerControllerConfig ImageTriggerControllerConfig
ImageImportControllerConfig ImageImportControllerConfig
ImageTriggerControllerConfig ImageTriggerControllerConfig
ImageSignatureImportControllerConfig ImageSignatureImportControllerConfig
ImageImportControllerConfig ImageImportControllerConfig

ServiceServingCertsControllerOptions ServiceServingCertsControllerOptions

Expand Down Expand Up @@ -80,6 +81,7 @@ func (c *OpenshiftControllerConfig) GetControllerInitializers() (map[string]Init

ret["openshift.io/image-trigger"] = c.ImageTriggerControllerConfig.RunController
ret["openshift.io/image-import"] = c.ImageImportControllerConfig.RunController
ret["openshift.io/image-signature-import"] = c.ImageSignatureImportControllerConfig.RunController

ret["openshift.io/templateinstance"] = RunTemplateInstanceController

Expand Down Expand Up @@ -203,6 +205,11 @@ func BuildOpenshiftControllerConfig(options configapi.MasterConfig) (*OpenshiftC
DisableScheduledImport: options.ImagePolicyConfig.DisableScheduledImport,
ScheduledImageImportMinimumIntervalSeconds: options.ImagePolicyConfig.ScheduledImageImportMinimumIntervalSeconds,
}
ret.ImageSignatureImportControllerConfig = ImageSignatureImportControllerConfig{
ResyncPeriod: 10 * time.Minute,
SignatureFetchTimeout: 1 * time.Minute,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deads2k ultimately we passing this to a context of containers/image where we do http.Get to fetch the sig data... This means after 1 minute we cancel the request and retry on next sync.

SignatureImportLimit: 3,
}

ret.ServiceServingCertsControllerOptions = ServiceServingCertsControllerOptions{
Signer: options.ControllerConfig.ServiceServingCert.Signer,
Expand Down
21 changes: 21 additions & 0 deletions pkg/cmd/server/origin/controller/image.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
"context"
"fmt"
"time"

Expand All @@ -18,6 +19,7 @@ import (
buildclient "github.com/openshift/origin/pkg/build/client"
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
imagecontroller "github.com/openshift/origin/pkg/image/controller"
imagesignaturecontroller "github.com/openshift/origin/pkg/image/controller/signature"
imagetriggercontroller "github.com/openshift/origin/pkg/image/controller/trigger"
triggerannotations "github.com/openshift/origin/pkg/image/trigger/annotations"
triggerbuildconfigs "github.com/openshift/origin/pkg/image/trigger/buildconfigs"
Expand Down Expand Up @@ -147,6 +149,25 @@ func (u podSpecUpdater) Update(obj runtime.Object) error {
}
}

type ImageSignatureImportControllerConfig struct {
ResyncPeriod time.Duration
SignatureFetchTimeout time.Duration
SignatureImportLimit int
}

func (c *ImageSignatureImportControllerConfig) RunController(ctx ControllerContext) (bool, error) {
controller := imagesignaturecontroller.NewSignatureImportController(
context.Background(),
ctx.ClientBuilder.OpenshiftInternalImageClientOrDie(bootstrappolicy.InfraImageImportControllerServiceAccountName),
ctx.ImageInformers.Image().InternalVersion().Images(),
c.ResyncPeriod,
c.SignatureFetchTimeout,
c.SignatureImportLimit,
)
go controller.Run(5, ctx.Stop)
return true, nil
}

type ImageImportControllerConfig struct {
MaxScheduledImageImportsPerMinute int
ScheduledImageImportMinimumIntervalSeconds int
Expand Down
62 changes: 62 additions & 0 deletions pkg/image/controller/signature/container_image_downloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package signature

import (
"context"
"crypto/sha256"
"fmt"
"time"

"github.com/containers/image/docker"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

imageapi "github.com/openshift/origin/pkg/image/apis/image"
)

type containerImageSignatureDownloader struct {
ctx context.Context
timeout time.Duration
}

func NewContainerImageSignatureDownloader(ctx context.Context, timeout time.Duration) SignatureDownloader {
return &containerImageSignatureDownloader{
ctx: ctx,
timeout: timeout,
}
}

func (s *containerImageSignatureDownloader) DownloadImageSignatures(image *imageapi.Image) ([]imageapi.ImageSignature, error) {
reference, err := docker.ParseReference("//" + image.DockerImageReference)
if err != nil {
return nil, err
}
source, err := reference.NewImageSource(nil, nil)
if err != nil {
return nil, err
}
defer source.Close()

ctx, cancel := context.WithTimeout(s.ctx, s.timeout)
defer cancel()

signatures, err := source.GetSignatures(ctx)
if err != nil {
return nil, err
}

ret := []imageapi.ImageSignature{}
for _, blob := range signatures {
sig := imageapi.ImageSignature{Type: imageapi.ImageSignatureTypeAtomicImageV1}
// This will use the name of the image (sha256:xxxx) and the SHA256 of the
// signature itself as the signature name has to be unique for each
// signature.
sig.Name = imageapi.JoinImageStreamImage(image.Name, fmt.Sprintf("%x", sha256.Sum256(blob)))
sig.Content = blob
sig.Annotations = map[string]string{
SignatureManagedAnnotation: "true",
}
sig.CreationTimestamp = metav1.Now()
ret = append(ret, sig)
}
return ret, nil
}
Loading