Skip to content

Commit 26cb16d

Browse files
liamfallonCopilot
andauthored
Changes to the v1alpha2/v1 for independent subpackage support (#993)
* API v1alpha2/v1 changes for independent subpackage support Signed-off-by: liamfallon <liam.fallon@est.tech> * Fix copilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Add generated code Signed-off-by: liamfallon <liam.fallon@est.tech> * Address copilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Added LastSubpackageOperation field Signed-off-by: liamfallon <liam.fallon@est.tech> * Address CoPilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Kick CI Signed-off-by: liamfallon <liam.fallon@est.tech> * Added LastSubpackageOperation field Signed-off-by: liamfallon <liam.fallon@est.tech> * Address CoPilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Addressed Copilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Push generated code Signed-off-by: liamfallon <liam.fallon@est.tech> * API v1alpha2/v1 changes for independent subpackage support Signed-off-by: liamfallon <liam.fallon@est.tech> * Fix copilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Add generated code Signed-off-by: liamfallon <liam.fallon@est.tech> * Address copilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Added LastSubpackageOperation field Signed-off-by: liamfallon <liam.fallon@est.tech> * Address CoPilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Kick CI Signed-off-by: liamfallon <liam.fallon@est.tech> * Added LastSubpackageOperation field Signed-off-by: liamfallon <liam.fallon@est.tech> * Address CoPilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Addressed Copilot comments Signed-off-by: liamfallon <liam.fallon@est.tech> * Fix incinsisteht funciton name Signed-off-by: liamfallon <liam.fallon@est.tech> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: liamfallon <liam.fallon@est.tech> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 69532f7 commit 26cb16d

4 files changed

Lines changed: 345 additions & 2 deletions

File tree

api/porch/v1alpha1/util.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ func IsPackageCreation(pkgRev *PackageRevision) bool {
7373
return false
7474
}
7575

76-
// IsSubpackageSource checks if the package revision contains a subpackage operation
77-
func GetSubpackage(pkgRev *PackageRevision) string {
76+
// GetSubpackageDir returns the SubpackageDir for a package revision,
77+
// or "" if there is no SubpackageDir set.
78+
func GetSubpackageDir(pkgRev *PackageRevision) string {
7879
for _, task := range pkgRev.Spec.Tasks {
7980
if task.Type == TaskTypeClone {
8081
if task.Clone == nil || task.Clone.SubpackageDir == "" {

api/porch/v1alpha2/packagerevision_types.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ type PackageRevisionSpec struct {
135135
// +optional
136136
Source *PackageSource `json:"source,omitempty"`
137137

138+
// SubpackageOperation specifies an operation to be carried out on an independent subpackage
139+
// in the package.
140+
// When set, exactly one subpackage operation may be specified.
141+
// +optional
142+
SubpackageOperation *SubpackageOperation `json:"subpackageOperation,omitempty"`
143+
138144
// ReadinessGates specifies conditions that must be met before the package is considered ready.
139145
ReadinessGates []ReadinessGate `json:"readinessGates,omitempty"`
140146

@@ -193,6 +199,10 @@ type PackageRevisionStatus struct {
193199
// +optional
194200
CreationSource string `json:"creationSource,omitempty"`
195201

202+
// LastSubpackageOperation holds the last operation that was carried out on an independent subpackage
203+
// in the package. It is used to prevent re-execution of the same operation.
204+
LastSubpackageOperation *SubpackageOperation `json:"lastSubpackageOperation,omitempty"`
205+
196206
// PackageConditions from Kptfile. Set by KRM functions, used for ReadinessGates.
197207
PackageConditions []PackageCondition `json:"packageConditions,omitempty"`
198208

@@ -222,6 +232,34 @@ type PackageSource struct {
222232
Upgrade *PackageUpgradeSpec `json:"upgrade,omitempty"`
223233
}
224234

235+
// SubpackageOperation specifies an operation on an independent subpackage of a package.
236+
// Exactly one field must be set.
237+
// +kubebuilder:validation:XValidation:rule="[has(self.cloneFrom), has(self.upgrade)].filter(x, x).size() == 1",message="exactly one of cloneFrom or upgrade must be set"
238+
// +kubebuilder:validation:XValidation:rule="has(self.subpackageDir) && !self.subpackageDir.startsWith('/') && !self.subpackageDir.startsWith('./') && !self.subpackageDir.contains('../')",message="subpackageDir must be set and a valid relative path without leading '/' or './' and without '../' segments"
239+
type SubpackageOperation struct {
240+
// `SubpackageDir` is the path to a subdirectory in an existing package revision
241+
// into which the package specified in `CloneFrom` will be cloned as an
242+
// independent subpackage, or which identifies the independent subpackage whose
243+
// upstream will be upgraded by `Upgrade`.
244+
// It is a relative path within the package being modified by the subpackage
245+
// operation. The path may not have any leading or trailing '/', and may not
246+
// contain any path segment equal to '.' or '..'.
247+
// +kubebuilder:validation:Required
248+
// +kubebuilder:validation:MinLength=1
249+
// +kubebuilder:validation:Pattern=`^([^./][^/]*|\.[^./][^/]*|\.\.[^/]+)(/([^./][^/]*|\.[^./][^/]*|\.\.[^/]+))*$`
250+
SubpackageDir string `json:"subpackageDir"`
251+
252+
// `CloneFrom` specifies an upstream package from which to clone the independent
253+
// subpackage. The package specified in `CloneFrom` is cloned into the subdirectory specified
254+
// in `SubpackageDir`.
255+
CloneFrom *UpstreamPackage `json:"cloneFrom,omitempty"`
256+
257+
// `Upgrade` specifies an upgrade of the upstream package of the independent subpackage
258+
// in `SubpackageDir`. The independent subpackage in the subdirectory specified in `SubpackageDir`
259+
// is upgraded.
260+
Upgrade *PackageUpgradeSpec `json:"upgrade,omitempty"`
261+
}
262+
225263
// PackageCondition describes a condition from the Kptfile (package content).
226264
// This matches the structure of conditions in Kptfile and is used for ReadinessGates validation.
227265
type PackageCondition struct {

api/porch/v1alpha2/porch.kpt.dev_packagerevisions.yaml

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,141 @@ spec:
260260
be set
261261
rule: '[has(self.init), has(self.cloneFrom), has(self.copyFrom),
262262
has(self.upgrade)].filter(x, x).size() == 1'
263+
subpackageOperation:
264+
description: |-
265+
SubpackageOperation specifies an operation to be carried out on an independent subpackage
266+
in the package.
267+
When set, exactly one subpackage operation may be specified.
268+
properties:
269+
cloneFrom:
270+
description: |-
271+
`CloneFrom` specifies an upstream package from which to clone the independent
272+
subpackage. The package specified in `CloneFrom` is cloned into the subdirectory specified
273+
in `SubpackageDir`.
274+
properties:
275+
git:
276+
description: Git upstream package specification. Required
277+
if type is git.
278+
properties:
279+
directory:
280+
description: Directory within the Git repository where
281+
the packages are stored.
282+
type: string
283+
ref:
284+
description: Ref is the git ref containing the package.
285+
Ref can be a branch, tag, or commit SHA.
286+
type: string
287+
repo:
288+
description: |-
289+
Repo is the address of the Git repository, for example:
290+
https://github.com/GoogleCloudPlatform/blueprints.git
291+
type: string
292+
secretRef:
293+
description: SecretRef is a reference to secret containing
294+
authentication credentials.
295+
properties:
296+
name:
297+
type: string
298+
required:
299+
- name
300+
type: object
301+
required:
302+
- directory
303+
- ref
304+
- repo
305+
type: object
306+
type:
307+
description: Type of the repository (i.e. git). If empty,
308+
upstreamRef will be used.
309+
enum:
310+
- git
311+
type: string
312+
upstreamRef:
313+
description: UpstreamRef is the reference to the package from
314+
a registered repository.
315+
properties:
316+
name:
317+
type: string
318+
required:
319+
- name
320+
type: object
321+
type: object
322+
subpackageDir:
323+
description: |-
324+
`SubpackageDir` is the path to a subdirectory in an existing package revision
325+
into which the package specified in `CloneFrom` will be cloned as an
326+
independent subpackage, or which identifies the independent subpackage whose
327+
upstream will be upgraded by `Upgrade`.
328+
It is a relative path within the package being modified by the subpackage
329+
operation. The path may not have any leading or trailing '/', and may not
330+
contain any path segment equal to '.' or '..'.
331+
minLength: 1
332+
pattern: ^([^./][^/]*|\.[^./][^/]*|\.\.[^/]+)(/([^./][^/]*|\.[^./][^/]*|\.\.[^/]+))*$
333+
type: string
334+
upgrade:
335+
description: |-
336+
`Upgrade` specifies an upgrade of the upstream package of the independent subpackage
337+
in `SubpackageDir`. The independent subpackage in the subdirectory specified in `SubpackageDir`
338+
is upgraded.
339+
properties:
340+
currentPackage:
341+
description: |-
342+
CurrentPackage is the reference to the current local package revision that
343+
contains all the local changes on top of the OldUpstream package revision.
344+
properties:
345+
name:
346+
type: string
347+
required:
348+
- name
349+
type: object
350+
newUpstream:
351+
description: |-
352+
NewUpstream is the reference to the new upstream package revision that the
353+
local package will be upgraded to.
354+
properties:
355+
name:
356+
type: string
357+
required:
358+
- name
359+
type: object
360+
oldUpstream:
361+
description: |-
362+
OldUpstream is the reference to the original upstream package revision that is
363+
the common ancestor of the local package and the new upstream package revision.
364+
properties:
365+
name:
366+
type: string
367+
required:
368+
- name
369+
type: object
370+
strategy:
371+
description: |-
372+
Strategy defines which strategy should be used to update the package. It defaults to 'resource-merge'.
373+
* resource-merge: Perform a structural comparison of the original /
374+
updated resources, and merge the changes into the local package.
375+
* fast-forward: Fail without updating if the local package was modified
376+
since it was fetched.
377+
* force-delete-replace: Wipe all the local changes to the package and replace
378+
it with the remote version.
379+
* copy-merge: Copy all the remote changes to the local package.
380+
enum:
381+
- resource-merge
382+
- fast-forward
383+
- force-delete-replace
384+
- copy-merge
385+
type: string
386+
type: object
387+
required:
388+
- subpackageDir
389+
type: object
390+
x-kubernetes-validations:
391+
- message: exactly one of cloneFrom or upgrade must be set
392+
rule: '[has(self.cloneFrom), has(self.upgrade)].filter(x, x).size()
393+
== 1'
394+
- message: subpackageDir must be set and a valid relative path without
395+
leading '/' or './' and without '../' segments
396+
rule: has(self.subpackageDir) && !self.subpackageDir.startsWith('/')
397+
&& !self.subpackageDir.startsWith('./') && !self.subpackageDir.contains('../')
263398
workspaceName:
264399
description: WorkspaceName is a short, unique description of the changes
265400
contained in this package revision.
@@ -338,6 +473,140 @@ spec:
338473
description: Deployment is true if this is a deployment package (in
339474
a deployment repository).
340475
type: boolean
476+
lastSubpackageOperation:
477+
description: |-
478+
LastSubpackageOperation holds the last operation that was carried out on an independent subpackage
479+
in the package. It is used to prevent re-execution of the same operation.
480+
properties:
481+
cloneFrom:
482+
description: |-
483+
`CloneFrom` specifies an upstream package from which to clone the independent
484+
subpackage. The package specified in `CloneFrom` is cloned into the subdirectory specified
485+
in `SubpackageDir`.
486+
properties:
487+
git:
488+
description: Git upstream package specification. Required
489+
if type is git.
490+
properties:
491+
directory:
492+
description: Directory within the Git repository where
493+
the packages are stored.
494+
type: string
495+
ref:
496+
description: Ref is the git ref containing the package.
497+
Ref can be a branch, tag, or commit SHA.
498+
type: string
499+
repo:
500+
description: |-
501+
Repo is the address of the Git repository, for example:
502+
https://github.com/GoogleCloudPlatform/blueprints.git
503+
type: string
504+
secretRef:
505+
description: SecretRef is a reference to secret containing
506+
authentication credentials.
507+
properties:
508+
name:
509+
type: string
510+
required:
511+
- name
512+
type: object
513+
required:
514+
- directory
515+
- ref
516+
- repo
517+
type: object
518+
type:
519+
description: Type of the repository (i.e. git). If empty,
520+
upstreamRef will be used.
521+
enum:
522+
- git
523+
type: string
524+
upstreamRef:
525+
description: UpstreamRef is the reference to the package from
526+
a registered repository.
527+
properties:
528+
name:
529+
type: string
530+
required:
531+
- name
532+
type: object
533+
type: object
534+
subpackageDir:
535+
description: |-
536+
`SubpackageDir` is the path to a subdirectory in an existing package revision
537+
into which the package specified in `CloneFrom` will be cloned as an
538+
independent subpackage, or which identifies the independent subpackage whose
539+
upstream will be upgraded by `Upgrade`.
540+
It is a relative path within the package being modified by the subpackage
541+
operation. The path may not have any leading or trailing '/', and may not
542+
contain any path segment equal to '.' or '..'.
543+
minLength: 1
544+
pattern: ^([^./][^/]*|\.[^./][^/]*|\.\.[^/]+)(/([^./][^/]*|\.[^./][^/]*|\.\.[^/]+))*$
545+
type: string
546+
upgrade:
547+
description: |-
548+
`Upgrade` specifies an upgrade of the upstream package of the independent subpackage
549+
in `SubpackageDir`. The independent subpackage in the subdirectory specified in `SubpackageDir`
550+
is upgraded.
551+
properties:
552+
currentPackage:
553+
description: |-
554+
CurrentPackage is the reference to the current local package revision that
555+
contains all the local changes on top of the OldUpstream package revision.
556+
properties:
557+
name:
558+
type: string
559+
required:
560+
- name
561+
type: object
562+
newUpstream:
563+
description: |-
564+
NewUpstream is the reference to the new upstream package revision that the
565+
local package will be upgraded to.
566+
properties:
567+
name:
568+
type: string
569+
required:
570+
- name
571+
type: object
572+
oldUpstream:
573+
description: |-
574+
OldUpstream is the reference to the original upstream package revision that is
575+
the common ancestor of the local package and the new upstream package revision.
576+
properties:
577+
name:
578+
type: string
579+
required:
580+
- name
581+
type: object
582+
strategy:
583+
description: |-
584+
Strategy defines which strategy should be used to update the package. It defaults to 'resource-merge'.
585+
* resource-merge: Perform a structural comparison of the original /
586+
updated resources, and merge the changes into the local package.
587+
* fast-forward: Fail without updating if the local package was modified
588+
since it was fetched.
589+
* force-delete-replace: Wipe all the local changes to the package and replace
590+
it with the remote version.
591+
* copy-merge: Copy all the remote changes to the local package.
592+
enum:
593+
- resource-merge
594+
- fast-forward
595+
- force-delete-replace
596+
- copy-merge
597+
type: string
598+
type: object
599+
required:
600+
- subpackageDir
601+
type: object
602+
x-kubernetes-validations:
603+
- message: exactly one of cloneFrom or upgrade must be set
604+
rule: '[has(self.cloneFrom), has(self.upgrade)].filter(x, x).size()
605+
== 1'
606+
- message: subpackageDir must be set and a valid relative path without
607+
leading '/' or './' and without '../' segments
608+
rule: has(self.subpackageDir) && !self.subpackageDir.startsWith('/')
609+
&& !self.subpackageDir.startsWith('./') && !self.subpackageDir.contains('../')
341610
observedGeneration:
342611
description: ObservedGeneration is the generation of the PackageRevision
343612
spec that was last reconciled.

0 commit comments

Comments
 (0)