diff --git a/docs/docs/40-admin/03-computeclasses.md b/docs/docs/40-admin/03-computeclasses.md index 1445417d8..58b322c03 100644 --- a/docs/docs/40-admin/03-computeclasses.md +++ b/docs/docs/40-admin/03-computeclasses.md @@ -40,6 +40,7 @@ affinity: # The same affinity fields for Pods operator: In values: - bar +supportedRegions: ["local"] # should always be set to ["local"] ``` If `memory.min`, `memory.max`, `memory.values`, `affinity`, and `tolerations` are not given, then there are no scheduling rules for workloads using the compute class. diff --git a/pkg/apis/internal.acorn.io/v1/appinstance.go b/pkg/apis/internal.acorn.io/v1/appinstance.go index deccdebca..9e8b7d879 100644 --- a/pkg/apis/internal.acorn.io/v1/appinstance.go +++ b/pkg/apis/internal.acorn.io/v1/appinstance.go @@ -15,6 +15,7 @@ type AppInstanceCondition string var ( AppInstanceConditionDefined = "defined" AppInstanceConditionDefaults = "defaults" + AppInstanceConditionResolvedOfferings = "resolved-offerings" AppInstanceConditionScheduling = "scheduling" AppInstanceConditionNamespace = "namespace" AppInstanceConditionParsed = "parsed" @@ -210,6 +211,7 @@ type AppInstanceStatus struct { Scheduling map[string]Scheduling `json:"scheduling,omitempty"` Conditions []Condition `json:"conditions,omitempty"` Defaults Defaults `json:"defaults,omitempty"` + ResolvedOfferings ResolvedOfferings `json:"resolvedOfferings,omitempty"` Summary CommonSummary `json:"summary,omitempty"` Permissions []Permissions `json:"permissions,omitempty"` // Permissions given to this appInstance (only containers within, not nested Acorns/Services) DeniedConsumerPermissions []Permissions `json:"deniedConsumerPermissions,omitempty"` // Permissions given to this appInstance by a consumed service, which it is not authorized to have @@ -242,6 +244,25 @@ type VolumeDefault struct { AccessModes AccessModes `json:"accessModes,omitempty"` } +type ResolvedOfferings struct { + Volumes map[string]VolumeResolvedOffering `json:"volumes,omitempty"` + VolumeSize *resource.Quantity `json:"volumeSize,omitempty"` + Containers map[string]ContainerResolvedOffering `json:"containers,omitempty"` + Region string `json:"region,omitempty"` +} + +type VolumeResolvedOffering struct { + Class string `json:"class,omitempty"` + Size Quantity `json:"size,omitempty"` + AccessModes AccessModes `json:"accessModes,omitempty"` +} + +type ContainerResolvedOffering struct { + Class string `json:"class,omitempty"` + Memory *int64 `json:"memory,omitempty"` + CPUScaler *float64 `json:"cpuScaler,omitempty"` +} + type Scheduling struct { Requirements corev1.ResourceRequirements `json:"requirements,omitempty"` Affinity *corev1.Affinity `json:"affinity,omitempty"` diff --git a/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go b/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go index 4723a1893..3a66fd5dd 100644 --- a/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go +++ b/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go @@ -585,6 +585,7 @@ func (in *AppInstanceStatus) DeepCopyInto(out *AppInstanceStatus) { } } in.Defaults.DeepCopyInto(&out.Defaults) + in.ResolvedOfferings.DeepCopyInto(&out.ResolvedOfferings) in.Summary.DeepCopyInto(&out.Summary) if in.Permissions != nil { in, out := &in.Permissions, &out.Permissions @@ -1344,6 +1345,31 @@ func (in *ContainerImageBuilderSpec) DeepCopy() *ContainerImageBuilderSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResolvedOffering) DeepCopyInto(out *ContainerResolvedOffering) { + *out = *in + if in.Memory != nil { + in, out := &in.Memory, &out.Memory + *out = new(int64) + **out = **in + } + if in.CPUScaler != nil { + in, out := &in.CPUScaler, &out.CPUScaler + *out = new(float64) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResolvedOffering. +func (in *ContainerResolvedOffering) DeepCopy() *ContainerResolvedOffering { + if in == nil { + return nil + } + out := new(ContainerResolvedOffering) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContainerStatus) DeepCopyInto(out *ContainerStatus) { *out = *in @@ -2784,6 +2810,40 @@ func (in *ReplicasSummary) DeepCopy() *ReplicasSummary { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResolvedOfferings) DeepCopyInto(out *ResolvedOfferings) { + *out = *in + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make(map[string]VolumeResolvedOffering, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.VolumeSize != nil { + in, out := &in.VolumeSize, &out.VolumeSize + x := (*in).DeepCopy() + *out = &x + } + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make(map[string]ContainerResolvedOffering, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResolvedOfferings. +func (in *ResolvedOfferings) DeepCopy() *ResolvedOfferings { + if in == nil { + return nil + } + out := new(ResolvedOfferings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Route) DeepCopyInto(out *Route) { *out = *in @@ -3672,6 +3732,26 @@ func (in *VolumeRequest) DeepCopy() *VolumeRequest { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeResolvedOffering) DeepCopyInto(out *VolumeResolvedOffering) { + *out = *in + if in.AccessModes != nil { + in, out := &in.AccessModes, &out.AccessModes + *out = make(AccessModes, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeResolvedOffering. +func (in *VolumeResolvedOffering) DeepCopy() *VolumeResolvedOffering { + if in == nil { + return nil + } + out := new(VolumeResolvedOffering) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeSecretMount) DeepCopyInto(out *VolumeSecretMount) { *out = *in diff --git a/pkg/cli/testdata/TestAll/acorn_all_-o_json.golden b/pkg/cli/testdata/TestAll/acorn_all_-o_json.golden index 0b362c571..6a1ce4f7c 100644 --- a/pkg/cli/testdata/TestAll/acorn_all_-o_json.golden +++ b/pkg/cli/testdata/TestAll/acorn_all_-o_json.golden @@ -32,6 +32,7 @@ ACORNS: "appSpec": {}, "appStatus": {}, "defaults": {}, + "resolvedOfferings": {}, "summary": {} } } diff --git a/pkg/cli/testdata/TestAll/acorn_all_-o_yaml.golden b/pkg/cli/testdata/TestAll/acorn_all_-o_yaml.golden index a8f6731ff..7ea83f2ba 100644 --- a/pkg/cli/testdata/TestAll/acorn_all_-o_yaml.golden +++ b/pkg/cli/testdata/TestAll/acorn_all_-o_yaml.golden @@ -18,6 +18,7 @@ items: appStatus: {} columns: {} defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/deploy.go b/pkg/controller/appdefinition/deploy.go index fa2c20270..d9dd1495b 100644 --- a/pkg/controller/appdefinition/deploy.go +++ b/pkg/controller/appdefinition/deploy.go @@ -597,12 +597,34 @@ func containerAnnotation(container v1.Container) string { return string(json) } +func resolvedOfferingsAnnotation(appInstance *v1.AppInstance, container v1.Container) (string, error) { + if resolved, exists := appInstance.Status.ResolvedOfferings.Containers[container.Name]; exists { + data, err := convert.EncodeToMap(resolved) + if err != nil { + return "", err + } + + j, err := json.Marshal(data) + if err != nil { + return "", err + } + + return string(j), nil + } + return "", nil +} + func podAnnotations(appInstance *v1.AppInstance, container v1.Container) map[string]string { annotations := map[string]string{ labels.AcornContainerSpec: containerAnnotation(container), } addPrometheusAnnotations(annotations, container) + offerings, err := resolvedOfferingsAnnotation(appInstance, container) + if err == nil && offerings != "" { + annotations[labels.AcornContainerResolvedOfferings] = offerings + } + images := map[string]string{} addImageAnnotations(images, appInstance, container) diff --git a/pkg/controller/appdefinition/testdata/TestComputeMem.golden b/pkg/controller/appdefinition/testdata/TestComputeMem.golden index 9f160e2a5..fd9ac2f51 100644 --- a/pkg/controller/appdefinition/testdata/TestComputeMem.golden +++ b/pkg/controller/appdefinition/testdata/TestComputeMem.golden @@ -117,6 +117,7 @@ status: appStatus: {} columns: {} defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} @@ -158,6 +159,7 @@ status: appStatus: {} columns: {} defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} @@ -202,6 +204,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/acorn/basic/expected.golden b/pkg/controller/appdefinition/testdata/acorn/basic/expected.golden index a86ce4724..040f6b038 100644 --- a/pkg/controller/appdefinition/testdata/acorn/basic/expected.golden +++ b/pkg/controller/appdefinition/testdata/acorn/basic/expected.golden @@ -133,6 +133,7 @@ status: appStatus: {} columns: {} defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} @@ -214,6 +215,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/acorn/labels/expected.golden b/pkg/controller/appdefinition/testdata/acorn/labels/expected.golden index 94f10fed6..a7f8c8577 100644 --- a/pkg/controller/appdefinition/testdata/acorn/labels/expected.golden +++ b/pkg/controller/appdefinition/testdata/acorn/labels/expected.golden @@ -151,6 +151,7 @@ status: appStatus: {} columns: {} defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} @@ -256,6 +257,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/assignnamespace/expected.golden b/pkg/controller/appdefinition/testdata/assignnamespace/expected.golden index b101e1c8c..8df685cda 100644 --- a/pkg/controller/appdefinition/testdata/assignnamespace/expected.golden +++ b/pkg/controller/appdefinition/testdata/assignnamespace/expected.golden @@ -21,6 +21,7 @@ status: type: namespace defaults: {} namespace: default-1234567890ab + resolvedOfferings: {} staged: appImage: buildContext: {} @@ -52,6 +53,7 @@ status: type: namespace defaults: {} namespace: default-1234567890ab + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/autoupgrade/with-local-image/expected.golden b/pkg/controller/appdefinition/testdata/autoupgrade/with-local-image/expected.golden index 518c57d7f..58e84f910 100644 --- a/pkg/controller/appdefinition/testdata/autoupgrade/with-local-image/expected.golden +++ b/pkg/controller/appdefinition/testdata/autoupgrade/with-local-image/expected.golden @@ -23,6 +23,7 @@ status: type: image-pull defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/computeclass/all-set-overwrite-computeclass/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/all-set-overwrite-computeclass/expected.golden index 753f7bcfc..bf29ece21 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/all-set-overwrite-computeclass/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/all-set-overwrite-computeclass/expected.golden @@ -240,6 +240,7 @@ status: oneimage: 2097152 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/computeclass/all-set/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/all-set/expected.golden index c8439e019..30ae770e0 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/all-set/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/all-set/expected.golden @@ -239,6 +239,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/computeclass/container/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/container/expected.golden index f22484471..daf0c8336 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/container/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/container/expected.golden @@ -239,6 +239,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/computeclass/different-computeclass/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/different-computeclass/expected.golden index ab86edaf4..840683204 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/different-computeclass/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/different-computeclass/expected.golden @@ -388,6 +388,7 @@ status: twoimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: oneimage: affinity: diff --git a/pkg/controller/appdefinition/testdata/computeclass/job/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/job/expected.golden index d55c1e3ef..b21a4ca1b 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/job/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/job/expected.golden @@ -238,6 +238,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden index 3d86319f1..a89c0dbaa 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden @@ -240,6 +240,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/computeclass/two-containers/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/two-containers/expected.golden index fbe43e572..1af74a016 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/two-containers/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/two-containers/expected.golden @@ -373,6 +373,7 @@ status: twoimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: oneimage: affinity: diff --git a/pkg/controller/appdefinition/testdata/computeclass/with-acornfile-computeclass/expected.golden b/pkg/controller/appdefinition/testdata/computeclass/with-acornfile-computeclass/expected.golden index 51ed2acd7..2ce23f2ed 100644 --- a/pkg/controller/appdefinition/testdata/computeclass/with-acornfile-computeclass/expected.golden +++ b/pkg/controller/appdefinition/testdata/computeclass/with-acornfile-computeclass/expected.golden @@ -238,6 +238,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/depends-ready/expected.golden b/pkg/controller/appdefinition/testdata/depends-ready/expected.golden index 2f1522d5f..3b68b26ba 100644 --- a/pkg/controller/appdefinition/testdata/depends-ready/expected.golden +++ b/pkg/controller/appdefinition/testdata/depends-ready/expected.golden @@ -307,6 +307,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/depends/expected.golden b/pkg/controller/appdefinition/testdata/depends/expected.golden index 196da524b..112584e0d 100644 --- a/pkg/controller/appdefinition/testdata/depends/expected.golden +++ b/pkg/controller/appdefinition/testdata/depends/expected.golden @@ -311,6 +311,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/basic/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/basic/expected.golden index a028b5f70..85eb3c17b 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/basic/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/basic/expected.golden @@ -323,6 +323,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/filter-user-labels/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/filter-user-labels/expected.golden index 00b17fa2e..85b02dceb 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/filter-user-labels/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/filter-user-labels/expected.golden @@ -458,6 +458,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/karpenter/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/karpenter/expected.golden index 14b2a2576..6b3d2825a 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/karpenter/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/karpenter/expected.golden @@ -380,6 +380,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/labels/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/labels/expected.golden index 433591b2a..e547f2bf0 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/labels/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/labels/expected.golden @@ -464,6 +464,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/metrics/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/metrics/expected.golden index 0c9f1513d..b0e1c1666 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/metrics/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/metrics/expected.golden @@ -185,6 +185,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/no-user-labels/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/no-user-labels/expected.golden index c8f2931de..954974543 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/no-user-labels/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/no-user-labels/expected.golden @@ -331,6 +331,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/basic/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/basic/expected.golden index 5580aa20a..1f0b13a37 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/basic/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/basic/expected.golden @@ -356,6 +356,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/dev/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/dev/expected.golden index 48fcbbf4b..740c7c15c 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/dev/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/dev/expected.golden @@ -329,6 +329,7 @@ status: sessionStartTime: null sessionTimeoutSeconds: 60 namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/job/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/job/expected.golden index 2bff587a0..f84d10ab5 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/job/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/job/expected.golden @@ -204,6 +204,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/no-ports/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/no-ports/expected.golden index 7313fda09..e54547dac 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/no-ports/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/no-ports/expected.golden @@ -268,6 +268,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/ports-only-sidecar/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/ports-only-sidecar/expected.golden index 73f601540..a82c77226 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/ports-only-sidecar/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/ports-only-sidecar/expected.golden @@ -335,6 +335,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/stateful/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/stateful/expected.golden index 76b530280..29fc646d3 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/pre-stop/stateful/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/pre-stop/stateful/expected.golden @@ -227,6 +227,7 @@ status: class: test-custom-class size: 3Gi namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/scale/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/scale/expected.golden index fdbd5ffb5..a1baef373 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/scale/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/scale/expected.golden @@ -260,6 +260,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/deployspec/stop/expected.golden b/pkg/controller/appdefinition/testdata/deployspec/stop/expected.golden index 1d48b868a..6b4eeb03c 100644 --- a/pkg/controller/appdefinition/testdata/deployspec/stop/expected.golden +++ b/pkg/controller/appdefinition/testdata/deployspec/stop/expected.golden @@ -261,6 +261,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/files-bug/expected.golden b/pkg/controller/appdefinition/testdata/files-bug/expected.golden index afc121717..313660746 100644 --- a/pkg/controller/appdefinition/testdata/files-bug/expected.golden +++ b/pkg/controller/appdefinition/testdata/files-bug/expected.golden @@ -186,6 +186,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/files/expected.golden b/pkg/controller/appdefinition/testdata/files/expected.golden index d43240798..65bdf11b4 100644 --- a/pkg/controller/appdefinition/testdata/files/expected.golden +++ b/pkg/controller/appdefinition/testdata/files/expected.golden @@ -218,6 +218,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/globalenv/expected.golden b/pkg/controller/appdefinition/testdata/globalenv/expected.golden index ac5d939ed..69233ae8d 100644 --- a/pkg/controller/appdefinition/testdata/globalenv/expected.golden +++ b/pkg/controller/appdefinition/testdata/globalenv/expected.golden @@ -190,6 +190,7 @@ status: appStatus: {} columns: {} defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} @@ -241,6 +242,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/ingress/basic/expected.golden b/pkg/controller/appdefinition/testdata/ingress/basic/expected.golden index d337c144e..a2df90bff 100644 --- a/pkg/controller/appdefinition/testdata/ingress/basic/expected.golden +++ b/pkg/controller/appdefinition/testdata/ingress/basic/expected.golden @@ -393,6 +393,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/ingress/clusterdomainport/expected.golden b/pkg/controller/appdefinition/testdata/ingress/clusterdomainport/expected.golden index c32622804..a5b91eabc 100644 --- a/pkg/controller/appdefinition/testdata/ingress/clusterdomainport/expected.golden +++ b/pkg/controller/appdefinition/testdata/ingress/clusterdomainport/expected.golden @@ -186,6 +186,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/ingress/labels/expected.golden b/pkg/controller/appdefinition/testdata/ingress/labels/expected.golden index b20bb6058..7617ec5a8 100644 --- a/pkg/controller/appdefinition/testdata/ingress/labels/expected.golden +++ b/pkg/controller/appdefinition/testdata/ingress/labels/expected.golden @@ -262,6 +262,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/ingress/letsencrypt/expected.golden b/pkg/controller/appdefinition/testdata/ingress/letsencrypt/expected.golden index 0a1b5ff82..cf6f7ed70 100644 --- a/pkg/controller/appdefinition/testdata/ingress/letsencrypt/expected.golden +++ b/pkg/controller/appdefinition/testdata/ingress/letsencrypt/expected.golden @@ -355,6 +355,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-1/expected.golden b/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-1/expected.golden index 5adec7492..d9e52253d 100644 --- a/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-1/expected.golden +++ b/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-1/expected.golden @@ -264,6 +264,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-2/expected.golden b/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-2/expected.golden index f9029bea9..c1ad2e918 100644 --- a/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-2/expected.golden +++ b/pkg/controller/appdefinition/testdata/ingress/prefix/prefix-2/expected.golden @@ -264,6 +264,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/interpolation/expected.golden b/pkg/controller/appdefinition/testdata/interpolation/expected.golden index 69b515efd..cd85363b3 100644 --- a/pkg/controller/appdefinition/testdata/interpolation/expected.golden +++ b/pkg/controller/appdefinition/testdata/interpolation/expected.golden @@ -184,6 +184,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/basic/expected.golden b/pkg/controller/appdefinition/testdata/job/basic/expected.golden index 2bff587a0..f84d10ab5 100644 --- a/pkg/controller/appdefinition/testdata/job/basic/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/basic/expected.golden @@ -204,6 +204,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-create-app/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-create-app/expected.golden index 87c677958..14f44ed98 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-create-app/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-create-app/expected.golden @@ -161,6 +161,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-delete-app/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-delete-app/expected.golden index fa87005d9..0b5771652 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-delete-app/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-delete-app/expected.golden @@ -163,6 +163,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-start-app/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-start-app/expected.golden index ab44576db..e8c5f819c 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-start-app/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-start-app/expected.golden @@ -162,6 +162,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-stop-app/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-stop-app/expected.golden index 6c530fcc2..900890981 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-stop-app/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-stop-app/expected.golden @@ -162,6 +162,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-update-app-with-create/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-update-app-with-create/expected.golden index c8b39e86c..23b49f48e 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-update-app-with-create/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-update-app-with-create/expected.golden @@ -263,6 +263,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-update-app/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-update-app/expected.golden index 7097cc0f5..5970c4274 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-update-app/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-update-app/expected.golden @@ -162,6 +162,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-update-create-job/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-update-create-job/expected.golden index 72f9ed126..08a2aaf0d 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-update-create-job/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-update-create-job/expected.golden @@ -139,6 +139,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/event-jobs-update-generation-one/expected.golden b/pkg/controller/appdefinition/testdata/job/event-jobs-update-generation-one/expected.golden index 7c53a953e..32e38ee5d 100644 --- a/pkg/controller/appdefinition/testdata/job/event-jobs-update-generation-one/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/event-jobs-update-generation-one/expected.golden @@ -60,6 +60,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/job/labels/expected.golden b/pkg/controller/appdefinition/testdata/job/labels/expected.golden index 042d05c80..e3846cc4d 100644 --- a/pkg/controller/appdefinition/testdata/job/labels/expected.golden +++ b/pkg/controller/appdefinition/testdata/job/labels/expected.golden @@ -265,6 +265,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/link/expected.golden b/pkg/controller/appdefinition/testdata/link/expected.golden index 1438c99a6..e66fb610c 100644 --- a/pkg/controller/appdefinition/testdata/link/expected.golden +++ b/pkg/controller/appdefinition/testdata/link/expected.golden @@ -59,6 +59,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/memory/all-set-overwrite/expected.golden b/pkg/controller/appdefinition/testdata/memory/all-set-overwrite/expected.golden index 49d97c1ff..4445eeb64 100644 --- a/pkg/controller/appdefinition/testdata/memory/all-set-overwrite/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/all-set-overwrite/expected.golden @@ -229,6 +229,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/memory/all-set/expected.golden b/pkg/controller/appdefinition/testdata/memory/all-set/expected.golden index 3061aede9..62e96b510 100644 --- a/pkg/controller/appdefinition/testdata/memory/all-set/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/all-set/expected.golden @@ -228,6 +228,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/memory/container/expected.golden b/pkg/controller/appdefinition/testdata/memory/container/expected.golden index c45e9957d..be1d56d44 100644 --- a/pkg/controller/appdefinition/testdata/memory/container/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/container/expected.golden @@ -224,6 +224,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/appdefinition/testdata/memory/job/expected.golden b/pkg/controller/appdefinition/testdata/memory/job/expected.golden index e277de6ee..faa70c183 100644 --- a/pkg/controller/appdefinition/testdata/memory/job/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/job/expected.golden @@ -223,6 +223,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/appdefinition/testdata/memory/overwrite-acornfile-memory/expected.golden b/pkg/controller/appdefinition/testdata/memory/overwrite-acornfile-memory/expected.golden index f0209f8e7..79c9b9c31 100644 --- a/pkg/controller/appdefinition/testdata/memory/overwrite-acornfile-memory/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/overwrite-acornfile-memory/expected.golden @@ -225,6 +225,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/appdefinition/testdata/memory/sidecar/expected.golden b/pkg/controller/appdefinition/testdata/memory/sidecar/expected.golden index 809eda4e5..57ba40dbb 100644 --- a/pkg/controller/appdefinition/testdata/memory/sidecar/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/sidecar/expected.golden @@ -224,6 +224,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/appdefinition/testdata/memory/two-containers/expected.golden b/pkg/controller/appdefinition/testdata/memory/two-containers/expected.golden index 8e77fabaf..5aac13d1a 100644 --- a/pkg/controller/appdefinition/testdata/memory/two-containers/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/two-containers/expected.golden @@ -363,6 +363,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: oneimage: requirements: diff --git a/pkg/controller/appdefinition/testdata/memory/with-acornfile-memory/expected.golden b/pkg/controller/appdefinition/testdata/memory/with-acornfile-memory/expected.golden index 81b34f14d..57bba5562 100644 --- a/pkg/controller/appdefinition/testdata/memory/with-acornfile-memory/expected.golden +++ b/pkg/controller/appdefinition/testdata/memory/with-acornfile-memory/expected.golden @@ -223,6 +223,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/appdefinition/testdata/parseappimage/expected.golden b/pkg/controller/appdefinition/testdata/parseappimage/expected.golden index a79beef26..0786fc1e0 100644 --- a/pkg/controller/appdefinition/testdata/parseappimage/expected.golden +++ b/pkg/controller/appdefinition/testdata/parseappimage/expected.golden @@ -52,6 +52,7 @@ status: success: true type: parsed defaults: {} + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/parsedevmode/expected.golden b/pkg/controller/appdefinition/testdata/parsedevmode/expected.golden index 96e7c3d53..43e0e46e0 100644 --- a/pkg/controller/appdefinition/testdata/parsedevmode/expected.golden +++ b/pkg/controller/appdefinition/testdata/parsedevmode/expected.golden @@ -44,6 +44,7 @@ status: imageSource: {} sessionRenewTime: null sessionStartTime: null + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/both/expected.golden b/pkg/controller/appdefinition/testdata/permissions/both/expected.golden index b88ec07ab..3c06c1276 100644 --- a/pkg/controller/appdefinition/testdata/permissions/both/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/both/expected.golden @@ -650,6 +650,7 @@ status: verbs: - patch serviceName: twoimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/bothwithnopermissions/expected.golden b/pkg/controller/appdefinition/testdata/permissions/bothwithnopermissions/expected.golden index da8ee9cc1..f56631e56 100644 --- a/pkg/controller/appdefinition/testdata/permissions/bothwithnopermissions/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/bothwithnopermissions/expected.golden @@ -386,6 +386,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/container/expected.golden b/pkg/controller/appdefinition/testdata/permissions/container/expected.golden index 933fda07e..0589386d9 100644 --- a/pkg/controller/appdefinition/testdata/permissions/container/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/container/expected.golden @@ -336,6 +336,7 @@ status: verbs: - patch serviceName: oneimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/containerwithnamespace/expected.golden b/pkg/controller/appdefinition/testdata/permissions/containerwithnamespace/expected.golden index 57cd48fe9..f40f53dc4 100644 --- a/pkg/controller/appdefinition/testdata/permissions/containerwithnamespace/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/containerwithnamespace/expected.golden @@ -452,6 +452,7 @@ status: verbs: - patch serviceName: oneimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/differentpermissions/expected.golden b/pkg/controller/appdefinition/testdata/permissions/differentpermissions/expected.golden index 65710f6a8..2d936ddc1 100644 --- a/pkg/controller/appdefinition/testdata/permissions/differentpermissions/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/differentpermissions/expected.golden @@ -646,6 +646,7 @@ status: verbs: - delete serviceName: twoimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/job/expected.golden b/pkg/controller/appdefinition/testdata/permissions/job/expected.golden index 637fd487f..72bbc9aab 100644 --- a/pkg/controller/appdefinition/testdata/permissions/job/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/job/expected.golden @@ -339,6 +339,7 @@ status: verbs: - patch serviceName: oneimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/multiplecontainers/expected.golden b/pkg/controller/appdefinition/testdata/permissions/multiplecontainers/expected.golden index 471abe52a..e7ee5a63d 100644 --- a/pkg/controller/appdefinition/testdata/permissions/multiplecontainers/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/multiplecontainers/expected.golden @@ -646,6 +646,7 @@ status: verbs: - patch serviceName: twoimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/permissions/multiplejobs/expected.golden b/pkg/controller/appdefinition/testdata/permissions/multiplejobs/expected.golden index 00b9615a1..69038915e 100644 --- a/pkg/controller/appdefinition/testdata/permissions/multiplejobs/expected.golden +++ b/pkg/controller/appdefinition/testdata/permissions/multiplejobs/expected.golden @@ -651,6 +651,7 @@ status: verbs: - patch serviceName: twoimage + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/probes/expected.golden b/pkg/controller/appdefinition/testdata/probes/expected.golden index fda5df155..7037a6d19 100644 --- a/pkg/controller/appdefinition/testdata/probes/expected.golden +++ b/pkg/controller/appdefinition/testdata/probes/expected.golden @@ -370,6 +370,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/pullsecrets/custom/expected.golden b/pkg/controller/appdefinition/testdata/pullsecrets/custom/expected.golden index 1a4d3cdc7..2965c136f 100644 --- a/pkg/controller/appdefinition/testdata/pullsecrets/custom/expected.golden +++ b/pkg/controller/appdefinition/testdata/pullsecrets/custom/expected.golden @@ -262,6 +262,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/pullsecrets/default/expected.golden b/pkg/controller/appdefinition/testdata/pullsecrets/default/expected.golden index 6609cd71f..99c63498c 100644 --- a/pkg/controller/appdefinition/testdata/pullsecrets/default/expected.golden +++ b/pkg/controller/appdefinition/testdata/pullsecrets/default/expected.golden @@ -262,6 +262,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/router/expected.golden b/pkg/controller/appdefinition/testdata/router/expected.golden index 24c438c25..4cb43ede6 100644 --- a/pkg/controller/appdefinition/testdata/router/expected.golden +++ b/pkg/controller/appdefinition/testdata/router/expected.golden @@ -279,6 +279,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/secret/expected.golden b/pkg/controller/appdefinition/testdata/secret/expected.golden index df36efc17..555d232bb 100644 --- a/pkg/controller/appdefinition/testdata/secret/expected.golden +++ b/pkg/controller/appdefinition/testdata/secret/expected.golden @@ -243,6 +243,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/service/alias/expected.golden b/pkg/controller/appdefinition/testdata/service/alias/expected.golden index 51cd2ebc9..50d73bae5 100644 --- a/pkg/controller/appdefinition/testdata/service/alias/expected.golden +++ b/pkg/controller/appdefinition/testdata/service/alias/expected.golden @@ -588,6 +588,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/service/basic/expected.golden b/pkg/controller/appdefinition/testdata/service/basic/expected.golden index 45f12af58..f4c17d2cb 100644 --- a/pkg/controller/appdefinition/testdata/service/basic/expected.golden +++ b/pkg/controller/appdefinition/testdata/service/basic/expected.golden @@ -388,6 +388,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/template/expected.golden b/pkg/controller/appdefinition/testdata/template/expected.golden index bc1ff8f49..8fdd5a065 100644 --- a/pkg/controller/appdefinition/testdata/template/expected.golden +++ b/pkg/controller/appdefinition/testdata/template/expected.golden @@ -139,6 +139,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/cluster-default-with-bind-combos/expected.golden b/pkg/controller/appdefinition/testdata/volumes/cluster-default-with-bind-combos/expected.golden index 6dd4f518c..ed46c7788 100644 --- a/pkg/controller/appdefinition/testdata/volumes/cluster-default-with-bind-combos/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/cluster-default-with-bind-combos/expected.golden @@ -237,6 +237,7 @@ status: class: test-custom-class-default size: 2Gi namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/configure-but-no-bind/expected.golden b/pkg/controller/appdefinition/testdata/volumes/configure-but-no-bind/expected.golden index 6626b5c6f..33091aafa 100644 --- a/pkg/controller/appdefinition/testdata/volumes/configure-but-no-bind/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/configure-but-no-bind/expected.golden @@ -185,6 +185,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/contextdir/expected.golden b/pkg/controller/appdefinition/testdata/volumes/contextdir/expected.golden index 041e7e82a..3cb7d67f1 100644 --- a/pkg/controller/appdefinition/testdata/volumes/contextdir/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/contextdir/expected.golden @@ -153,6 +153,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/defaults/expected.golden b/pkg/controller/appdefinition/testdata/volumes/defaults/expected.golden index 1d6ccdd46..5741dbef2 100644 --- a/pkg/controller/appdefinition/testdata/volumes/defaults/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/defaults/expected.golden @@ -185,6 +185,7 @@ status: class: test-custom-class size: 3Gi namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/empty/expected.golden b/pkg/controller/appdefinition/testdata/volumes/empty/expected.golden index aec68b6f4..b76653125 100644 --- a/pkg/controller/appdefinition/testdata/volumes/empty/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/empty/expected.golden @@ -177,6 +177,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/ephemeral-bound/expected.golden b/pkg/controller/appdefinition/testdata/volumes/ephemeral-bound/expected.golden index 9c5bcbe58..f598fc839 100644 --- a/pkg/controller/appdefinition/testdata/volumes/ephemeral-bound/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/ephemeral-bound/expected.golden @@ -183,6 +183,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/ephemeral/expected.golden b/pkg/controller/appdefinition/testdata/volumes/ephemeral/expected.golden index d8c009787..472bccb32 100644 --- a/pkg/controller/appdefinition/testdata/volumes/ephemeral/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/ephemeral/expected.golden @@ -154,6 +154,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/inactive-class/expected.golden b/pkg/controller/appdefinition/testdata/volumes/inactive-class/expected.golden index 1d6ccdd46..5741dbef2 100644 --- a/pkg/controller/appdefinition/testdata/volumes/inactive-class/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/inactive-class/expected.golden @@ -185,6 +185,7 @@ status: class: test-custom-class size: 3Gi namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/named-bound/expected.golden b/pkg/controller/appdefinition/testdata/volumes/named-bound/expected.golden index 0e446cd14..090439736 100644 --- a/pkg/controller/appdefinition/testdata/volumes/named-bound/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/named-bound/expected.golden @@ -185,6 +185,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/named/expected.golden b/pkg/controller/appdefinition/testdata/volumes/named/expected.golden index 59655bcf4..2ef561c4d 100644 --- a/pkg/controller/appdefinition/testdata/volumes/named/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/named/expected.golden @@ -181,6 +181,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/no-default-class/expected.golden b/pkg/controller/appdefinition/testdata/volumes/no-default-class/expected.golden index aec68b6f4..b76653125 100644 --- a/pkg/controller/appdefinition/testdata/volumes/no-default-class/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/no-default-class/expected.golden @@ -177,6 +177,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/preload/expected.golden b/pkg/controller/appdefinition/testdata/volumes/preload/expected.golden index 11cbffd17..d09ae704e 100644 --- a/pkg/controller/appdefinition/testdata/volumes/preload/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/preload/expected.golden @@ -240,6 +240,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/appdefinition/testdata/volumes/reuse-existing/expected.golden b/pkg/controller/appdefinition/testdata/volumes/reuse-existing/expected.golden index 782822f5a..8ed2fac00 100644 --- a/pkg/controller/appdefinition/testdata/volumes/reuse-existing/expected.golden +++ b/pkg/controller/appdefinition/testdata/volumes/reuse-existing/expected.golden @@ -179,6 +179,7 @@ status: type: defined defaults: {} namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/all-set-overwrite/expected.golden b/pkg/controller/defaults/testdata/memory/all-set-overwrite/expected.golden index 094fafdc3..1b4c997ce 100644 --- a/pkg/controller/defaults/testdata/memory/all-set-overwrite/expected.golden +++ b/pkg/controller/defaults/testdata/memory/all-set-overwrite/expected.golden @@ -53,6 +53,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/all-set/expected.golden b/pkg/controller/defaults/testdata/memory/all-set/expected.golden index 67d1a40a5..d92040783 100644 --- a/pkg/controller/defaults/testdata/memory/all-set/expected.golden +++ b/pkg/controller/defaults/testdata/memory/all-set/expected.golden @@ -52,6 +52,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/container/expected.golden b/pkg/controller/defaults/testdata/memory/container/expected.golden index d2b5b4bd7..6ee276044 100644 --- a/pkg/controller/defaults/testdata/memory/container/expected.golden +++ b/pkg/controller/defaults/testdata/memory/container/expected.golden @@ -52,6 +52,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/job/expected.golden b/pkg/controller/defaults/testdata/memory/job/expected.golden index 6d4a068f2..1e5fc09c5 100644 --- a/pkg/controller/defaults/testdata/memory/job/expected.golden +++ b/pkg/controller/defaults/testdata/memory/job/expected.golden @@ -52,6 +52,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/overwrite-acornfile-memory/expected.golden b/pkg/controller/defaults/testdata/memory/overwrite-acornfile-memory/expected.golden index 7006c74d2..96cace5f0 100644 --- a/pkg/controller/defaults/testdata/memory/overwrite-acornfile-memory/expected.golden +++ b/pkg/controller/defaults/testdata/memory/overwrite-acornfile-memory/expected.golden @@ -53,6 +53,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/same-generation/expected.golden b/pkg/controller/defaults/testdata/memory/same-generation/expected.golden index 7ea75f112..f17329dc2 100644 --- a/pkg/controller/defaults/testdata/memory/same-generation/expected.golden +++ b/pkg/controller/defaults/testdata/memory/same-generation/expected.golden @@ -50,6 +50,7 @@ status: left: 0 oneimage: 0 namespace: app-created-namespace + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/sidecar/expected.golden b/pkg/controller/defaults/testdata/memory/sidecar/expected.golden index 78ef621ea..51fa8ef1f 100644 --- a/pkg/controller/defaults/testdata/memory/sidecar/expected.golden +++ b/pkg/controller/defaults/testdata/memory/sidecar/expected.golden @@ -52,6 +52,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/two-containers/expected.golden b/pkg/controller/defaults/testdata/memory/two-containers/expected.golden index 34a0213d4..67a607db8 100644 --- a/pkg/controller/defaults/testdata/memory/two-containers/expected.golden +++ b/pkg/controller/defaults/testdata/memory/two-containers/expected.golden @@ -54,6 +54,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/memory/with-acornfile-memory/expected.golden b/pkg/controller/defaults/testdata/memory/with-acornfile-memory/expected.golden index e23679fdb..2e46573fd 100644 --- a/pkg/controller/defaults/testdata/memory/with-acornfile-memory/expected.golden +++ b/pkg/controller/defaults/testdata/memory/with-acornfile-memory/expected.golden @@ -51,6 +51,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/region/default/expected.golden b/pkg/controller/defaults/testdata/region/default/expected.golden index ff24b6397..23ee47a01 100644 --- a/pkg/controller/defaults/testdata/region/default/expected.golden +++ b/pkg/controller/defaults/testdata/region/default/expected.golden @@ -33,6 +33,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/region/project-default-status/expected.golden b/pkg/controller/defaults/testdata/region/project-default-status/expected.golden index ff24b6397..23ee47a01 100644 --- a/pkg/controller/defaults/testdata/region/project-default-status/expected.golden +++ b/pkg/controller/defaults/testdata/region/project-default-status/expected.golden @@ -33,6 +33,7 @@ status: region: local namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/region/region-on-spec/expected.golden b/pkg/controller/defaults/testdata/region/region-on-spec/expected.golden index fe4b17aaf..0f82ce6f0 100644 --- a/pkg/controller/defaults/testdata/region/region-on-spec/expected.golden +++ b/pkg/controller/defaults/testdata/region/region-on-spec/expected.golden @@ -33,6 +33,7 @@ status: container-name: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden b/pkg/controller/defaults/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden index 17231acd8..b5d223f78 100644 --- a/pkg/controller/defaults/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden @@ -45,6 +45,7 @@ status: size: 6Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden index 0d0f1f3a2..9d7ae6441 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden @@ -40,6 +40,7 @@ status: defaults: {} namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-set/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-set/expected.golden index 775c3f3f6..6b9cedd30 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-set/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-defaults-set/expected.golden @@ -45,6 +45,7 @@ status: size: 4Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden index ced454b76..ee91f8935 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden @@ -45,6 +45,7 @@ status: size: 3Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden index f604b7258..36cf9ec71 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden @@ -48,6 +48,7 @@ status: size: 5Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults/expected.golden index 45fd223b6..b69c6b285 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-defaults/expected.golden @@ -45,6 +45,7 @@ status: size: 2Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-project-default/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-project-default/expected.golden index 9a87fb84b..571227eda 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-project-default/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-project-default/expected.golden @@ -46,6 +46,7 @@ status: size: 2Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-size/expected.golden b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-size/expected.golden index 9062fe05c..aabb2451d 100644 --- a/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-size/expected.golden +++ b/pkg/controller/defaults/testdata/volumeclass/volume-class-fill-size/expected.golden @@ -45,6 +45,7 @@ status: size: 2Gi namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} staged: appImage: buildContext: {} diff --git a/pkg/controller/resolvedofferings/computeclass.go b/pkg/controller/resolvedofferings/computeclass.go new file mode 100644 index 000000000..9c7e1d48a --- /dev/null +++ b/pkg/controller/resolvedofferings/computeclass.go @@ -0,0 +1,123 @@ +package resolvedofferings + +import ( + "github.com/acorn-io/baaah/pkg/router" + apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1" + v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" + adminv1 "github.com/acorn-io/runtime/pkg/apis/internal.admin.acorn.io/v1" + "github.com/acorn-io/runtime/pkg/computeclasses" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +// resolveComputeClasses resolves the compute class information for each container in the AppInstance +func resolveComputeClasses(req router.Request, cfg *apiv1.Config, appInstance *v1.AppInstance) error { + if appInstance.Status.ResolvedOfferings.Containers == nil { + appInstance.Status.ResolvedOfferings.Containers = map[string]v1.ContainerResolvedOffering{} + } + + var ( + defaultCC string + err error + ) + if value, ok := appInstance.Spec.ComputeClasses[""]; ok { + defaultCC = value + } else { + defaultCC, err = adminv1.GetDefaultComputeClass(req.Ctx, req.Client, appInstance.Namespace) + if err != nil { + return err + } + } + + // Set the default for all containers, noted by the empty string + appInstance.Status.ResolvedOfferings.Containers[""] = v1.ContainerResolvedOffering{ + Memory: cfg.WorkloadMemoryDefault, + Class: defaultCC, + } + cc, err := computeclasses.GetAsProjectComputeClassInstance(req.Ctx, req.Client, appInstance.Status.Namespace, defaultCC) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + + if cc != nil { + parsedMemory, err := computeclasses.ParseComputeClassMemory(cc.Memory) + if err != nil { + return err + } + def := parsedMemory.Def.Value() + appInstance.Status.ResolvedOfferings.Containers[""] = v1.ContainerResolvedOffering{ + Memory: &def, + CPUScaler: &cc.CPUScaler, + Class: appInstance.Status.ResolvedOfferings.Containers[""].Class, + } + } + + // Set the compute class info for each container and job individually + if err := resolveComputeClass(req, appInstance, cfg.WorkloadMemoryDefault, cc, defaultCC, appInstance.Status.AppSpec.Containers); err != nil { + return err + } + + if err := resolveComputeClass(req, appInstance, cfg.WorkloadMemoryDefault, cc, defaultCC, appInstance.Status.AppSpec.Jobs); err != nil { + return err + } + + return nil +} + +func resolveComputeClass(req router.Request, appInstance *v1.AppInstance, configDefault *int64, defaultCC *adminv1.ProjectComputeClassInstance, defaultCCName string, containers map[string]v1.Container) error { + for name, container := range containers { + var cpuScaler *float64 + ccName := "" + + // First, get the compute class for the workload + cc, err := computeclasses.GetClassForWorkload(req.Ctx, req.Client, appInstance.Spec.ComputeClasses, container, name, appInstance.Namespace) + if err != nil { + return err + } + if cc == nil { + cc = defaultCC + } + if cc != nil { + ccName = cc.Name + cpuScaler = &cc.CPUScaler + } else { + ccName = defaultCCName + } + + // Next, determine the memory request. This is the order of priority: + // 1. runtime-level overrides from the user (in app.Spec) + // 2. defaults in the acorn image + // 3. defaults from compute class + // 4. global default + + memory := configDefault // set to global default first, then check the higher priority values + + if containerMemoryOverride := appInstance.Spec.Memory[name]; containerMemoryOverride != nil { // runtime-level overrides from the user + memory = containerMemoryOverride + } else if container.Memory != nil { // defaults in the acorn image + memory = container.Memory + } else if cc != nil { // defaults from compute class + parsedMemory, err := computeclasses.ParseComputeClassMemory(cc.Memory) + if err != nil { + return err + } + def := parsedMemory.Def.Value() + memory = &def + } + + appInstance.Status.ResolvedOfferings.Containers[name] = v1.ContainerResolvedOffering{ + Class: ccName, + Memory: memory, + CPUScaler: cpuScaler, + } + + for sidecarName := range container.Sidecars { + appInstance.Status.ResolvedOfferings.Containers[sidecarName] = v1.ContainerResolvedOffering{ + Class: ccName, + Memory: memory, + CPUScaler: cpuScaler, + } + } + } + + return nil +} diff --git a/pkg/controller/resolvedofferings/computeclass_test.go b/pkg/controller/resolvedofferings/computeclass_test.go new file mode 100644 index 000000000..76cdfbed9 --- /dev/null +++ b/pkg/controller/resolvedofferings/computeclass_test.go @@ -0,0 +1,86 @@ +package resolvedofferings + +import ( + "testing" + + "github.com/acorn-io/baaah/pkg/router" + "github.com/acorn-io/baaah/pkg/router/tester" + "github.com/acorn-io/runtime/pkg/scheme" + "github.com/stretchr/testify/assert" +) + +func TestContainerMemory(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/container", Calculate) +} + +func TestSidecarMemory(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/sidecar", Calculate) +} + +func TestJobMemory(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/job", Calculate) +} + +func TestOverwriteAcornfileMemory(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/overwrite-acornfile-memory", Calculate) +} + +func TestWithAcornfileMemory(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/with-acornfile-memory", Calculate) +} + +func TestTwoContainers(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/two-containers", Calculate) +} + +func TestAllSet(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/all-set", Calculate) +} + +func TestAllSetOverwrite(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/all-set-overwrite", Calculate) +} + +func TestMemorySameGeneration(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/same-generation", Calculate) +} + +func TestTwoCCCDefaultsShouldError(t *testing.T) { + harness, input, err := tester.FromDir(scheme.Scheme, "testdata/computeclass/two-ccc-defaults-should-error") + if err != nil { + t.Fatal(err) + } + + resp, err := harness.Invoke(t, input, router.HandlerFunc(Calculate)) + if err != nil { + t.Fatal(err) + } + + assert.True(t, resp.NoPrune, "NoPrune should be true when error occurs") +} + +func TestTwoPCCDefaultsShouldError(t *testing.T) { + harness, input, err := tester.FromDir(scheme.Scheme, "testdata/computeclass/two-pcc-defaults-should-error") + if err != nil { + t.Fatal(err) + } + + resp, err := harness.Invoke(t, input, router.HandlerFunc(Calculate)) + if err != nil { + t.Fatal(err) + } + + assert.True(t, resp.NoPrune, "NoPrune should be true when error occurs") +} + +func TestComputeClassDefault(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/compute-class-default", Calculate) +} + +func TestAcornfileOverrideComputeClass(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/acornfile-override-compute-class", Calculate) +} + +func TestUserOverrideComputeClass(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/user-override-compute-class", Calculate) +} diff --git a/pkg/controller/resolvedofferings/region.go b/pkg/controller/resolvedofferings/region.go new file mode 100644 index 000000000..6f9e8b4a6 --- /dev/null +++ b/pkg/controller/resolvedofferings/region.go @@ -0,0 +1,23 @@ +package resolvedofferings + +import ( + "context" + + v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func AddDefaultRegion(ctx context.Context, c client.Client, app v1.AppInstance) error { + if app.GetRegion() == "" { + project := new(v1.ProjectInstance) + if err := c.Get(ctx, client.ObjectKey{Name: app.GetNamespace()}, project); err != nil { + return err + } + + app.Status.ResolvedOfferings.Region = project.Status.DefaultRegion + } else { + app.Status.ResolvedOfferings.Region = app.GetRegion() + } + + return nil +} diff --git a/pkg/controller/resolvedofferings/region_test.go b/pkg/controller/resolvedofferings/region_test.go new file mode 100644 index 000000000..d32551751 --- /dev/null +++ b/pkg/controller/resolvedofferings/region_test.go @@ -0,0 +1,20 @@ +package resolvedofferings + +import ( + "testing" + + "github.com/acorn-io/baaah/pkg/router/tester" + "github.com/acorn-io/runtime/pkg/scheme" +) + +func TestCalculateRegionDefault(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/region/default", Calculate) +} + +func TestCalculateRegionDefaultProjectStatus(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/region/project-default-status", Calculate) +} + +func TestCalculateRegionDefaultOnSpec(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/region/region-on-spec", Calculate) +} diff --git a/pkg/controller/resolvedofferings/resolvedofferings.go b/pkg/controller/resolvedofferings/resolvedofferings.go new file mode 100644 index 000000000..774e23e8c --- /dev/null +++ b/pkg/controller/resolvedofferings/resolvedofferings.go @@ -0,0 +1,65 @@ +package resolvedofferings + +import ( + "github.com/acorn-io/baaah/pkg/router" + internalv1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" + "github.com/acorn-io/runtime/pkg/condition" + "github.com/acorn-io/runtime/pkg/config" +) + +// Calculate is a handler that sets the resolved offerings for an AppInstance to its status if +// and only if its generation is different from its observedGeneration. +// +// This is necessary because querying for resolved offerings will result in all running +// AppInstances using that default to redeploy when a default changes. By +// calculating the resolved offerings only when the generation changes, we can ensure that +// updated resolved offerings are only applied when an AppInstance is updated directly. +func Calculate(req router.Request, resp router.Response) (err error) { + appInstance := req.Object.(*internalv1.AppInstance) + status := condition.Setter(appInstance, resp, internalv1.AppInstanceConditionResolvedOfferings) + + defer func() { + if err == nil { + status.Success() + } else { + status.Error(err) + // Disable prune because we are short-circuiting the handlers and don't want objects getting cleaned up accidentally. + resp.DisablePrune() + // Don't return the error so the other conditions don't get the same information. + err = nil + } + }() + + // resolveVolumeClasses should run everytime as the function itself will not overwrite any existing + // information. Effectively, this means that volume class info only gets set if it have not been set before. + if err = resolveVolumeClasses(req.Ctx, req.Client, appInstance); err != nil { + return err + } + + if appInstance.Generation != appInstance.Status.ObservedGeneration { + if err = calculate(req, appInstance); err != nil { + return err + } + } + + return nil +} + +func calculate(req router.Request, appInstance *internalv1.AppInstance) error { + cfg, err := config.Get(req.Ctx, req.Client) + if err != nil { + return err + } + + if appInstance != nil { + if err = AddDefaultRegion(req.Ctx, req.Client, *appInstance); err != nil { + return err + } + } + + if err = resolveComputeClasses(req, cfg, appInstance); err != nil { + return err + } + + return nil +} diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/existing.yaml new file mode 100644 index 000000000..1f862ac4e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/existing.yaml @@ -0,0 +1,31 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local +--- +kind: ProjectComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class + namespace: app-namespace +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 2Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/expected.golden new file mode 100644 index 000000000..cb8d42109 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/expected.golden @@ -0,0 +1,68 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + memory: 2097152 + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + class: sample-compute-class + memory: 0 + left: + class: sample-compute-class + cpuScaler: 0.25 + memory: 2097152 + oneimage: + class: sample-compute-class + cpuScaler: 0.25 + memory: 2097152 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/input.yaml new file mode 100644 index 000000000..140ee5c17 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/acornfile-override-compute-class/input.yaml @@ -0,0 +1,32 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + memory: 2097152 # 2Mi diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/expected.golden new file mode 100644 index 000000000..881397965 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/expected.golden @@ -0,0 +1,65 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + "": 1048576 + oneimage: 2097152 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 2097152 + oneimage: + memory: 2097152 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/input.yaml new file mode 100644 index 000000000..8c8fbda96 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/all-set-overwrite/input.yaml @@ -0,0 +1,34 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + "": 1048576 # 1Mi + oneimage: 2097152 # 2Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/all-set/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/all-set/existing.yaml new file mode 100644 index 000000000..f98ccb6f3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/all-set/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/all-set/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/all-set/expected.golden new file mode 100644 index 000000000..5e5cd2671 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/all-set/expected.golden @@ -0,0 +1,64 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + "": 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 0 + oneimage: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/all-set/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/all-set/input.yaml new file mode 100644 index 000000000..c76acc55b --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/all-set/input.yaml @@ -0,0 +1,33 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + "": 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/existing.yaml new file mode 100644 index 000000000..1f862ac4e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/existing.yaml @@ -0,0 +1,31 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local +--- +kind: ProjectComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class + namespace: app-namespace +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 2Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/expected.golden new file mode 100644 index 000000000..ceb05a081 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/expected.golden @@ -0,0 +1,67 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + class: sample-compute-class + memory: 0 + left: + class: sample-compute-class + cpuScaler: 0.25 + memory: 1048576 + oneimage: + class: sample-compute-class + cpuScaler: 0.25 + memory: 1048576 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/input.yaml new file mode 100644 index 000000000..701e1c7c8 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/compute-class-default/input.yaml @@ -0,0 +1,31 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/container/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/container/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/container/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/container/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/container/expected.golden new file mode 100644 index 000000000..355106ff3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/container/expected.golden @@ -0,0 +1,64 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 1048576 + oneimage: + memory: 1048576 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/container/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/container/input.yaml new file mode 100644 index 000000000..7dca842b8 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/container/input.yaml @@ -0,0 +1,33 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/job/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/job/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/job/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/job/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/job/expected.golden new file mode 100644 index 000000000..fb4b785ac --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/job/expected.golden @@ -0,0 +1,64 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + jobs: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 1048576 + oneimage: + memory: 1048576 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/job/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/job/input.yaml new file mode 100644 index 000000000..5dcefca68 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/job/input.yaml @@ -0,0 +1,33 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + jobs: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/expected.golden new file mode 100644 index 000000000..58e8a19fd --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/expected.golden @@ -0,0 +1,65 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + memory: 2097152 + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 1048576 + oneimage: + memory: 1048576 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/input.yaml new file mode 100644 index 000000000..0d3884e69 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/overwrite-acornfile-memory/input.yaml @@ -0,0 +1,34 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + memory: 2097152 # 2Mi diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/same-generation/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/same-generation/expected.golden new file mode 100644 index 000000000..ffcde0fe3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/same-generation/expected.golden @@ -0,0 +1,63 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + left: 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 0 + oneimage: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/same-generation/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/same-generation/input.yaml new file mode 100644 index 000000000..b6661c147 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/same-generation/input.yaml @@ -0,0 +1,40 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + left: 1048576 # 1Mi +status: + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 0 + oneimage: + memory: 0 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/expected.golden new file mode 100644 index 000000000..fc8207d16 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/expected.golden @@ -0,0 +1,64 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + left: 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 0 + oneimage: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/input.yaml new file mode 100644 index 000000000..5a12f7971 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/sidecar/input.yaml @@ -0,0 +1,33 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + left: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/existing.yaml new file mode 100644 index 000000000..bed9cfee0 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/existing.yaml @@ -0,0 +1,52 @@ +--- +kind: ClusterComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 2Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar +--- +kind: ClusterComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class-other +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 2Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml new file mode 100644 index 000000000..a14780b7c --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml @@ -0,0 +1,40 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + conditions: + - error: true + message: 'cannot establish defaults because two default computeclasses exist: sample-compute-class and sample-compute-class-other' + reason: Error + status: "False" + type: resolved-offerings + resolvedOfferings: {} diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/input.yaml new file mode 100644 index 000000000..7dca842b8 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-ccc-defaults-should-error/input.yaml @@ -0,0 +1,33 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/expected.golden new file mode 100644 index 000000000..d90950f84 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/expected.golden @@ -0,0 +1,66 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + twoimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + oneimage: + memory: 1048576 + twoimage: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/input.yaml new file mode 100644 index 000000000..51c73f061 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-containers/input.yaml @@ -0,0 +1,35 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + twoimage: + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/existing.yaml new file mode 100644 index 000000000..21be6c7c9 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/existing.yaml @@ -0,0 +1,54 @@ +--- +kind: ProjectComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class + namespace: app-namespace +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 2Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar +--- +kind: ProjectComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class-other + namespace: app-namespace +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 2Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml new file mode 100644 index 000000000..a14780b7c --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml @@ -0,0 +1,40 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + conditions: + - error: true + message: 'cannot establish defaults because two default computeclasses exist: sample-compute-class and sample-compute-class-other' + reason: Error + status: "False" + type: resolved-offerings + resolvedOfferings: {} diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/input.yaml new file mode 100644 index 000000000..7dca842b8 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/two-pcc-defaults-should-error/input.yaml @@ -0,0 +1,33 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 1048576 # 1Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/existing.yaml new file mode 100644 index 000000000..ebad9b6a8 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/existing.yaml @@ -0,0 +1,31 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local +--- +kind: ProjectComputeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: sample-compute-class + namespace: app-namespace +description: Simple description for a simple ComputeClass +cpuScaler: 0.25 +default: true +memory: + min: 1Mi # 1Mi + max: 3Mi # 2Mi + default: 1Mi # 1Mi +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: foo + operator: In + values: + - bar \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/expected.golden new file mode 100644 index 000000000..b0509b70a --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/expected.golden @@ -0,0 +1,70 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 3145728 +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + memory: 2097152 + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + class: sample-compute-class + memory: 0 + left: + class: sample-compute-class + cpuScaler: 0.25 + memory: 3145728 + oneimage: + class: sample-compute-class + cpuScaler: 0.25 + memory: 3145728 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/input.yaml new file mode 100644 index 000000000..4871266e5 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/user-override-compute-class/input.yaml @@ -0,0 +1,34 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + memory: + oneimage: 3145728 # 3Mi +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + memory: 2097152 # 2Mi diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/existing.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/existing.yaml new file mode 100644 index 000000000..68c21dc2e --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/expected.golden b/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/expected.golden new file mode 100644 index 000000000..da7c2f35d --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/expected.golden @@ -0,0 +1,63 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + oneimage: + build: + context: . + dockerfile: Dockerfile + image: image-name + memory: 1048576 + metrics: {} + ports: + - port: 80 + protocol: http + targetPort: 81 + probes: null + sidecars: + left: + image: foo + metrics: {} + ports: + - port: 90 + protocol: tcp + targetPort: 91 + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + left: + memory: 1048576 + oneimage: + memory: 1048576 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/input.yaml b/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/input.yaml new file mode 100644 index 000000000..c08f79405 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/computeclass/with-acornfile-memory/input.yaml @@ -0,0 +1,32 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + oneimage: + sidecars: + left: + image: "foo" + ports: + - port: 90 + targetPort: 91 + protocol: tcp + ports: + - port: 80 + targetPort: 81 + protocol: http + image: "image-name" + build: + dockerfile: "Dockerfile" + context: "." + memory: 1048576 # 1Mi diff --git a/pkg/controller/resolvedofferings/testdata/region/default/existing.yaml b/pkg/controller/resolvedofferings/testdata/region/default/existing.yaml new file mode 100644 index 000000000..f98ccb6f3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/default/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/region/default/expected.golden b/pkg/controller/resolvedofferings/testdata/region/default/expected.golden new file mode 100644 index 000000000..dbc54b612 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/default/expected.golden @@ -0,0 +1,44 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + image: image-name + metrics: {} + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/region/default/input.yaml b/pkg/controller/resolvedofferings/testdata/region/default/input.yaml new file mode 100644 index 000000000..fde881306 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/default/input.yaml @@ -0,0 +1,17 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" diff --git a/pkg/controller/resolvedofferings/testdata/region/project-default-status/existing.yaml b/pkg/controller/resolvedofferings/testdata/region/project-default-status/existing.yaml new file mode 100644 index 000000000..f98ccb6f3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/project-default-status/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/region/project-default-status/expected.golden b/pkg/controller/resolvedofferings/testdata/region/project-default-status/expected.golden new file mode 100644 index 000000000..dbc54b612 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/project-default-status/expected.golden @@ -0,0 +1,44 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + image: image-name + metrics: {} + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/region/project-default-status/input.yaml b/pkg/controller/resolvedofferings/testdata/region/project-default-status/input.yaml new file mode 100644 index 000000000..fde881306 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/project-default-status/input.yaml @@ -0,0 +1,17 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" diff --git a/pkg/controller/resolvedofferings/testdata/region/region-on-spec/existing.yaml b/pkg/controller/resolvedofferings/testdata/region/region-on-spec/existing.yaml new file mode 100644 index 000000000..f98ccb6f3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/region-on-spec/existing.yaml @@ -0,0 +1,9 @@ +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/region/region-on-spec/expected.golden b/pkg/controller/resolvedofferings/testdata/region/region-on-spec/expected.golden new file mode 100644 index 000000000..befa2cb38 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/region-on-spec/expected.golden @@ -0,0 +1,45 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + region: my-region +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + image: image-name + metrics: {} + probes: null + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/region/region-on-spec/input.yaml b/pkg/controller/resolvedofferings/testdata/region/region-on-spec/input.yaml new file mode 100644 index 000000000..ee4ee0516 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/region/region-on-spec/input.yaml @@ -0,0 +1,18 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + region: my-region +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/existing.yaml new file mode 100644 index 000000000..58103a871 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/existing.yaml @@ -0,0 +1,37 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: custom-class +description: Just a simple test volume class +default: true +storageClassName: custom-class +size: + min: 1Gi + max: 10Gi + default: 3Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: custom-class + namespace: app-namespace +description: Just a simple test volume class +default: true +storageClassName: custom-class +size: + min: 2Gi + max: 20Gi + default: 6Gi +allowedAccessModes: ["readWriteMany"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden new file mode 100644 index 000000000..f7c7b8473 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/expected.golden @@ -0,0 +1,57 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: + class: custom-class + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + volumes: + foo: + accessModes: + - readWriteMany + class: custom-class + size: 6Gi + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/input.yaml new file mode 100644 index 000000000..ab34a03f1 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/cluster-and-project-class-same-name/input.yaml @@ -0,0 +1,23 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: + class: custom-class diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/existing.yaml new file mode 100644 index 000000000..72dda906d --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/existing.yaml @@ -0,0 +1,38 @@ +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class + namespace: app-namespace +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class-1 + namespace: app-namespace +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden new file mode 100644 index 000000000..9492d9de3 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/expected.golden @@ -0,0 +1,50 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + generation: 1 + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: + class: test-volume-class + appStatus: {} + columns: {} + conditions: + - error: true + message: 'cannot resolve volume classes because two defaults volume classes exist: + test-volume-class and test-volume-class-1' + observedGeneration: 1 + reason: Error + status: "False" + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: {} + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/input.yaml new file mode 100644 index 000000000..fd89dcc74 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-defaults-same-gen/input.yaml @@ -0,0 +1,24 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + generation: 1 + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: + class: test-volume-class diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/existing.yaml new file mode 100644 index 000000000..3ad20cb87 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/existing.yaml @@ -0,0 +1,51 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 3Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class-inactive +description: Just a simple test volume class +default: true +inactive: true +storageClassName: test-storage-class-inactive +size: + min: 2Gi + max: 20Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-project-volume-class + namespace: app-namespace +description: Just a simple project test volume class +default: false +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce", "readOnlyMany"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden new file mode 100644 index 000000000..c110065d8 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/expected.golden @@ -0,0 +1,56 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: {} + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + volumes: + foo: + accessModes: + - readWriteOnce + class: test-volume-class + size: 3Gi + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/input.yaml new file mode 100644 index 000000000..951e767e5 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-cluster-default/input.yaml @@ -0,0 +1,22 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: {} diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/existing.yaml new file mode 100644 index 000000000..9b804bb13 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/existing.yaml @@ -0,0 +1,36 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class +description: Just a simple test volume class +default: false +storageClassName: test-storage-class +size: + min: 1Gi + max: 20Gi + default: 5Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: default-test-volume-class +description: Just a simple test volume class +default: true +storageClassName: default-test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden new file mode 100644 index 000000000..3a7bc997d --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/expected.golden @@ -0,0 +1,60 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + volumes: + - class: test-volume-class + target: foo +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: + class: default-test-volume-class + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + volumes: + foo: + accessModes: + - readWriteOnce + class: test-volume-class + size: 5Gi + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/input.yaml new file mode 100644 index 000000000..aaed98821 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults-with-bind/input.yaml @@ -0,0 +1,26 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test + volumes: + - target: foo + class: test-volume-class +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: + class: default-test-volume-class diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/existing.yaml new file mode 100644 index 000000000..da136132f --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/existing.yaml @@ -0,0 +1,23 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class +description: Just a simple test volume class +default: false +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/expected.golden new file mode 100644 index 000000000..44f81a974 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/expected.golden @@ -0,0 +1,57 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: + class: test-volume-class + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + volumes: + foo: + accessModes: + - readWriteOnce + class: test-volume-class + size: 2Gi + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/input.yaml new file mode 100644 index 000000000..a3ea0d7f7 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-defaults/input.yaml @@ -0,0 +1,23 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: + class: test-volume-class diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/existing.yaml new file mode 100644 index 000000000..3a06f0084 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/existing.yaml @@ -0,0 +1,52 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-cluster-volume-class +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 3Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-project-volume-class + namespace: app-namespace +description: Just a simple project test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce", "readOnlyMany"] +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-project-volume-class-inactive + namespace: app-namespace +description: Just a simple project test volume class +default: true +inactive: true +storageClassName: test-storage-class-inactive +size: + min: 2Gi + max: 20Gi + default: 4Gi +allowedAccessModes: ["readWriteOnce", "readOnlyMany"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/expected.golden new file mode 100644 index 000000000..11c04b056 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/expected.golden @@ -0,0 +1,57 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: {} + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + volumes: + foo: + accessModes: + - readWriteOnce + - readOnlyMany + class: test-project-volume-class + size: 2Gi + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/input.yaml new file mode 100644 index 000000000..951e767e5 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-project-default/input.yaml @@ -0,0 +1,22 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: {} diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/existing.yaml new file mode 100644 index 000000000..18ad48cfe --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/existing.yaml @@ -0,0 +1,23 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class +description: Just a simple test volume class +default: false +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce", "readOnlyMany"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/expected.golden b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/expected.golden new file mode 100644 index 000000000..9c27fe527 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/expected.golden @@ -0,0 +1,59 @@ +`apiVersion: internal.acorn.io/v1 +kind: AppInstance +metadata: + creationTimestamp: null + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + appImage: + buildContext: {} + id: test + imageData: {} + vcs: {} + appSpec: + containers: + container-name: + dirs: + /var/tmp: + secret: {} + volume: foo + image: image-name + metrics: {} + probes: null + volumes: + foo: + accessModes: + - readWriteOnce + class: test-volume-class + appStatus: {} + columns: {} + conditions: + reason: Success + status: "True" + success: true + type: resolved-offerings + defaults: {} + namespace: app-created-namespace + observedGeneration: 1 + resolvedOfferings: + containers: + "": + memory: 0 + container-name: + memory: 0 + volumes: + foo: + accessModes: + - readWriteOnce + class: test-volume-class + size: 2Gi + staged: + appImage: + buildContext: {} + imageData: {} + vcs: {} + summary: {} +` diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/input.yaml new file mode 100644 index 000000000..b283fb2de --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-fill-size/input.yaml @@ -0,0 +1,24 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: + class: test-volume-class + accessModes: ["readWriteOnce"] diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/existing.yaml new file mode 100644 index 000000000..89a744aa6 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/existing.yaml @@ -0,0 +1,38 @@ +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class + namespace: app-namespace +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class-1 + namespace: app-namespace +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/expected.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/expected.yaml new file mode 100644 index 000000000..c62bd0c6c --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/expected.yaml @@ -0,0 +1,28 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: {} + conditions: + - error: true + message: 'cannot resolve volume classes because two defaults volume classes exist: test-volume-class and test-volume-class-1' + reason: Error + status: "False" + type: resolved-offerings diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/input.yaml new file mode 100644 index 000000000..951e767e5 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-cluster-defaults/input.yaml @@ -0,0 +1,22 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: {} diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/existing.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/existing.yaml new file mode 100644 index 000000000..8b5295b2c --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/existing.yaml @@ -0,0 +1,36 @@ +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ClusterVolumeClassInstance +apiVersion: internal.admin.acorn.io/v1 +metadata: + name: test-volume-class-1 +description: Just a simple test volume class +default: true +storageClassName: test-storage-class +size: + min: 1Gi + max: 10Gi + default: 2Gi +allowedAccessModes: ["readWriteOnce"] +--- +kind: ProjectInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-namespace +spec: {} +status: + defaultRegion: local + supportedRegions: + - local \ No newline at end of file diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/expected.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/expected.yaml new file mode 100644 index 000000000..c62bd0c6c --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/expected.yaml @@ -0,0 +1,28 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: {} + conditions: + - error: true + message: 'cannot resolve volume classes because two defaults volume classes exist: test-volume-class and test-volume-class-1' + reason: Error + status: "False" + type: resolved-offerings diff --git a/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/input.yaml b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/input.yaml new file mode 100644 index 000000000..951e767e5 --- /dev/null +++ b/pkg/controller/resolvedofferings/testdata/volumeclass/volume-class-two-project-defaults/input.yaml @@ -0,0 +1,22 @@ +kind: AppInstance +apiVersion: internal.acorn.io/v1 +metadata: + name: app-name + namespace: app-namespace + uid: 1234567890abcdef +spec: + image: test +status: + observedGeneration: 1 + namespace: app-created-namespace + appImage: + id: test + appSpec: + containers: + container-name: + image: "image-name" + dirs: + "/var/tmp": + volume: foo + volumes: + foo: {} diff --git a/pkg/controller/resolvedofferings/volumeclass.go b/pkg/controller/resolvedofferings/volumeclass.go new file mode 100644 index 000000000..4e4fe9cc5 --- /dev/null +++ b/pkg/controller/resolvedofferings/volumeclass.go @@ -0,0 +1,99 @@ +package resolvedofferings + +import ( + "context" + "fmt" + + "github.com/acorn-io/baaah/pkg/typed" + internalv1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" + "github.com/acorn-io/runtime/pkg/labels" + "github.com/acorn-io/runtime/pkg/volume" + corev1 "k8s.io/api/core/v1" + klabels "k8s.io/apimachinery/pkg/labels" + kclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +func resolveVolumeClasses(ctx context.Context, c kclient.Client, app *internalv1.AppInstance) error { + if len(app.Status.AppSpec.Volumes) == 0 { + return nil + } + + volumeClasses, defaultVolumeClass, err := volume.GetVolumeClassInstances(ctx, c, app.Namespace) + if err != nil { + return err + } + + for _, entry := range typed.Sorted(volumeClasses) { + vc := entry.Value + if vc.Default && vc.Name != defaultVolumeClass.Name { + return fmt.Errorf("cannot resolve volume classes because two defaults volume classes exist: %s and %s", defaultVolumeClass.Name, vc.Name) + } + } + + if app.Status.ResolvedOfferings.Volumes == nil { + app.Status.ResolvedOfferings.Volumes = make(map[string]internalv1.VolumeResolvedOffering) + } + + volumeBindings := volume.SliceToMap(app.Spec.Volumes, func(vb internalv1.VolumeBinding) string { + return vb.Target + }) + + for name, vol := range app.Status.AppSpec.Volumes { + vol, err = volume.ResolveVolumeRequest(ctx, c, vol, volumeBindings[name], volumeClasses, defaultVolumeClass, app.Status.ResolvedOfferings.Volumes[name]) + if err != nil { + return err + } + resolvedVolume := internalv1.VolumeResolvedOffering{ + AccessModes: vol.AccessModes, + Class: vol.Class, + Size: vol.Size, + } + + // If an existing volume is bound to this volume request, then find it and use its values as the resolved offerings + if volumeBindings[name].Volume != "" { + // Try to find the volume by public name first + var boundVolumeList corev1.PersistentVolumeList + if err := c.List(ctx, &boundVolumeList, &kclient.ListOptions{ + LabelSelector: klabels.SelectorFromSet(map[string]string{ + labels.AcornPublicName: volumeBindings[name].Volume, + labels.AcornAppNamespace: app.Namespace, + labels.AcornManaged: "true", + }), + }); err != nil { + return fmt.Errorf("error while looking for bound volume %s in namespace %s: %w", volumeBindings[name].Volume, app.Namespace, err) + } else if len(boundVolumeList.Items) == 0 { + // See if the user provided a PV name instead + var boundPV corev1.PersistentVolume + if err := c.Get(ctx, kclient.ObjectKey{Name: volumeBindings[name].Volume}, &boundPV); err != nil { + return fmt.Errorf("error while looking for bound volume %s in namespace %s: %w", volumeBindings[name].Volume, app.Namespace, err) + } else if boundPV.ObjectMeta.Labels[labels.AcornAppNamespace] != app.Namespace { + return fmt.Errorf("could not find volume %s in project %s", volumeBindings[name].Volume, app.Namespace) + } + + boundVolumeList.Items = []corev1.PersistentVolume{boundPV} + } + + // If we found the volume, then use its values as the resolved offerings + if len(boundVolumeList.Items) == 1 { + for _, a := range boundVolumeList.Items[0].Spec.AccessModes { + resolvedVolume.AccessModes = append(resolvedVolume.AccessModes, internalv1.AccessMode(a)) + } + resolvedVolume.Class = boundVolumeList.Items[0].ObjectMeta.Labels[labels.AcornVolumeClass] + resolvedVolume.Size = internalv1.Quantity(boundVolumeList.Items[0].Spec.Capacity.Storage().String()) + } + } + + // This is a bit of a hack as we're migrating away from the VolumeSize field. Essentially, + // we want to ensure that app.Status.Volumes[name] always has a size set. If the VolumeSize + // field has been set in the past, we want to migrate that over to be set on app.Status.Volumes[name]. + // There is another edge case where the Size field was set by a VolumeClass's default size. In this + // case we want to leave the Size field alone. + if app.Status.ResolvedOfferings.VolumeSize != nil && resolvedVolume.Size == "" { + resolvedVolume.Size = internalv1.Quantity(app.Status.ResolvedOfferings.VolumeSize.String()) + } + + app.Status.ResolvedOfferings.Volumes[name] = resolvedVolume + } + + return nil +} diff --git a/pkg/controller/resolvedofferings/volumeclass_test.go b/pkg/controller/resolvedofferings/volumeclass_test.go new file mode 100644 index 000000000..1392ea034 --- /dev/null +++ b/pkg/controller/resolvedofferings/volumeclass_test.go @@ -0,0 +1,66 @@ +package resolvedofferings + +import ( + "testing" + + "github.com/acorn-io/baaah/pkg/router" + "github.com/acorn-io/baaah/pkg/router/tester" + "github.com/acorn-io/runtime/pkg/scheme" + "github.com/stretchr/testify/assert" +) + +func TestCalculateSameGeneration(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/volume-class-defaults-same-gen", Calculate) +} + +func TestFillVolumeClassDefaults(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/volume-class-fill-defaults", Calculate) +} + +func TestVolumeClassFillSizeDefaults(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/volume-class-fill-size", Calculate) +} + +func TestProjectVolumeClassDefault(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/volume-class-fill-project-default", Calculate) +} + +func TestClusterVolumeClassDefault(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/volume-class-fill-cluster-default", Calculate) +} + +func TestClusterProjectWithSameName(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/cluster-and-project-class-same-name", Calculate) +} + +func TestFillVolumeClassDefaultsWithVolumeBinding(t *testing.T) { + tester.DefaultTest(t, scheme.Scheme, "testdata/volumeclass/volume-class-fill-defaults-with-bind", Calculate) +} + +func TestTwoClusterDefaultsShouldError(t *testing.T) { + harness, input, err := tester.FromDir(scheme.Scheme, "testdata/volumeclass/volume-class-two-cluster-defaults") + if err != nil { + t.Fatal(err) + } + + resp, err := harness.Invoke(t, input, router.HandlerFunc(Calculate)) + if err != nil { + t.Fatal(err) + } + + assert.True(t, resp.NoPrune, "NoPrune should be true when error occurs") +} + +func TestTwoProjectDefaultsShouldError(t *testing.T) { + harness, input, err := tester.FromDir(scheme.Scheme, "testdata/volumeclass/volume-class-two-project-defaults") + if err != nil { + t.Fatal(err) + } + + resp, err := harness.Invoke(t, input, router.HandlerFunc(Calculate)) + if err != nil { + t.Fatal(err) + } + + assert.True(t, resp.NoPrune, "NoPrune should be true when error occurs") +} diff --git a/pkg/controller/routes.go b/pkg/controller/routes.go index fbbf9850d..41b864c7f 100644 --- a/pkg/controller/routes.go +++ b/pkg/controller/routes.go @@ -24,6 +24,7 @@ import ( "github.com/acorn-io/runtime/pkg/controller/permissions" "github.com/acorn-io/runtime/pkg/controller/pvc" "github.com/acorn-io/runtime/pkg/controller/quota" + "github.com/acorn-io/runtime/pkg/controller/resolvedofferings" "github.com/acorn-io/runtime/pkg/controller/scheduling" "github.com/acorn-io/runtime/pkg/controller/secrets" "github.com/acorn-io/runtime/pkg/controller/service" @@ -77,6 +78,7 @@ func routes(router *router.Router, cfg *rest.Config, registryTransport http.Roun // DeploySpec will create the namespace, so ensure it runs before anything that requires a namespace appHasNamespace := appRouter.Middleware(appdefinition.RequireNamespace, appdefinition.IgnoreTerminatingNamespace, appdefinition.FilterLabelsAndAnnotationsConfig) appHasNamespace.HandlerFunc(defaults.Calculate) + appHasNamespace.HandlerFunc(resolvedofferings.Calculate) appHasNamespace.HandlerFunc(scheduling.Calculate) appHasNamespace.HandlerFunc(quota.EnsureQuotaRequest) appHasNamespace.HandlerFunc(quota.WaitForAllocation) diff --git a/pkg/controller/scheduling/scheduling.go b/pkg/controller/scheduling/scheduling.go index cded2eabf..968c9ffc8 100644 --- a/pkg/controller/scheduling/scheduling.go +++ b/pkg/controller/scheduling/scheduling.go @@ -157,9 +157,9 @@ func ResourceRequirements(req router.Request, app *v1.AppInstance, containerName requirements := &corev1.ResourceRequirements{Limits: corev1.ResourceList{}, Requests: corev1.ResourceList{}} var memDefault *int64 - if val, ok := app.Status.Defaults.Memory[containerName]; ok && val != nil { + if val := app.Status.Defaults.Memory[containerName]; val != nil { memDefault = val - } else if val, ok := app.Status.Defaults.Memory[""]; ok && val != nil { + } else if val := app.Status.Defaults.Memory[""]; val != nil { memDefault = val } diff --git a/pkg/controller/scheduling/testdata/computeclass/all-set-overwrite-computeclass/expected.golden b/pkg/controller/scheduling/testdata/computeclass/all-set-overwrite-computeclass/expected.golden index 0a2cb4afb..34133bdd1 100644 --- a/pkg/controller/scheduling/testdata/computeclass/all-set-overwrite-computeclass/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/all-set-overwrite-computeclass/expected.golden @@ -52,6 +52,7 @@ status: oneimage: 2097152 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/all-set/expected.golden b/pkg/controller/scheduling/testdata/computeclass/all-set/expected.golden index 92115fed7..525a49f80 100644 --- a/pkg/controller/scheduling/testdata/computeclass/all-set/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/all-set/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/container/expected.golden b/pkg/controller/scheduling/testdata/computeclass/container/expected.golden index 88d74ed06..27911557d 100644 --- a/pkg/controller/scheduling/testdata/computeclass/container/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/container/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/different-computeclass/expected.golden b/pkg/controller/scheduling/testdata/computeclass/different-computeclass/expected.golden index 690a372d8..5c1bb0f37 100644 --- a/pkg/controller/scheduling/testdata/computeclass/different-computeclass/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/different-computeclass/expected.golden @@ -54,6 +54,7 @@ status: twoimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: oneimage: affinity: diff --git a/pkg/controller/scheduling/testdata/computeclass/different-digest-generation/expected.golden b/pkg/controller/scheduling/testdata/computeclass/different-digest-generation/expected.golden index b9a567d32..ebf00147e 100644 --- a/pkg/controller/scheduling/testdata/computeclass/different-digest-generation/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/different-digest-generation/expected.golden @@ -52,6 +52,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedImageDigest: foo + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/invalid-priority-class-should-error/expected.golden b/pkg/controller/scheduling/testdata/computeclass/invalid-priority-class-should-error/expected.golden index 0a1b8f50f..202c878f9 100644 --- a/pkg/controller/scheduling/testdata/computeclass/invalid-priority-class-should-error/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/invalid-priority-class-should-error/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/computeclass/job/expected.golden b/pkg/controller/scheduling/testdata/computeclass/job/expected.golden index 4fbf7b27b..ae94fddbb 100644 --- a/pkg/controller/scheduling/testdata/computeclass/job/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/job/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden b/pkg/controller/scheduling/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden index 04436e2ec..8e2706750 100644 --- a/pkg/controller/scheduling/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/overwrite-acornfile-computeclass/expected.golden @@ -52,6 +52,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/priority-class/expected.golden b/pkg/controller/scheduling/testdata/computeclass/priority-class/expected.golden index 637e03d17..5b70db5a4 100644 --- a/pkg/controller/scheduling/testdata/computeclass/priority-class/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/priority-class/expected.golden @@ -49,6 +49,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/computeclass/same-digest-generation/expected.golden b/pkg/controller/scheduling/testdata/computeclass/same-digest-generation/expected.golden index 01362fc8f..a275938d0 100644 --- a/pkg/controller/scheduling/testdata/computeclass/same-digest-generation/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/same-digest-generation/expected.golden @@ -52,6 +52,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedImageDigest: foo + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/same-generation/expected.golden b/pkg/controller/scheduling/testdata/computeclass/same-generation/expected.golden index 099032e78..7d0c7f223 100644 --- a/pkg/controller/scheduling/testdata/computeclass/same-generation/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/same-generation/expected.golden @@ -50,6 +50,7 @@ status: left: 1048576 oneimage: 1048576 namespace: app-created-namespace + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml b/pkg/controller/scheduling/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml index 54416cac0..b7d48a92a 100644 --- a/pkg/controller/scheduling/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml +++ b/pkg/controller/scheduling/testdata/computeclass/two-ccc-defaults-should-error/expected.yaml @@ -9,12 +9,13 @@ spec: memory: oneimage: 1048576 # 1Mi status: - observedGeneration: 1 defaults: memory: "": 0 - left: 1048576 # 1Mi - oneimage: 1048576 # 1Mi + left: 1048576 + oneimage: 1048576 + observedGeneration: 1 + resolvedOfferings: {} namespace: app-created-namespace appImage: id: test diff --git a/pkg/controller/scheduling/testdata/computeclass/two-containers/expected.golden b/pkg/controller/scheduling/testdata/computeclass/two-containers/expected.golden index 648117340..83f711883 100644 --- a/pkg/controller/scheduling/testdata/computeclass/two-containers/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/two-containers/expected.golden @@ -53,6 +53,7 @@ status: twoimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: oneimage: affinity: diff --git a/pkg/controller/scheduling/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml b/pkg/controller/scheduling/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml index a603062f3..f50dac7c3 100644 --- a/pkg/controller/scheduling/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml +++ b/pkg/controller/scheduling/testdata/computeclass/two-pcc-defaults-should-error/expected.yaml @@ -12,8 +12,9 @@ status: defaults: memory: "": 0 - left: 1048576 # 1Mi - oneimage: 1048576 # 1Mi + left: 1048576 + oneimage: 1048576 + resolvedOfferings: {} observedGeneration: 1 namespace: app-created-namespace appImage: diff --git a/pkg/controller/scheduling/testdata/computeclass/with-acornfile-computeclass/expected.golden b/pkg/controller/scheduling/testdata/computeclass/with-acornfile-computeclass/expected.golden index ffbcfb00f..0686d5612 100644 --- a/pkg/controller/scheduling/testdata/computeclass/with-acornfile-computeclass/expected.golden +++ b/pkg/controller/scheduling/testdata/computeclass/with-acornfile-computeclass/expected.golden @@ -50,6 +50,7 @@ status: oneimage: 1048576 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/memory/all-set-overwrite/expected.golden b/pkg/controller/scheduling/testdata/memory/all-set-overwrite/expected.golden index 215d2dc70..a0d7046c1 100644 --- a/pkg/controller/scheduling/testdata/memory/all-set-overwrite/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/all-set-overwrite/expected.golden @@ -52,6 +52,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/memory/all-set/expected.golden b/pkg/controller/scheduling/testdata/memory/all-set/expected.golden index d2ebab294..da6ddfdbc 100644 --- a/pkg/controller/scheduling/testdata/memory/all-set/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/all-set/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/memory/container/expected.golden b/pkg/controller/scheduling/testdata/memory/container/expected.golden index d31531e73..9a3f42408 100644 --- a/pkg/controller/scheduling/testdata/memory/container/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/container/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/memory/job/expected.golden b/pkg/controller/scheduling/testdata/memory/job/expected.golden index 81eba6dca..e89d80750 100644 --- a/pkg/controller/scheduling/testdata/memory/job/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/job/expected.golden @@ -51,6 +51,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/memory/overwrite-acornfile-memory/expected.golden b/pkg/controller/scheduling/testdata/memory/overwrite-acornfile-memory/expected.golden index 816279731..9218874c0 100644 --- a/pkg/controller/scheduling/testdata/memory/overwrite-acornfile-memory/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/overwrite-acornfile-memory/expected.golden @@ -52,6 +52,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/memory/same-generation/expected.golden b/pkg/controller/scheduling/testdata/memory/same-generation/expected.golden index c244d03de..02e39d738 100644 --- a/pkg/controller/scheduling/testdata/memory/same-generation/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/same-generation/expected.golden @@ -50,6 +50,7 @@ status: left: 0 oneimage: 0 namespace: app-created-namespace + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/memory/sidecar/expected.golden b/pkg/controller/scheduling/testdata/memory/sidecar/expected.golden index 19cbe99a0..5336316b1 100644 --- a/pkg/controller/scheduling/testdata/memory/sidecar/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/sidecar/expected.golden @@ -47,6 +47,7 @@ status: defaults: {} namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: diff --git a/pkg/controller/scheduling/testdata/memory/two-containers/expected.golden b/pkg/controller/scheduling/testdata/memory/two-containers/expected.golden index 653ca3172..82d125c37 100644 --- a/pkg/controller/scheduling/testdata/memory/two-containers/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/two-containers/expected.golden @@ -53,6 +53,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: oneimage: requirements: diff --git a/pkg/controller/scheduling/testdata/memory/with-acornfile-memory/expected.golden b/pkg/controller/scheduling/testdata/memory/with-acornfile-memory/expected.golden index 8a78515e4..73e7a155e 100644 --- a/pkg/controller/scheduling/testdata/memory/with-acornfile-memory/expected.golden +++ b/pkg/controller/scheduling/testdata/memory/with-acornfile-memory/expected.golden @@ -50,6 +50,7 @@ status: oneimage: 0 namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/tolerations/container/expected.golden b/pkg/controller/scheduling/testdata/tolerations/container/expected.golden index e04e1a4b4..78f6af63e 100644 --- a/pkg/controller/scheduling/testdata/tolerations/container/expected.golden +++ b/pkg/controller/scheduling/testdata/tolerations/container/expected.golden @@ -45,6 +45,7 @@ status: defaults: {} namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/controller/scheduling/testdata/tolerations/job/expected.golden b/pkg/controller/scheduling/testdata/tolerations/job/expected.golden index fedff8320..b9588af73 100644 --- a/pkg/controller/scheduling/testdata/tolerations/job/expected.golden +++ b/pkg/controller/scheduling/testdata/tolerations/job/expected.golden @@ -45,6 +45,7 @@ status: defaults: {} namespace: app-created-namespace observedGeneration: 1 + resolvedOfferings: {} scheduling: left: requirements: {} diff --git a/pkg/labels/labels.go b/pkg/labels/labels.go index cbcb114fd..1643f237a 100644 --- a/pkg/labels/labels.go +++ b/pkg/labels/labels.go @@ -61,6 +61,7 @@ const ( ProjectEnforcedQuotaAnnotation = Prefix + "enforced-quota" AcornPermissions = Prefix + "permissions" AcornConfigHashAnnotation = Prefix + "config-hash" + AcornContainerResolvedOfferings = Prefix + "container-resolved-offerings" IdentityPrefix = "identity." + Prefix AcornIdentityAccountServerURL = IdentityPrefix + "account-server-url" diff --git a/pkg/openapi/generated/openapi_generated.go b/pkg/openapi/generated/openapi_generated.go index 985f6ed93..3534bb0e3 100644 --- a/pkg/openapi/generated/openapi_generated.go +++ b/pkg/openapi/generated/openapi_generated.go @@ -137,6 +137,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Container": schema_pkg_apis_internalacornio_v1_Container(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ContainerData": schema_pkg_apis_internalacornio_v1_ContainerData(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ContainerImageBuilderSpec": schema_pkg_apis_internalacornio_v1_ContainerImageBuilderSpec(ref), + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ContainerResolvedOffering": schema_pkg_apis_internalacornio_v1_ContainerResolvedOffering(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ContainerStatus": schema_pkg_apis_internalacornio_v1_ContainerStatus(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults": schema_pkg_apis_internalacornio_v1_Defaults(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Dependency": schema_pkg_apis_internalacornio_v1_Dependency(ref), @@ -192,6 +193,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ProjectInstanceSpec": schema_pkg_apis_internalacornio_v1_ProjectInstanceSpec(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ProjectInstanceStatus": schema_pkg_apis_internalacornio_v1_ProjectInstanceStatus(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ReplicasSummary": schema_pkg_apis_internalacornio_v1_ReplicasSummary(ref), + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings": schema_pkg_apis_internalacornio_v1_ResolvedOfferings(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Route": schema_pkg_apis_internalacornio_v1_Route(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Router": schema_pkg_apis_internalacornio_v1_Router(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.RouterStatus": schema_pkg_apis_internalacornio_v1_RouterStatus(ref), @@ -219,6 +221,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeDefault": schema_pkg_apis_internalacornio_v1_VolumeDefault(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeMount": schema_pkg_apis_internalacornio_v1_VolumeMount(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeRequest": schema_pkg_apis_internalacornio_v1_VolumeRequest(ref), + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeResolvedOffering": schema_pkg_apis_internalacornio_v1_VolumeResolvedOffering(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeSecretMount": schema_pkg_apis_internalacornio_v1_VolumeSecretMount(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeStatus": schema_pkg_apis_internalacornio_v1_VolumeStatus(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.acornAliases": schema_pkg_apis_internalacornio_v1_acornAliases(ref), @@ -7021,6 +7024,12 @@ func schema_pkg_apis_internalacornio_v1_AppInstanceStatus(ref common.ReferenceCa Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults"), }, }, + "resolvedOfferings": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings"), + }, + }, "summary": { SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, @@ -7058,7 +7067,7 @@ func schema_pkg_apis_internalacornio_v1_AppInstanceStatus(ref common.ReferenceCa }, }, Dependencies: []string{ - "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppColumns", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppImage", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatusStaged", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.CommonSummary", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Condition", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Scheduling"}, + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppColumns", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppImage", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatusStaged", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.CommonSummary", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Condition", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Scheduling"}, } } @@ -8486,6 +8495,36 @@ func schema_pkg_apis_internalacornio_v1_ContainerImageBuilderSpec(ref common.Ref } } +func schema_pkg_apis_internalacornio_v1_ContainerResolvedOffering(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "class": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "memory": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + "cpuScaler": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + Format: "double", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_internalacornio_v1_ContainerStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -11026,6 +11065,59 @@ func schema_pkg_apis_internalacornio_v1_ReplicasSummary(ref common.ReferenceCall } } +func schema_pkg_apis_internalacornio_v1_ResolvedOfferings(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "volumes": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeResolvedOffering"), + }, + }, + }, + }, + }, + "volumeSize": { + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + "containers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ContainerResolvedOffering"), + }, + }, + }, + }, + }, + "region": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ContainerResolvedOffering", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeResolvedOffering", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, + } +} + func schema_pkg_apis_internalacornio_v1_Route(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -12881,6 +12973,44 @@ func schema_pkg_apis_internalacornio_v1_VolumeRequest(ref common.ReferenceCallba } } +func schema_pkg_apis_internalacornio_v1_VolumeResolvedOffering(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "class": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "size": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "accessModes": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_internalacornio_v1_VolumeSecretMount(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/server/registry/apigroups/acorn/projects/validator_test.go b/pkg/server/registry/apigroups/acorn/projects/validator_test.go index 9e67c7363..f22052bd3 100644 --- a/pkg/server/registry/apigroups/acorn/projects/validator_test.go +++ b/pkg/server/registry/apigroups/acorn/projects/validator_test.go @@ -236,6 +236,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-region", + }, + }, }, }, }, @@ -272,6 +277,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-region", + }, + }, }, }, }, @@ -313,6 +323,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-other-region", + }, + }, }, }, }, @@ -397,7 +412,7 @@ func TestProjectUpdateValidation(t *testing.T) { Namespace: "my-project", }, Status: v1.AppInstanceStatus{ - Defaults: v1.Defaults{ + ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, }, @@ -446,6 +461,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-other-region", + }, + }, }, }, }, @@ -488,6 +508,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-other-region", + }, + }, }, { ObjectMeta: metav1.ObjectMeta{ @@ -497,6 +522,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-region", + }, + }, }, }, }, @@ -539,6 +569,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-other-region", + }, + }, }, }, }, @@ -579,6 +614,11 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, + Status: v1.AppInstanceStatus{ + ResolvedOfferings: v1.ResolvedOfferings{ + Region: "my-other-region", + }, + }, }, }, }, diff --git a/pkg/volume/volume.go b/pkg/volume/volume.go index 96a7b2b31..60ca6c2b3 100644 --- a/pkg/volume/volume.go +++ b/pkg/volume/volume.go @@ -174,6 +174,60 @@ func CopyVolumeDefaults(volumeRequest v1.VolumeRequest, volumeBinding v1.VolumeB return volumeRequest } +func ResolveVolumeRequest(ctx context.Context, c client.Client, volumeRequest v1.VolumeRequest, + volumeBinding v1.VolumeBinding, volumeClasses map[string]adminv1.ProjectVolumeClassInstance, + defaultVolumeClass *adminv1.ProjectVolumeClassInstance, existingResolvedVolume v1.VolumeResolvedOffering) (v1.VolumeRequest, error) { + bind := volumeBinding.Volume != "" + trueVolumeClass := defaultVolumeClass.DeepCopy() + + if volumeBinding.Class != "" { + volumeRequest.Class = volumeBinding.Class + vc := volumeClasses[volumeBinding.Class] + trueVolumeClass = &vc + } else if volumeRequest.Class != "" { + vc := volumeClasses[volumeRequest.Class] + trueVolumeClass = &vc + } else if !bind && defaultVolumeClass != nil { + volumeRequest.Class = defaultVolumeClass.Name + } + + if volumeBinding.Size != "" { + volumeRequest.Size = volumeBinding.Size + } else if !bind && volumeRequest.Size == "" { + if existingResolvedVolume.Size != "" { + volumeRequest.Size = existingResolvedVolume.Size + } else if trueVolumeClass != nil { + volumeRequest.Size = trueVolumeClass.Size.Default + } else { + defaultSize, err := GetDefaultVolumeSize(ctx, c) + if err != nil { + return v1.VolumeRequest{}, err + } + volumeRequest.Size = defaultSize + } + } + + if len(volumeBinding.AccessModes) > 0 { + volumeRequest.AccessModes = volumeBinding.AccessModes + } else if !bind && len(volumeRequest.AccessModes) == 0 && trueVolumeClass != nil { + volumeRequest.AccessModes = trueVolumeClass.AllowedAccessModes + } + + // If there is an existing VolumeResolvedOffering, and we are not binding to an already existing volume, + // then make sure that we continue using the same VolumeClass and AccessModes, since those cannot be + // changed on existing volumes + if !bind { + if existingResolvedVolume.Class != "" { + volumeRequest.Class = existingResolvedVolume.Class + } + if len(existingResolvedVolume.AccessModes) > 0 { + volumeRequest.AccessModes = existingResolvedVolume.AccessModes + } + } + + return volumeRequest, nil +} + func FindDefaultStorageClass(ctx context.Context, c client.Reader) (string, error) { storageClasses := &storagev1.StorageClassList{} if err := c.List(ctx, storageClasses); err != nil { @@ -188,3 +242,19 @@ func FindDefaultStorageClass(ctx context.Context, c client.Reader) (string, erro return "", nil } + +func GetDefaultVolumeSize(ctx context.Context, c client.Client) (v1.Quantity, error) { + cfg, err := config.Get(ctx, c) + if err != nil { + return "", err + } + + // If the default volume size is set in the config, use that. Otherwise use the + // package level default in internalv1. + defaultVolumeSize := v1.DefaultSizeQuantity + if cfg.VolumeSizeDefault != "" { + defaultVolumeSize = v1.Quantity(cfg.VolumeSizeDefault) + } + + return defaultVolumeSize, nil +}