From 6b09e1d9be38a653ef11e6dee1e6db45a40aa427 Mon Sep 17 00:00:00 2001 From: Ryan Cole Date: Fri, 29 May 2026 13:31:37 -0400 Subject: [PATCH] feat: add parent snapshot data to the snapshot status Some ComponentGroups are composed of other ComponentGroups. When a child ComponentGroup has a snapshot created, the integration service's snapshot controller will create snapshots for all parents as well. The new status field tracks which parent ComponentGroups have had snapshots created and what those snaphots are called. This prevents the integration service's snapshot controller from creating duplicate parent snaphots. Signed-off-by: Ryan Cole --- api/v1alpha1/snapshot_types.go | 19 ++++++ api/v1alpha1/zz_generated.deepcopy.go | 68 ++++++++++++++++--- .../bases/appstudio.redhat.com_snapshots.yaml | 22 ++++++ ...ication-api-customresourcedefinitions.yaml | 22 ++++++ 4 files changed, 123 insertions(+), 8 deletions(-) diff --git a/api/v1alpha1/snapshot_types.go b/api/v1alpha1/snapshot_types.go index 9a20bb1..f2bff79 100644 --- a/api/v1alpha1/snapshot_types.go +++ b/api/v1alpha1/snapshot_types.go @@ -81,6 +81,25 @@ type SnapshotStatus struct { // Conditions represent the latest available observations for the Snapshot // +optional Conditions []metav1.Condition `json:"conditions"` + + // ParentSnapshots contains a map of ComponentGroups that are parents of the + // ComponentGroup for which the snapshot was created and their corresponding + // snapshots + ParentSnapshots map[string]ParentSnapshotData `json:"parentSnapshots,omitempty"` +} + +type ParentSnapshotData struct { + // Name of the parent snapshot + // +optional + Name string `json:"name,omitempty"` + + // Whether the Snapshot has been created + Created bool `json:"created"` + + // If the snapshot could not be created, this will contain an error string + // If it was created, this will contain a success message + // +optional + Message string `json:"err,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 3218108..0d91bcd 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -191,9 +191,21 @@ func (in *ComponentActions) DeepCopy() *ComponentActions { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentBuildPipeline) DeepCopyInto(out *ComponentBuildPipeline) { *out = *in - out.PullAndPush = in.PullAndPush - out.Pull = in.Pull - out.Push = in.Push + if in.PullAndPush != nil { + in, out := &in.PullAndPush, &out.PullAndPush + *out = new(PipelineDefinition) + (*in).DeepCopyInto(*out) + } + if in.Pull != nil { + in, out := &in.Pull, &out.Pull + *out = new(PipelineDefinition) + (*in).DeepCopyInto(*out) + } + if in.Push != nil { + in, out := &in.Push, &out.Push + *out = new(PipelineDefinition) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentBuildPipeline. @@ -426,7 +438,9 @@ func (in *ComponentSourceUnion) DeepCopyInto(out *ComponentSourceUnion) { if in.Versions != nil { in, out := &in.Versions, &out.Versions *out = make([]ComponentVersion, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } @@ -464,7 +478,11 @@ func (in *ComponentSpec) DeepCopyInto(out *ComponentSpec) { } in.Actions.DeepCopyInto(&out.Actions) in.RepositorySettings.DeepCopyInto(&out.RepositorySettings) - out.DefaultBuildPipeline = in.DefaultBuildPipeline + if in.DefaultBuildPipeline != nil { + in, out := &in.DefaultBuildPipeline, &out.DefaultBuildPipeline + *out = new(ComponentBuildPipeline) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentSpec. @@ -514,7 +532,11 @@ func (in *ComponentStatus) DeepCopy() *ComponentStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentVersion) DeepCopyInto(out *ComponentVersion) { *out = *in - out.BuildPipeline = in.BuildPipeline + if in.BuildPipeline != nil { + in, out := &in.BuildPipeline, &out.BuildPipeline + *out = new(ComponentBuildPipeline) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersion. @@ -572,11 +594,34 @@ func (in *GitSource) DeepCopy() *GitSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParentSnapshotData) DeepCopyInto(out *ParentSnapshotData) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentSnapshotData. +func (in *ParentSnapshotData) DeepCopy() *ParentSnapshotData { + if in == nil { + return nil + } + out := new(ParentSnapshotData) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PipelineDefinition) DeepCopyInto(out *PipelineDefinition) { *out = *in - out.PipelineRefGit = in.PipelineRefGit - out.PipelineSpecFromBundle = in.PipelineSpecFromBundle + if in.PipelineRefGit != nil { + in, out := &in.PipelineRefGit, &out.PipelineRefGit + *out = new(PipelineRefGit) + **out = **in + } + if in.PipelineSpecFromBundle != nil { + in, out := &in.PipelineSpecFromBundle, &out.PipelineSpecFromBundle + *out = new(PipelineSpecFromBundle) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PipelineDefinition. @@ -767,6 +812,13 @@ func (in *SnapshotStatus) DeepCopyInto(out *SnapshotStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.ParentSnapshots != nil { + in, out := &in.ParentSnapshots, &out.ParentSnapshots + *out = make(map[string]ParentSnapshotData, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnapshotStatus. diff --git a/config/crd/bases/appstudio.redhat.com_snapshots.yaml b/config/crd/bases/appstudio.redhat.com_snapshots.yaml index 55f6502..b1978e3 100644 --- a/config/crd/bases/appstudio.redhat.com_snapshots.yaml +++ b/config/crd/bases/appstudio.redhat.com_snapshots.yaml @@ -471,6 +471,28 @@ spec: - type type: object type: array + parentSnapshots: + additionalProperties: + properties: + created: + description: Whether the Snapshot has been created + type: boolean + err: + description: |- + If the snapshot could not be created, this will contain an error string + If it was created, this will contain a success message + type: string + name: + description: Name of the parent snapshot + type: string + required: + - created + type: object + description: |- + ParentSnapshots contains a map of ComponentGroups that are parents of the + ComponentGroup for which the snapshot was created and their corresponding + snapshots + type: object type: object type: object served: true diff --git a/manifests/application-api-customresourcedefinitions.yaml b/manifests/application-api-customresourcedefinitions.yaml index bf22593..a7b6648 100644 --- a/manifests/application-api-customresourcedefinitions.yaml +++ b/manifests/application-api-customresourcedefinitions.yaml @@ -3985,6 +3985,28 @@ spec: - type type: object type: array + parentSnapshots: + additionalProperties: + properties: + created: + description: Whether the Snapshot has been created + type: boolean + err: + description: |- + If the snapshot could not be created, this will contain an error string + If it was created, this will contain a success message + type: string + name: + description: Name of the parent snapshot + type: string + required: + - created + type: object + description: |- + ParentSnapshots contains a map of ComponentGroups that are parents of the + ComponentGroup for which the snapshot was created and their corresponding + snapshots + type: object type: object type: object served: true