Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
61 changes: 36 additions & 25 deletions pkg/cvo/updatepayload.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,25 @@ func (optr *Operator) defaultPayloadDir() string {

func (optr *Operator) defaultPayloadRetriever() PayloadRetriever {
return &payloadRetriever{
kubeClient: optr.kubeClient,
operatorName: optr.name,
releaseImage: optr.release.Image,
namespace: optr.namespace,
nodeName: optr.nodename,
payloadDir: optr.defaultPayloadDir(),
workingDir: targetUpdatePayloadsDir,
verifier: optr.verifier,
kubeClient: optr.kubeClient,
operatorName: optr.name,
releaseImage: optr.release.Image,
namespace: optr.namespace,
nodeName: optr.nodename,
payloadDir: optr.defaultPayloadDir(),
workingDir: targetUpdatePayloadsDir,
verifier: optr.verifier,
verifyTimeoutOnForce: 2 * time.Minute,
downloadTimeout: 2 * time.Minute,
}
}

const (
targetUpdatePayloadsDir = "/etc/cvo/updatepayloads"
)

type downloadFunc func(context.Context, configv1.Update) (string, error)
Comment thread
petr-muller marked this conversation as resolved.

type payloadRetriever struct {
// releaseImage and payloadDir are the default payload identifiers - updates that point
// to releaseImage will always use the contents of payloadDir
Expand All @@ -67,7 +71,11 @@ type payloadRetriever struct {
operatorName string

// verifier guards against invalid remote data being accessed
verifier verify.Interface
verifier verify.Interface
verifyTimeoutOnForce time.Duration

downloader downloadFunc
downloadTimeout time.Duration
}

func (r *payloadRetriever) RetrievePayload(ctx context.Context, update configv1.Update) (PayloadInfo, error) {
Expand All @@ -82,28 +90,28 @@ func (r *payloadRetriever) RetrievePayload(ctx context.Context, update configv1.
return PayloadInfo{}, fmt.Errorf("no payload image has been specified and the contents of the payload cannot be retrieved")
}

var info PayloadInfo

// verify the provided payload
var releaseDigest string
if index := strings.LastIndex(update.Image, "@"); index != -1 {
releaseDigest = update.Image[index+1:]
}
verifyCtx := ctx

// if 'force' specified, ensure call to verify payload signature times out well before parent context
// to allow time to perform forced update
if update.Force {
timeout := time.Minute * 2
if deadline, deadlineSet := ctx.Deadline(); deadlineSet {
timeout = time.Until(deadline) / 2
}
klog.V(2).Infof("Forced update so reducing payload signature verification timeout to %s", timeout)
var cancel context.CancelFunc
verifyCtx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()

var downloadCtx context.Context
var downloadCtxCancel context.CancelFunc
var verifyTimeout time.Duration

if deadline, ok := ctx.Deadline(); ok {
verifyTimeout = time.Until(deadline) / 2
downloadCtx = ctx
} else {
verifyTimeout = r.verifyTimeoutOnForce
downloadCtx, downloadCtxCancel = context.WithTimeout(ctx, r.verifyTimeoutOnForce+r.downloadTimeout)
Comment thread
petr-muller marked this conversation as resolved.
Outdated
defer downloadCtxCancel()
}
verifyCtx, verifyCtxCancel := context.WithTimeout(ctx, verifyTimeout)
defer verifyCtxCancel()

var info PayloadInfo
if err := r.verifier.Verify(verifyCtx, releaseDigest); err != nil {
vErr := &payload.UpdateError{
Reason: "ImageVerificationFailed",
Expand All @@ -120,9 +128,12 @@ func (r *payloadRetriever) RetrievePayload(ctx context.Context, update configv1.
info.Verified = true
}

if r.downloader == nil {
r.downloader = r.targetUpdatePayloadDir
}
// download the payload to the directory
var err error
info.Directory, err = r.targetUpdatePayloadDir(ctx, update)
info.Directory, err = r.downloader(downloadCtx, update)
if err != nil {
return PayloadInfo{}, &payload.UpdateError{
Reason: "UpdatePayloadRetrievalFailed",
Expand Down
Loading