Skip to content
Draft
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
16 changes: 15 additions & 1 deletion api/v1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,14 @@ type BundleMetadata struct {
Version string `json:"version"`
}

type RevisionStatus struct {
Name string `json:"name"`
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// ClusterExtensionStatus defines the observed state of a ClusterExtension.
type ClusterExtensionStatus struct {
// The set of condition types which apply to all spec.source variations are Installed and Progressing.
Expand Down Expand Up @@ -499,6 +507,12 @@ type ClusterExtensionStatus struct {
//
// +optional
Install *ClusterExtensionInstallStatus `json:"install,omitempty"`

// +listType=map
// +listMapKey=name
// +optional
// <opcon:experimental>
ActiveRevisions []RevisionStatus `json:"activeRevisions,omitempty"`
}

// ClusterExtensionInstallStatus is a representation of the status of the identified bundle.
Expand All @@ -517,7 +531,7 @@ type ClusterExtensionInstallStatus struct {
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Installed Bundle",type=string,JSONPath=`.status.install.bundle.name`
// +kubebuilder:printcolumn:name=Version,type=string,JSONPath=`.status.install.bundle.version`
// +kubebuilder:printcolumn:name="Installed",type=string,JSONPath=`.status.conditions[?(@.type=='Installed')].status`
// +kubebuilder:printcolumn:name="Available",type=string,JSONPath=`.status.conditions[?(@.type=='Available')].status`
// +kubebuilder:printcolumn:name="Progressing",type=string,JSONPath=`.status.conditions[?(@.type=='Progressing')].status`
// +kubebuilder:printcolumn:name=Age,type=date,JSONPath=`.metadata.creationTimestamp`

Expand Down
51 changes: 49 additions & 2 deletions api/v1/clusterextensionrevision_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1

import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
Expand All @@ -26,8 +27,9 @@ const (
ClusterExtensionRevisionKind = "ClusterExtensionRevision"

// Condition Types
ClusterExtensionRevisionTypeAvailable = "Available"
ClusterExtensionRevisionTypeSucceeded = "Succeeded"
ClusterExtensionRevisionTypeAvailable = "Available"
ClusterExtensionRevisionTypeSucceeded = "Succeeded"
ClusterExtensionRevisionTypeProgressing = "Progressing"

// Condition Reasons
ClusterExtensionRevisionReasonAvailable = "Available"
Expand All @@ -37,9 +39,13 @@ const (
ClusterExtensionRevisionReasonObjectCollisions = "ObjectCollisions"
ClusterExtensionRevisionReasonRolloutSuccess = "RolloutSuccess"
ClusterExtensionRevisionReasonProbeFailure = "ProbeFailure"
ClusterExtensionRevisionReasonProbesSucceeded = "ProbesSucceeded"
ClusterExtensionRevisionReasonIncomplete = "Incomplete"
ClusterExtensionRevisionReasonProgressing = "Progressing"
ClusterExtensionRevisionReasonArchived = "Archived"
ClusterExtensionRevisionReasonRolloutInProgress = "RollingOut"
ClusterExtensionRevisionReasonRolloutError = "RolloutError"
ClusterExtensionRevisionReasonRolledOut = "RolledOut"
)

// ClusterExtensionRevisionSpec defines the desired state of ClusterExtensionRevision.
Expand Down Expand Up @@ -150,6 +156,7 @@ type ClusterExtensionRevisionStatus struct {

// ClusterExtensionRevision is the Schema for the clusterextensionrevisions API
// +kubebuilder:printcolumn:name="Available",type=string,JSONPath=`.status.conditions[?(@.type=='Available')].status`
// +kubebuilder:printcolumn:name="Progressing",type=string,JSONPath=`.status.conditions[?(@.type=='Progressing')].status`
// +kubebuilder:printcolumn:name=Age,type=date,JSONPath=`.metadata.creationTimestamp`
type ClusterExtensionRevision struct {
metav1.TypeMeta `json:",inline"`
Expand All @@ -164,6 +171,46 @@ type ClusterExtensionRevision struct {
Status ClusterExtensionRevisionStatus `json:"status,omitempty"`
}

func (cer *ClusterExtensionRevision) MarkAsProgressing(reason, message string) {
meta.SetStatusCondition(&cer.Status.Conditions, metav1.Condition{
Type: ClusterExtensionRevisionTypeProgressing,
Status: metav1.ConditionTrue,
Reason: reason,
Message: message,
ObservedGeneration: cer.Generation,
})
}

func (cer *ClusterExtensionRevision) MarkAsNotProgressing(reason, message string) {
meta.SetStatusCondition(&cer.Status.Conditions, metav1.Condition{
Type: ClusterExtensionRevisionTypeProgressing,
Status: metav1.ConditionFalse,
Reason: reason,
Message: message,
ObservedGeneration: cer.Generation,
})
}

func (cer *ClusterExtensionRevision) MarkAsAvailable(reason, message string) {
meta.SetStatusCondition(&cer.Status.Conditions, metav1.Condition{
Type: ClusterExtensionRevisionTypeAvailable,
Status: metav1.ConditionTrue,
Reason: reason,
Message: message,
ObservedGeneration: cer.Generation,
})
}

func (cer *ClusterExtensionRevision) MarkAsUnavailable(reason, message string) {
meta.SetStatusCondition(&cer.Status.Conditions, metav1.Condition{
Type: ClusterExtensionRevisionTypeAvailable,
Status: metav1.ConditionFalse,
Reason: reason,
Message: message,
ObservedGeneration: cer.Generation,
})
}

// +kubebuilder:object:root=true

// ClusterExtensionRevisionList contains a list of ClusterExtensionRevision
Expand Down
29 changes: 29 additions & 0 deletions api/v1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ spec:
- jsonPath: .status.conditions[?(@.type=='Available')].status
name: Available
type: string
- jsonPath: .status.conditions[?(@.type=='Progressing')].status
name: Progressing
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ spec:
- jsonPath: .status.install.bundle.version
name: Version
type: string
- jsonPath: .status.conditions[?(@.type=='Installed')].status
name: Installed
- jsonPath: .status.conditions[?(@.type=='Available')].status
name: Available
type: string
- jsonPath: .status.conditions[?(@.type=='Progressing')].status
name: Progressing
Expand Down Expand Up @@ -505,6 +505,78 @@ spec:
description: status is an optional field that defines the observed state
of the ClusterExtension.
properties:
activeRevisions:
items:
properties:
conditions:
items:
description: Condition contains details for one aspect of
the current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False,
Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
name:
type: string
required:
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
conditions:
description: |-
The set of condition types which apply to all spec.source variations are Installed and Progressing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ spec:
- jsonPath: .status.install.bundle.version
name: Version
type: string
- jsonPath: .status.conditions[?(@.type=='Installed')].status
name: Installed
- jsonPath: .status.conditions[?(@.type=='Available')].status
name: Available
type: string
- jsonPath: .status.conditions[?(@.type=='Progressing')].status
name: Progressing
Expand Down
2 changes: 0 additions & 2 deletions internal/operator-controller/applier/boxcutter.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,6 @@ func (bc *Boxcutter) apply(ctx context.Context, contentFS fs.FS, ext *ocv1.Clust
return false, "New revision created", nil
} else if progressingCondition != nil && progressingCondition.Status == metav1.ConditionTrue {
return false, progressingCondition.Message, nil
} else if availableCondition != nil && availableCondition.Status != metav1.ConditionTrue {
return false, "", errors.New(availableCondition.Message)
} else if succeededCondition != nil && succeededCondition.Status != metav1.ConditionTrue {
return false, succeededCondition.Message, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,32 +297,51 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1.Cl
// to ensure exponential backoff can occur:
// - Permission errors (it is not possible to watch changes to permissions.
// The only way to eventually recover from permission errors is to keep retrying).
rolloutSucceeded, rolloutStatus, err := r.Applier.Apply(ctx, imageFS, ext, objLbls, storeLbls)
_, _, err = r.Applier.Apply(ctx, imageFS, ext, objLbls, storeLbls)

// Set installed status
if rolloutSucceeded {
revisionStates = &RevisionStates{Installed: resolvedRevisionMetadata}
} else if err == nil && revisionStates.Installed == nil && len(revisionStates.RollingOut) == 0 {
revisionStates = &RevisionStates{RollingOut: []*RevisionMetadata{resolvedRevisionMetadata}}
}
setInstalledStatusFromRevisionStates(ext, revisionStates)
//if rolloutSucceeded {
// revisionStates = &RevisionStates{Installed: resolvedRevisionMetadata}
//} else if err == nil && revisionStates.Installed == nil && len(revisionStates.RollingOut) == 0 {
// revisionStates = &RevisionStates{RollingOut: []*RevisionMetadata{resolvedRevisionMetadata}}
//}
//setInstalledStatusFromRevisionStates(ext, revisionStates)

// If there was an error applying the resolved bundle,
// report the error via the Progressing condition.
if err != nil {
setStatusProgressing(ext, wrapErrorWithResolutionInfo(resolvedRevisionMetadata.BundleMetadata, err))
return ctrl.Result{}, err
} else if !rolloutSucceeded {
apimeta.SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
Type: ocv1.TypeProgressing,
Status: metav1.ConditionTrue,
Reason: ocv1.ReasonRolloutInProgress,
Message: rolloutStatus,
ObservedGeneration: ext.GetGeneration(),
})
} else {
setStatusProgressing(ext, nil)
}
//else if !rolloutSucceeded {
// apimeta.SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
// Type: ocv1.TypeProgressing,
// Status: metav1.ConditionTrue,
// Reason: ocv1.ReasonRolloutInProgress,
// Message: rolloutStatus,
// ObservedGeneration: ext.GetGeneration(),
// })
//} else {
// setStatusProgressing(ext, nil)
//}
if i := revisionStates.Installed; i != nil {
cnd := *apimeta.FindStatusCondition(i.Conditions, ocv1.ClusterExtensionRevisionTypeAvailable)
apimeta.SetStatusCondition(&ext.Status.Conditions, cnd)
ext.Status.Install = &ocv1.ClusterExtensionInstallStatus{
Bundle: i.BundleMetadata,
}
ext.Status.ActiveRevisions = []ocv1.RevisionStatus{{Name: i.RevName}}
apimeta.SetStatusCondition(&ext.Status.Conditions, *apimeta.FindStatusCondition(i.Conditions, ocv1.ClusterExtensionRevisionTypeProgressing))
}
if len(revisionStates.RollingOut) > 0 {
apimeta.SetStatusCondition(&ext.Status.Conditions, *apimeta.FindStatusCondition(revisionStates.RollingOut[0].Conditions, ocv1.ClusterExtensionRevisionTypeProgressing))
if len(ext.Status.ActiveRevisions) == 0 {
ext.Status.ActiveRevisions = []ocv1.RevisionStatus{{Name: revisionStates.RollingOut[0].RevName}}
} else {
ext.Status.ActiveRevisions = append(ext.Status.ActiveRevisions, ocv1.RevisionStatus{Name: revisionStates.RollingOut[0].RevName})
}
}

return ctrl.Result{}, nil
}

Expand Down Expand Up @@ -474,9 +493,11 @@ func clusterExtensionRequestsForCatalog(c client.Reader, logger logr.Logger) crh
}

type RevisionMetadata struct {
RevName string
Package string
Image string
ocv1.BundleMetadata
Conditions []metav1.Condition
}

type RevisionStates struct {
Expand Down Expand Up @@ -553,8 +574,10 @@ func (d *BoxcutterRevisionStatesGetter) GetRevisionStates(ctx context.Context, e
// is fairly decoupled from this code where we get the annotations back out. We may want to co-locate
// the set/get logic a bit better to make it more maintainable and less likely to get out of sync.
rm := &RevisionMetadata{
Package: rev.Labels[labels.PackageNameKey],
Image: rev.Annotations[labels.BundleReferenceKey],
RevName: rev.Name,
Package: rev.Labels[labels.PackageNameKey],
Image: rev.Annotations[labels.BundleReferenceKey],
Conditions: rev.Status.Conditions,
BundleMetadata: ocv1.BundleMetadata{
Name: rev.Annotations[labels.BundleNameKey],
Version: rev.Annotations[labels.BundleVersionKey],
Expand Down
Loading