Skip to content

Commit d3332e5

Browse files
mschmidt291voigt
authored andcommitted
Add Job Function
Signed-off-by: Max Schmidt <[email protected]>
1 parent 4c2cfb6 commit d3332e5

File tree

7 files changed

+192
-37
lines changed

7 files changed

+192
-37
lines changed

api/v1beta1/shim_types.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,13 @@ type RollingSpec struct {
5050
}
5151

5252
// ShimStatus defines the observed state of Shim
53+
// +operator-sdk:csv:customresourcedefinitions:type=status
5354
type ShimStatus struct {
54-
Conditions []ShimCondition `json:"conditions"`
55-
}
56-
57-
type ShimCondition struct {
58-
Type string `json:"type"`
59-
Status string `json:"status"`
60-
ConditionSeverity string `json:"conditionSeverity"`
61-
LastTransitionTime string `json:"lastTransitionTime"`
62-
Reason string `json:"reason"`
63-
Message string `json:"message"`
55+
Conditions []metav1.Condition `json:"conditions,omitempty"`
6456
}
6557

6658
// +kubebuilder:object:root=true
6759
// +kubebuilder:resource:path=shims,scope=Cluster
68-
// +kubebuilder:subresource:status
6960
// Shim is the Schema for the shims API
7061
type Shim struct {
7162
metav1.TypeMeta `json:",inline"`

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 5 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/runtime.kwasm.sh_shims.yaml

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,33 +83,73 @@ spec:
8383
properties:
8484
conditions:
8585
items:
86+
description: "Condition contains details for one aspect of the current
87+
state of this API Resource. --- This struct is intended for direct
88+
use as an array at the field path .status.conditions. For example,
89+
\n type FooStatus struct{ // Represents the observations of a
90+
foo's current state. // Known .status.conditions.type are: \"Available\",
91+
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
92+
// +listType=map // +listMapKey=type Conditions []metav1.Condition
93+
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
94+
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
8695
properties:
87-
conditionSeverity:
88-
type: string
8996
lastTransitionTime:
97+
description: lastTransitionTime is the last time the condition
98+
transitioned from one status to another. This should be when
99+
the underlying condition changed. If that is not known, then
100+
using the time when the API field changed is acceptable.
101+
format: date-time
90102
type: string
91103
message:
104+
description: message is a human readable message indicating
105+
details about the transition. This may be an empty string.
106+
maxLength: 32768
92107
type: string
108+
observedGeneration:
109+
description: observedGeneration represents the .metadata.generation
110+
that the condition was set based upon. For instance, if .metadata.generation
111+
is currently 12, but the .status.conditions[x].observedGeneration
112+
is 9, the condition is out of date with respect to the current
113+
state of the instance.
114+
format: int64
115+
minimum: 0
116+
type: integer
93117
reason:
118+
description: reason contains a programmatic identifier indicating
119+
the reason for the condition's last transition. Producers
120+
of specific condition types may define expected values and
121+
meanings for this field, and whether the values are considered
122+
a guaranteed API. The value should be a CamelCase string.
123+
This field may not be empty.
124+
maxLength: 1024
125+
minLength: 1
126+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
94127
type: string
95128
status:
129+
description: status of the condition, one of True, False, Unknown.
130+
enum:
131+
- "True"
132+
- "False"
133+
- Unknown
96134
type: string
97135
type:
136+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
137+
--- Many .condition.type values are consistent across resources
138+
like Available, but because arbitrary conditions can be useful
139+
(see .node.status.conditions), the ability to deconflict is
140+
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
141+
maxLength: 316
142+
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
98143
type: string
99144
required:
100-
- conditionSeverity
101145
- lastTransitionTime
102146
- message
103147
- reason
104148
- status
105149
- type
106150
type: object
107151
type: array
108-
required:
109-
- conditions
110152
type: object
111153
type: object
112154
served: true
113155
storage: true
114-
subresources:
115-
status: {}

config/manager/kustomization.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
resources:
22
- manager.yaml
3+
apiVersion: kustomize.config.k8s.io/v1beta1
4+
kind: Kustomization
5+
images:
6+
- name: controller
7+
newName: controller
8+
newTag: latest

controllers/shim_controller.go

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,38 @@ package controllers
1818

1919
import (
2020
"context"
21+
"fmt"
22+
"os"
2123

2224
"k8s.io/apimachinery/pkg/runtime"
25+
"k8s.io/client-go/tools/record"
2326
ctrl "sigs.k8s.io/controller-runtime"
2427
"sigs.k8s.io/controller-runtime/pkg/client"
28+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2529
"sigs.k8s.io/controller-runtime/pkg/log"
2630

31+
"github.com/kwasm/kwasm-operator/api/v1beta1"
2732
runtimev1beta1 "github.com/kwasm/kwasm-operator/api/v1beta1"
33+
batchv1 "k8s.io/api/batch/v1"
34+
corev1 "k8s.io/api/core/v1"
35+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2836
)
2937

3038
// ShimReconciler reconciles a Shim object
3139
type ShimReconciler struct {
3240
client.Client
33-
Scheme *runtime.Scheme
41+
Scheme *runtime.Scheme
42+
Recorder record.EventRecorder
3443
}
3544

45+
// Definitions to manage status conditions
46+
const (
47+
// typeAvailableShim represents the status of the Deployment reconciliation
48+
typeAvailableShim = "Available"
49+
// typeDegradedShim represents the status used when the custom resource is deleted and the finalizer operations are must to occur.
50+
typeDegradedShim = "Degraded"
51+
)
52+
3653
//+kubebuilder:rbac:groups=runtime.kwasm.sh,resources=shims,verbs=get;list;watch;create;update;patch;delete
3754
//+kubebuilder:rbac:groups=runtime.kwasm.sh,resources=shims/status,verbs=get;update;patch
3855
//+kubebuilder:rbac:groups=runtime.kwasm.sh,resources=shims/finalizers,verbs=update
@@ -48,12 +65,64 @@ type ShimReconciler struct {
4865
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile
4966
func (r *ShimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
5067
_ = log.FromContext(ctx)
68+
// Fetch the Shim custom resource
69+
shim := &v1beta1.Shim{}
70+
err := r.Get(ctx, req.NamespacedName, shim)
71+
if err != nil {
72+
return ctrl.Result{}, client.IgnoreNotFound(err)
73+
}
74+
75+
// Create a new Kubernetes Job based on the Shim custom resource
76+
job := r.buildJobForShim(shim)
77+
78+
// Set the owner reference to the Shim custom resource
79+
if err := controllerutil.SetControllerReference(shim, job, r.Scheme); err != nil {
80+
return ctrl.Result{}, err
81+
}
5182

52-
// TODO(user): your logic here
83+
// Check if the Job already exists, if not, create it
84+
found := &batchv1.Job{}
85+
err = r.Get(ctx, req.NamespacedName, found)
86+
if err != nil && client.IgnoreNotFound(err) != nil {
87+
return ctrl.Result{}, err
88+
}
5389

90+
if err != nil {
91+
// Job does not exist, create it
92+
if err := r.Create(ctx, job); err != nil {
93+
return ctrl.Result{}, err
94+
}
95+
return ctrl.Result{}, nil
96+
}
97+
98+
// Job already exists, do nothing
5499
return ctrl.Result{}, nil
55100
}
56101

102+
func (r *ShimReconciler) buildJobForShim(shim *v1beta1.Shim) *batchv1.Job {
103+
job := &batchv1.Job{
104+
ObjectMeta: metav1.ObjectMeta{
105+
Name: fmt.Sprintf("shim-job-%s", shim.Name),
106+
Namespace: os.Getenv("CONTROLLER_NAMESPACE"),
107+
},
108+
Spec: batchv1.JobSpec{
109+
Template: corev1.PodTemplateSpec{
110+
Spec: corev1.PodSpec{
111+
Containers: []corev1.Container{
112+
{
113+
Name: "my-shim-container",
114+
Image: "your-specific-image", // Set your specific image here
115+
// Add other container settings as needed
116+
},
117+
},
118+
RestartPolicy: "Never",
119+
},
120+
},
121+
},
122+
}
123+
return job
124+
}
125+
57126
// SetupWithManager sets up the controller with the Manager.
58127
func (r *ShimReconciler) SetupWithManager(mgr ctrl.Manager) error {
59128
return ctrl.NewControllerManagedBy(mgr).

main.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package main
1818

1919
import (
2020
"flag"
21+
"fmt"
2122
"os"
2223

2324
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
@@ -48,6 +49,20 @@ func init() {
4849
//+kubebuilder:scaffold:scheme
4950
}
5051

52+
// getWatchNamespace returns the Namespace the operator should be watching for changes
53+
func getWatchNamespace() string {
54+
// WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE
55+
// which specifies the Namespace to watch.
56+
// An empty value means the operator will fail to start.
57+
var watchNamespaceEnvVar = "CONTROLLER_NAMESPACE"
58+
59+
ns, found := os.LookupEnv(watchNamespaceEnvVar)
60+
if !found {
61+
panic(fmt.Sprintf("env var '%s' must be set", watchNamespaceEnvVar))
62+
}
63+
return ns
64+
}
65+
5166
func main() {
5267
var metricsAddr string
5368
var enableLeaderElection bool
@@ -70,6 +85,7 @@ func main() {
7085
MetricsBindAddress: metricsAddr,
7186
Port: 9443,
7287
HealthProbeBindAddress: probeAddr,
88+
Namespace: getWatchNamespace(),
7389
LeaderElection: enableLeaderElection,
7490
LeaderElectionID: "7584d300.kwasm.sh",
7591
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily

test-crd.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
apiVersion: runtime.kwasm.sh/v1beta1
2+
kind: Shim
3+
metadata:
4+
# The Shim resource is a cluster wide resource, no namespace.
5+
name: my-shim-v0.1.2
6+
spec:
7+
# optional: label selector for nodes to target with shim.
8+
# If not supplied, the shim should be installed on all nodes.
9+
nodeSelector:
10+
wasm: "true"
11+
12+
# required: The method for fetching a shim.
13+
# This could be any number of strategies for fetching. For example, OCI.
14+
fetchStrategy:
15+
anonHttp:
16+
location: https://github.com/some-org/some-project/releases/v0.8.0/shims.tar.gz
17+
18+
# required: The runtime class to be applied in the cluster for the shim.
19+
#
20+
# The validation for this structure should also validate the `handler`
21+
# will map to the name / path of the shim binary that is installed on the node.
22+
#
23+
# Upon installation of a shim to a node, a label should be added to the node
24+
# to indicate a specific shim is installed on the node. This label must be
25+
# used to inform the K8s scheduler where to schedule workloads for the given
26+
# runtime class.
27+
#
28+
# ---
29+
# apiVersion: node.k8s.io/v1
30+
# kind: RuntimeClass
31+
# metadata:
32+
# name: myshim-v0.1.2
33+
# handler: myshim_v0_1_2
34+
# scheduling:
35+
# nodeSelector:
36+
# myshim_v0_1_2: "true"
37+
runtimeClass:
38+
name: my-shim-v0.1.2
39+
40+
# rolloutStrategy describes how a change to this shim will be applied to nodes.
41+
rolloutStrategy:
42+
type: rolling
43+
rolling:
44+
maxUpdate: 5 # could also be a percentage of nodes, like 10% of nodes.
45+
# conditions should provide the status of the resource and it's progression

0 commit comments

Comments
 (0)