/
statefulset.go
160 lines (139 loc) · 3.75 KB
/
statefulset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
Copyright 2023 Lawrence Livermore National Security, LLC
(c.f. AUTHORS, NOTICE.LLNS, COPYING)
SPDX-License-Identifier: MIT
*/
package controllers
import (
"context"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// corev1 "k8s.io/api/core/v1"
api "github.com/converged-computing/oras-operator/api/v1alpha1"
"github.com/converged-computing/oras-operator/pkg/defaults"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
)
// getExistingJob gets an existing job that matches our CRD
func (r *OrasCacheReconciler) getExistingStatefulSet(
ctx context.Context,
set *api.OrasCache,
) (*appsv1.StatefulSet, error) {
existing := &appsv1.StatefulSet{}
err := r.Client.Get(
ctx,
types.NamespacedName{
Name: set.Name,
Namespace: set.Namespace,
},
existing,
)
return existing, err
}
// getStatefulSet retrieves the stateful set (or creates a new one)
func (r *OrasCacheReconciler) getStatefulSet(
ctx context.Context,
spec *api.OrasCache,
) (*appsv1.StatefulSet, ctrl.Result, bool, error) {
// Look for an existing job
set, err := r.getExistingStatefulSet(ctx, spec)
// Create a new job if it does not exist
if err != nil {
r.Log.Info(
"✨ Creating a new Oras Cache ✨",
"Namespace:", spec.Namespace,
"Name:", spec.Name,
)
// Get one JobSet and container specs to create config maps
set, err = r.createStatefulSet(ctx, spec)
// We don't create it here, we need configmaps first
return set, ctrl.Result{}, false, err
}
r.Log.Info(
"🎉 Found existing Oras Cache 🎉",
"Namespace:", set.Namespace,
"Name:", set.Name,
)
return set, ctrl.Result{}, true, err
}
// createStatefulSet creates the set (after we know it does not exist)
func (r *OrasCacheReconciler) createStatefulSet(
ctx context.Context,
spec *api.OrasCache,
) (*appsv1.StatefulSet, error) {
r.Log.Info(
"🎉 Creating Oras Cache 🎉",
"Namespace:", spec.Namespace,
"Name:", spec.Name,
)
// start with one registry for now
var replicas int32 = 1
labels := map[string]string{
defaults.OrasSelectorKey: spec.Namespace,
}
set := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: spec.Name,
Namespace: spec.Namespace,
},
Spec: appsv1.StatefulSetSpec{
Replicas: &replicas,
Selector: &metav1.LabelSelector{
MatchLabels: labels,
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
},
Spec: v1.PodSpec{
// TODO likely we want support for volumes here (for more registry space)
Volumes: []v1.Volume{},
Containers: []v1.Container{{
Name: "oras",
Image: spec.Spec.Image,
}},
// RestartPolicy defaults to Always
},
},
ServiceName: spec.Name,
// Default UpdateStrategy is RollingUpdate
},
}
// Prepare environment variables
// Do we have a secret?
if spec.Spec.Secrets.RegistryHttp != "" {
env := []corev1.EnvVar{}
env = append(env, corev1.EnvVar{
Name: "REGISTRY_HTTP_SECRET",
Value: spec.Spec.Secrets.RegistryHttp,
})
set.Spec.Template.Spec.Containers[0].Env = env
}
// Are we also adding environment variables from a secret?
if spec.Spec.Secrets.OrasEnv != "" {
set.Spec.Template.Spec.Containers[0].EnvFrom = []v1.EnvFromSource{
{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: spec.Spec.Secrets.OrasEnv,
},
},
},
}
}
// Controller reference always needs to be set before creation
ctrl.SetControllerReference(spec, set, r.Scheme)
err := r.Client.Create(ctx, set)
if err != nil {
r.Log.Error(
err,
"Failed to create new Oras Cache",
"Namespace:", set.Namespace,
"Name:", set.Name,
)
return set, err
}
return set, nil
}