Skip to content

Commit 15df44b

Browse files
astefanuttiopenshift-merge-robot
authored andcommitted
feat(api): Support custom InstaScale container image
1 parent be42693 commit 15df44b

File tree

7 files changed

+99
-34
lines changed

7 files changed

+99
-34
lines changed

Diff for: Makefile

+33-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
PREVIOUS_VERSION ?= 0.0.3
1010
VERSION ?= 0.0.3-dev
1111

12+
# INSTASCALE_VERSION defines the default version of the InstaScale controller
13+
INSTASCALE_VERSION ?= v0.0.3
14+
1215
# CHANNELS define the bundle channels used in the bundle.
1316
# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable")
1417
# To re-generate a bundle for other specific channels without changing the standard setup, you can:
@@ -28,12 +31,18 @@ BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL)
2831
endif
2932
BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL)
3033

34+
# IMAGE_ORG_BASE defines the base container registry and organization for container images.
35+
IMAGE_ORG_BASE ?= quay.io/project-codeflare
36+
3137
# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images.
3238
# This variable is used to construct full image tags for bundle and catalog images.
3339
#
3440
# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both
3541
# codeflare.dev/codeflare-operator-bundle:$VERSION and codeflare.dev/codeflare-operator-catalog:$VERSION.
36-
IMAGE_TAG_BASE ?= quay.io/project-codeflare/codeflare-operator
42+
IMAGE_TAG_BASE ?= $(IMAGE_ORG_BASE)/codeflare-operator
43+
44+
# INSTASCALE_IMAGE defines the default container image for the InstaScale controller
45+
INSTASCALE_IMAGE ?= $(IMAGE_ORG_BASE)/instascale-controller:$(INSTASCALE_VERSION)
3746

3847
# BUNDLE_IMG defines the image:tag used for the bundle.
3948
# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=<some-registry>/<project-name-bundle>:<tag>)
@@ -89,6 +98,25 @@ help: ## Display this help.
8998

9099
##@ Development
91100

101+
DEFAULTS_FILE := controllers/defaults.go
102+
103+
.PHONY: defaults
104+
defaults:
105+
$(info Regenerating $(DEFAULTS_FILE))
106+
@echo "package controllers" > $(DEFAULTS_FILE)
107+
@echo "" >> $(DEFAULTS_FILE)
108+
@echo "// ***********************" >> $(DEFAULTS_FILE)
109+
@echo "// DO NOT EDIT THIS FILE" >> $(DEFAULTS_FILE)
110+
@echo "// ***********************" >> $(DEFAULTS_FILE)
111+
@echo "" >> $(DEFAULTS_FILE)
112+
@echo "const (" >> $(DEFAULTS_FILE)
113+
@echo " InstaScaleImage = \"$(INSTASCALE_IMAGE)\"" >> $(DEFAULTS_FILE)
114+
@echo "" >> $(DEFAULTS_FILE)
115+
@echo ")" >> $(DEFAULTS_FILE)
116+
@echo "" >> $(DEFAULTS_FILE)
117+
118+
gofmt -w $(DEFAULTS_FILE)
119+
92120
.PHONY: manifests
93121
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
94122
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
@@ -109,11 +137,11 @@ vet: ## Run go vet against code.
109137
##@ Build
110138

111139
.PHONY: build
112-
build: generate fmt vet ## Build manager binary.
140+
build: defaults generate fmt vet ## Build manager binary.
113141
go build -o bin/manager main.go
114142

115143
.PHONY: run
116-
run: manifests generate fmt vet ## Run a controller from your host.
144+
run: defaults manifests generate fmt vet ## Run a controller from your host.
117145
go run ./main.go
118146

119147
.PHONY: image-build
@@ -193,7 +221,7 @@ validate-bundle: install-operator-sdk
193221
$(OPERATOR_SDK) bundle validate ./bundle --select-optional suite=operatorframework
194222

195223
.PHONY: bundle
196-
bundle: manifests kustomize install-operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
224+
bundle: defaults manifests kustomize install-operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
197225
$(OPERATOR_SDK) generate kustomize manifests -q
198226
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
199227
cd config/manifests && $(KUSTOMIZE) edit add patch --patch '[{"op":"add", "path":"/metadata/annotations/containerImage", "value": "$(IMG)" }]' --kind ClusterServiceVersion
@@ -251,5 +279,5 @@ catalog-push: ## Push a catalog image.
251279
$(MAKE) image-push IMG=$(CATALOG_IMG)
252280

253281
.PHONY: test-unit
254-
test-unit: manifests generate fmt vet envtest ## Run tests.
282+
test-unit: defaults manifests generate fmt vet envtest ## Run tests.
255283
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out

Diff for: api/v1alpha1/instascale_types.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ type InstaScaleSpec struct {
3838

3939
// controllerResources determines the container resources for the InstaScale controller deployment
4040
ControllerResources *v1.ResourceRequirements `json:"controllerResources,omitempty"`
41+
42+
// The container image for the InstaScale controller deployment.
43+
// If specified, the provided container image must be compatible with the running CodeFlare operator.
44+
// Using an incompatible, or unrelated container image, will result in an undefined behavior.
45+
// A CodeFlare operator upgrade will not upgrade the InstaScale controller, that'll keep running this
46+
// specified container image.
47+
// If not specified, the latest version compatible with the running CodeFlare operator is used.
48+
// A CodeFlare operator upgrade may upgrade the InstaScale controller to a newer container image.
49+
//
50+
// +optional
51+
ControllerImage string `json:"controllerImage,omitempty"`
4152
}
4253

4354
// InstaScaleStatus defines the observed state of InstaScale
@@ -48,8 +59,8 @@ type InstaScaleStatus struct {
4859
Ready bool `json:"ready"`
4960
}
5061

51-
//+kubebuilder:object:root=true
52-
//+kubebuilder:subresource:status
62+
// +kubebuilder:object:root=true
63+
// +kubebuilder:subresource:status
5364

5465
// InstaScale is the Schema for the instascales API
5566
// +operator-sdk:csv:customresourcedefinitions:displayName="InstaScale"
@@ -61,7 +72,7 @@ type InstaScale struct {
6172
Status InstaScaleStatus `json:"status,omitempty"`
6273
}
6374

64-
//+kubebuilder:object:root=true
75+
// +kubebuilder:object:root=true
6576

6677
// InstaScaleList contains a list of InstaScale
6778
type InstaScaleList struct {

Diff for: config/crd/bases/codeflare.codeflare.dev_instascales.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ spec:
3535
spec:
3636
description: InstaScaleSpec defines the desired state of InstaScale
3737
properties:
38+
controllerImage:
39+
description: The container image for the InstaScale controller deployment.
40+
If specified, the provided container image must be compatible with
41+
the running CodeFlare operator. Using an incompatible, or unrelated
42+
container image, will result in an undefined behavior. A CodeFlare
43+
operator upgrade will not upgrade the InstaScale controller, that'll
44+
keep running this specified container image. If not specified, the
45+
latest version compatible with the running CodeFlare operator is
46+
used. A CodeFlare operator upgrade may upgrade the InstaScale controller
47+
to a newer container image.
48+
type: string
3849
controllerResources:
3950
description: controllerResources determines the container resources
4051
for the InstaScale controller deployment

Diff for: config/internal/instascale/deployment.yaml.tmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ spec:
1818
containers:
1919
- args:
2020
- "--configs-namespace={{.Namespace}}"
21-
image: quay.io/project-codeflare/instascale-controller:v0.0.3
21+
image: {{.ControllerImage}}
2222
name: instascale
2323
resources: {{.ControllerResources}}
2424
serviceAccountName: instascale-{{.Name}}-sa

Diff for: controllers/defaults.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package controllers
2+
3+
// ***********************
4+
// DO NOT EDIT THIS FILE
5+
// ***********************
6+
7+
const (
8+
InstaScaleImage = "quay.io/project-codeflare/instascale-controller:v0.0.3"
9+
)

Diff for: controllers/instascale_controller.go

+18-20
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package controllers
1919
import (
2020
"context"
2121
"fmt"
22+
"path"
2223

2324
appsv1 "k8s.io/api/apps/v1"
2425
corev1 "k8s.io/api/core/v1"
@@ -27,6 +28,7 @@ import (
2728
apierrs "k8s.io/apimachinery/pkg/api/errors"
2829
"k8s.io/apimachinery/pkg/runtime"
2930
"k8s.io/apimachinery/pkg/types"
31+
3032
ctrl "sigs.k8s.io/controller-runtime"
3133
"sigs.k8s.io/controller-runtime/pkg/client"
3234
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -36,6 +38,7 @@ import (
3638

3739
"github.com/go-logr/logr"
3840
mf "github.com/manifestival/manifestival"
41+
3942
codeflarev1alpha1 "github.com/project-codeflare/codeflare-operator/api/v1alpha1"
4043
"github.com/project-codeflare/codeflare-operator/controllers/config"
4144
"github.com/project-codeflare/codeflare-operator/controllers/util"
@@ -55,8 +58,7 @@ var instascaleClusterScopedTemplates = []string{
5558
}
5659

5760
func (r *InstaScaleReconciler) Apply(owner mf.Owner, params *InstaScaleParams, template string, fns ...mf.Transformer) error {
58-
59-
tmplManifest, err := config.Manifest(r.Client, r.TemplatesPath+template, params, template, r.Log)
61+
tmplManifest, err := config.Manifest(r.Client, path.Join(r.TemplatesPath, template), params, template, r.Log)
6062
if err != nil {
6163
return fmt.Errorf("error loading template yaml: %w", err)
6264
}
@@ -77,17 +79,17 @@ func (r *InstaScaleReconciler) Apply(owner mf.Owner, params *InstaScaleParams, t
7779

7880
// TODO: Review node permissions, instascale should only require read
7981

80-
//+kubebuilder:rbac:groups=codeflare.codeflare.dev,resources=instascales,verbs=get;list;watch;create;update;patch;delete
81-
//+kubebuilder:rbac:groups=codeflare.codeflare.dev,resources=instascales/status,verbs=get;update;patch
82-
//+kubebuilder:rbac:groups=codeflare.codeflare.dev,resources=instascales/finalizers,verbs=update
83-
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
84-
//+kubebuilder:rbac:groups=*,resources=deployments;services,verbs=get;list;watch;create;update;patch;delete
85-
//+kubebuilder:rbac:groups=core,resources=secrets;configmaps;nodes;services;serviceaccounts;persistentvolumes;persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
86-
//+kubebuilder:rbac:groups=core,resources=persistentvolumes;persistentvolumeclaims,verbs=*
87-
//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
88-
//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update;delete
89-
//+kubebuilder:rbac:groups=machine.openshift.io,resources=*,verbs=get;list;watch;create;update;patch;delete
90-
//+kubebuilder:rbac:groups=mcad.ibm.com,resources=appwrappers;queuejobs;schedulingspecs,verbs=get;list;watch;create;update;patch;delete
82+
// +kubebuilder:rbac:groups=codeflare.codeflare.dev,resources=instascales,verbs=get;list;watch;create;update;patch;delete
83+
// +kubebuilder:rbac:groups=codeflare.codeflare.dev,resources=instascales/status,verbs=get;update;patch
84+
// +kubebuilder:rbac:groups=codeflare.codeflare.dev,resources=instascales/finalizers,verbs=update
85+
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
86+
// +kubebuilder:rbac:groups=*,resources=deployments;services,verbs=get;list;watch;create;update;patch;delete
87+
// +kubebuilder:rbac:groups=core,resources=secrets;configmaps;nodes;services;serviceaccounts;persistentvolumes;persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
88+
// +kubebuilder:rbac:groups=core,resources=persistentvolumes;persistentvolumeclaims,verbs=*
89+
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
90+
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update;delete
91+
// +kubebuilder:rbac:groups=machine.openshift.io,resources=*,verbs=get;list;watch;create;update;patch;delete
92+
// +kubebuilder:rbac:groups=mcad.ibm.com,resources=appwrappers;queuejobs;schedulingspecs,verbs=get;list;watch;create;update;patch;delete
9193

9294
// Reconcile is part of the main kubernetes reconciliation loop which aims to
9395
// move the current state of the cluster closer to the desired state.
@@ -124,11 +126,7 @@ func (r *InstaScaleReconciler) Reconcile(ctx context.Context, req ctrl.Request)
124126
instascaleCustomResource.APIVersion, instascaleCustomResource.Kind = gvk.Version, gvk.Kind
125127
}
126128

127-
err = params.ExtractParams(instascaleCustomResource)
128-
if err != nil {
129-
log.Error(err, "Unable to parse InstaScale custom resource")
130-
return ctrl.Result{}, err
131-
}
129+
params.ExtractParams(instascaleCustomResource)
132130

133131
if instascaleCustomResource.ObjectMeta.DeletionTimestamp.IsZero() {
134132
if !controllerutil.ContainsFinalizer(instascaleCustomResource, finalizerName) {
@@ -152,7 +150,6 @@ func (r *InstaScaleReconciler) Reconcile(ctx context.Context, req ctrl.Request)
152150
return ctrl.Result{}, nil
153151
}
154152

155-
log.V(1).Info("ReconcileInstaScale called.")
156153
err = r.ReconcileInstaScale(instascaleCustomResource, params)
157154
if err != nil {
158155
return ctrl.Result{}, err
@@ -162,7 +159,8 @@ func (r *InstaScaleReconciler) Reconcile(ctx context.Context, req ctrl.Request)
162159
if err != nil {
163160
return ctrl.Result{}, err
164161
}
165-
err = r.Client.Status().Update(context.Background(), instascaleCustomResource)
162+
163+
err = r.Client.Status().Update(ctx, instascaleCustomResource)
166164
if err != nil {
167165
return ctrl.Result{}, err
168166
}

Diff for: controllers/instascale_params.go

+13-5
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,25 @@ package controllers
33
import (
44
"encoding/json"
55

6-
mf "github.com/manifestival/manifestival"
7-
instascalev1alpha1 "github.com/project-codeflare/codeflare-operator/api/v1alpha1"
6+
"github.com/manifestival/manifestival"
7+
88
v1 "k8s.io/api/core/v1"
99
"k8s.io/apimachinery/pkg/api/resource"
10+
11+
instascalev1alpha1 "github.com/project-codeflare/codeflare-operator/api/v1alpha1"
1012
)
1113

1214
type InstaScaleParams struct {
1315
Name string
1416
Namespace string
15-
Owner mf.Owner
17+
Owner manifestival.Owner
1618
EnableMonitoring bool
1719
MaxScaleoutAllowed int
1820
UseMachinePools bool
1921
ControllerResources ControllerResources
22+
ControllerImage string
2023
}
24+
2125
type ControllerResources struct {
2226
v1.ResourceRequirements
2327
}
@@ -29,9 +33,14 @@ func (c *ControllerResources) String() string {
2933
}
3034
return string(raw)
3135
}
32-
func (p *InstaScaleParams) ExtractParams(instascale *instascalev1alpha1.InstaScale) error {
36+
37+
func (p *InstaScaleParams) ExtractParams(instascale *instascalev1alpha1.InstaScale) {
3338
p.Name = instascale.Name
3439
p.Namespace = instascale.Namespace
40+
p.ControllerImage = instascale.Spec.ControllerImage
41+
if p.ControllerImage == "" {
42+
p.ControllerImage = InstaScaleImage
43+
}
3544
p.Owner = instascale
3645
p.EnableMonitoring = instascale.Spec.EnableMonitoring
3746
p.MaxScaleoutAllowed = instascale.Spec.MaxScaleoutAllowed
@@ -49,5 +58,4 @@ func (p *InstaScaleParams) ExtractParams(instascale *instascalev1alpha1.InstaSca
4958
} else {
5059
p.ControllerResources = ControllerResources{*instascale.Spec.ControllerResources}
5160
}
52-
return nil
5361
}

0 commit comments

Comments
 (0)