Skip to content

Commit a2a5553

Browse files
authored
[Feature] Split & Unify Lifecycle management functionality (#821)
1 parent 57eb6e9 commit a2a5553

25 files changed

+496
-348
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Change Log
22

33
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
4+
- Split & Unify Lifecycle management functionality
45

56
## [1.2.4](https://github.com/arangodb/kube-arangodb/tree/1.2.4) (2021-10-22)
67
- Replace `beta.kubernetes.io/arch` Pod label with `kubernetes.io/arch` using Silent Rotation

lifecycle.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ var (
4747

4848
cmdLifecyclePreStop = &cobra.Command{
4949
Use: "preStop",
50-
Run: cmdLifecyclePreStopRun,
50+
Hidden: true,
51+
}
52+
cmdLifecyclePreStopFinalizers = &cobra.Command{
53+
Use: "finalizers",
54+
Run: cmdLifecyclePreStopRunFinalizer,
5155
Hidden: true,
5256
}
5357
cmdLifecycleCopy = &cobra.Command{
@@ -63,6 +67,9 @@ var (
6367

6468
func init() {
6569
cmdMain.AddCommand(cmdLifecycle)
70+
71+
cmdLifecyclePreStop.AddCommand(cmdLifecyclePreStopFinalizers)
72+
6673
cmdLifecycle.AddCommand(cmdLifecyclePreStop)
6774
cmdLifecycle.AddCommand(cmdLifecycleCopy)
6875
cmdLifecycle.AddCommand(cmdLifecycleProbe)
@@ -71,7 +78,7 @@ func init() {
7178
}
7279

7380
// Wait until all finalizers of the current pod have been removed.
74-
func cmdLifecyclePreStopRun(cmd *cobra.Command, args []string) {
81+
func cmdLifecyclePreStopRunFinalizer(cmd *cobra.Command, args []string) {
7582

7683
cliLog.Info().Msgf("Starting arangodb-operator (%s), lifecycle preStop, version %s build %s", version.GetVersionV1().Edition.Title(), version.GetVersionV1().Version, version.GetVersionV1().Build)
7784

main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,13 +362,12 @@ func newOperatorConfigAndDeps(id, namespace, name string) (operator.Config, oper
362362
Namespace: namespace,
363363
PodName: name,
364364
ServiceAccount: serviceAccount,
365-
LifecycleImage: image,
365+
OperatorImage: image,
366366
EnableDeployment: operatorOptions.enableDeployment,
367367
EnableDeploymentReplication: operatorOptions.enableDeploymentReplication,
368368
EnableStorage: operatorOptions.enableStorage,
369369
EnableBackup: operatorOptions.enableBackup,
370370
AllowChaos: chaosOptions.allowed,
371-
MetricsExporterImage: operatorOptions.metricsExporterImage,
372371
ArangoImage: operatorOptions.arangoImage,
373372
SingleMode: operatorOptions.singleMode,
374373
Scope: scope,

pkg/apis/deployment/v1/deployment_metrics_spec.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func (m MetricsMode) New() *MetricsMode {
4141
return &m
4242
}
4343

44+
// deprecated
4445
func (m MetricsMode) GetMetricsEndpoint() string {
4546
switch m {
4647
case MetricsModeInternal:
@@ -51,9 +52,12 @@ func (m MetricsMode) GetMetricsEndpoint() string {
5152
}
5253

5354
const (
55+
// deprecated
5456
// MetricsModeExporter exporter mode for old exporter type
5557
MetricsModeExporter MetricsMode = "exporter"
56-
MetricsModeSidecar MetricsMode = "sidecar"
58+
// deprecated
59+
MetricsModeSidecar MetricsMode = "sidecar"
60+
// deprecated
5761
MetricsModeInternal MetricsMode = "internal"
5862
)
5963

@@ -67,12 +71,14 @@ func (m *MetricsMode) Get() MetricsMode {
6771

6872
// MetricsSpec contains spec for arangodb exporter
6973
type MetricsSpec struct {
70-
Enabled *bool `json:"enabled,omitempty"`
74+
Enabled *bool `json:"enabled,omitempty"`
75+
// deprecated
7176
Image *string `json:"image,omitempty"`
7277
Authentication MetricsAuthenticationSpec `json:"authentication,omitempty"`
7378
Resources v1.ResourceRequirements `json:"resources,omitempty"`
74-
Mode *MetricsMode `json:"mode,omitempty"`
75-
TLS *bool `json:"tls,omitempty"`
79+
// deprecated
80+
Mode *MetricsMode `json:"mode,omitempty"`
81+
TLS *bool `json:"tls,omitempty"`
7682

7783
ServiceMonitor *MetricsServiceMonitorSpec `json:"serviceMonitor,omitempty"`
7884

@@ -100,11 +106,13 @@ func (s *MetricsSpec) IsEnabled() bool {
100106
return util.BoolOrDefault(s.Enabled, false)
101107
}
102108

109+
// deprecated
103110
// HasImage returns whether a image was specified or not
104111
func (s *MetricsSpec) HasImage() bool {
105112
return s.Image != nil
106113
}
107114

115+
// deprecated
108116
// GetImage returns the Image or empty string
109117
func (s *MetricsSpec) GetImage() string {
110118
return util.StringOrDefault(s.Image)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2021 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package v1
22+
23+
const (
24+
ServerGroupReservedContainerNameServer = "server"
25+
ServerGroupReservedContainerNameExporter = "exporter"
26+
)
27+
28+
func IsReservedServerGroupContainerName(name string) bool {
29+
switch name {
30+
case ServerGroupReservedContainerNameServer, ServerGroupReservedContainerNameExporter:
31+
return true
32+
default:
33+
return false
34+
}
35+
}

pkg/deployment/context_impl.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,8 @@ func (d *Deployment) GetScope() scope.Scope {
115115
return d.config.Scope
116116
}
117117

118-
// GetLifecycleImage returns the image name containing the lifecycle helper (== name of operator image)
119-
func (d *Deployment) GetLifecycleImage() string {
120-
return d.config.LifecycleImage
121-
}
122-
123-
// GetOperatorUUIDImage returns the image name containing the uuid helper (== name of operator image)
124-
func (d *Deployment) GetOperatorUUIDImage() string {
125-
return d.config.OperatorUUIDInitImage
118+
func (d *Deployment) GetOperatorImage() string {
119+
return d.config.OperatorImage
126120
}
127121

128122
// GetNamespace returns the kubernetes namespace that contains
@@ -591,10 +585,6 @@ func (d *Deployment) SelectImageForMember(spec api.DeploymentSpec, status api.De
591585
return d.resources.SelectImageForMember(spec, status, member)
592586
}
593587

594-
func (d *Deployment) GetMetricsExporterImage() string {
595-
return d.config.MetricsExporterImage
596-
}
597-
598588
func (d *Deployment) GetArangoImage() string {
599589
return d.config.ArangoImage
600590
}

pkg/deployment/deployment.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,11 @@ import (
6969

7070
// Config holds configuration settings for a Deployment
7171
type Config struct {
72-
ServiceAccount string
73-
AllowChaos bool
74-
LifecycleImage string
75-
OperatorUUIDInitImage string
76-
MetricsExporterImage string
77-
ArangoImage string
78-
Scope scope.Scope
72+
ServiceAccount string
73+
AllowChaos bool
74+
OperatorImage string
75+
ArangoImage string
76+
Scope scope.Scope
7977
}
8078

8179
// Dependencies holds dependent services for a Deployment

pkg/deployment/deployment_core_test.go

Lines changed: 6 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333

3434
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
3535
"github.com/arangodb/kube-arangodb/pkg/util"
36-
"github.com/arangodb/kube-arangodb/pkg/util/constants"
3736
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
3837
)
3938

@@ -276,7 +275,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
276275
},
277276
},
278277
config: Config{
279-
OperatorUUIDInitImage: testImageOperatorUUIDInit,
278+
OperatorImage: testImageOperator,
280279
},
281280
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
282281
deployment.status.last = api.DeploymentStatus{
@@ -505,7 +504,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
505504
},
506505
},
507506
config: Config{
508-
OperatorUUIDInitImage: testImageOperatorUUIDInit,
507+
OperatorImage: testImageOperator,
509508
},
510509
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
511510
deployment.status.last = api.DeploymentStatus{
@@ -1090,7 +1089,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
10901089
testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes
10911090
},
10921091
config: Config{
1093-
LifecycleImage: testImageLifecycle,
1092+
OperatorImage: testImageOperator,
10941093
},
10951094
ExpectedEvent: "member dbserver is created",
10961095
ExpectedPod: core.Pod{
@@ -1108,13 +1107,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
11081107
Name: k8sutil.ServerContainerName,
11091108
Image: testImage,
11101109
Command: createTestCommandForDBServer(firstDBServerStatus.ID, false, false, false),
1111-
Env: []core.EnvVar{
1112-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"),
1113-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"),
1114-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"),
1115-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"),
1116-
},
1117-
Ports: createTestPorts(),
1110+
Ports: createTestPorts(),
11181111
VolumeMounts: []core.VolumeMount{
11191112
k8sutil.ArangodVolumeMount(),
11201113
k8sutil.LifecycleVolumeMount(),
@@ -1160,16 +1153,14 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
11601153
testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes
11611154
},
11621155
config: Config{
1163-
LifecycleImage: testImageLifecycle,
1164-
OperatorUUIDInitImage: testImageOperatorUUIDInit,
1156+
OperatorImage: testImageOperator,
11651157
},
11661158
ExpectedEvent: "member dbserver is created",
11671159
ExpectedPod: core.Pod{
11681160
Spec: core.PodSpec{
11691161
Volumes: []core.Volume{
11701162
k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName),
11711163
k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken),
1172-
k8sutil.LifecycleVolume(),
11731164
},
11741165
InitContainers: []core.Container{
11751166
createTestLifecycleContainer(emptyResources),
@@ -1180,13 +1171,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
11801171
Name: k8sutil.ServerContainerName,
11811172
Image: testImage,
11821173
Command: createTestCommandForDBServer(firstDBServerStatus.ID, false, false, false),
1183-
Env: []core.EnvVar{
1184-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"),
1185-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"),
1186-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"),
1187-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"),
1188-
},
1189-
Ports: createTestPorts(),
1174+
Ports: createTestPorts(),
11901175
VolumeMounts: []core.VolumeMount{
11911176
k8sutil.ArangodVolumeMount(),
11921177
k8sutil.LifecycleVolumeMount(),
@@ -1208,102 +1193,6 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
12081193
},
12091194
},
12101195
},
1211-
{
1212-
Name: "DBserver Pod with metrics exporter, lifecycle, tls, authentication, license, rocksDB encryption, secured liveness",
1213-
ArangoDeployment: &api.ArangoDeployment{
1214-
Spec: api.DeploymentSpec{
1215-
Image: util.NewString(testImage),
1216-
Authentication: authenticationSpec,
1217-
TLS: tlsSpec,
1218-
Metrics: metricsSpec,
1219-
RocksDB: rocksDBSpec,
1220-
Environment: api.NewEnvironment(api.EnvironmentProduction),
1221-
License: api.LicenseSpec{
1222-
SecretName: util.NewString(testLicense),
1223-
},
1224-
},
1225-
},
1226-
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
1227-
deployment.status.last = api.DeploymentStatus{
1228-
Members: api.DeploymentStatusMembers{
1229-
DBServers: api.MemberStatusList{
1230-
firstDBServerStatus,
1231-
},
1232-
},
1233-
Images: createTestImages(false),
1234-
}
1235-
1236-
testCase.createTestPodData(deployment, api.ServerGroupDBServers, firstDBServerStatus)
1237-
testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes
1238-
1239-
key := make([]byte, 32)
1240-
k8sutil.CreateEncryptionKeySecret(deployment.SecretsModInterface(), testRocksDBEncryptionKey, key)
1241-
1242-
authorization, err := createTestToken(deployment, testCase, []string{"/_api/version"})
1243-
require.NoError(t, err)
1244-
1245-
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true,
1246-
authorization, k8sutil.ArangoPort)
1247-
},
1248-
config: Config{
1249-
LifecycleImage: testImageLifecycle,
1250-
},
1251-
ExpectedEvent: "member dbserver is created",
1252-
ExpectedPod: core.Pod{
1253-
Spec: core.PodSpec{
1254-
Volumes: []core.Volume{
1255-
k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName),
1256-
createTestTLSVolume(api.ServerGroupDBServersString, firstDBServerStatus.ID),
1257-
k8sutil.CreateVolumeWithSecret(k8sutil.RocksdbEncryptionVolumeName, testRocksDBEncryptionKey),
1258-
k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken),
1259-
k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName),
1260-
k8sutil.LifecycleVolume(),
1261-
},
1262-
InitContainers: []core.Container{
1263-
createTestLifecycleContainer(emptyResources),
1264-
},
1265-
Containers: []core.Container{
1266-
{
1267-
Name: k8sutil.ServerContainerName,
1268-
Image: testImage,
1269-
Command: createTestCommandForDBServer(firstDBServerStatus.ID, true, true, true),
1270-
Env: []core.EnvVar{
1271-
k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoLicenseKey,
1272-
testLicense, constants.SecretKeyToken),
1273-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"),
1274-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"),
1275-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"),
1276-
k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"),
1277-
},
1278-
Ports: createTestPorts(),
1279-
Lifecycle: createTestLifecycle(),
1280-
LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort),
1281-
ImagePullPolicy: core.PullIfNotPresent,
1282-
SecurityContext: securityContext.NewSecurityContext(),
1283-
VolumeMounts: []core.VolumeMount{
1284-
k8sutil.ArangodVolumeMount(),
1285-
k8sutil.LifecycleVolumeMount(),
1286-
k8sutil.TlsKeyfileVolumeMount(),
1287-
k8sutil.RocksdbEncryptionVolumeMount(),
1288-
k8sutil.ClusterJWTVolumeMount(),
1289-
},
1290-
Resources: emptyResources,
1291-
},
1292-
func() core.Container {
1293-
c := testArangodbInternalExporterContainer(true, emptyResources)
1294-
c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount())
1295-
return c
1296-
}(),
1297-
},
1298-
RestartPolicy: core.RestartPolicyNever,
1299-
TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout,
1300-
Hostname: testDeploymentName + "-" + api.ServerGroupDBServersString + "-" + firstDBServerStatus.ID,
1301-
Subdomain: testDeploymentName + "-int",
1302-
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupDBServersString,
1303-
true, ""),
1304-
},
1305-
},
1306-
},
13071196
{
13081197
Name: "Coordinator Pod with TLS and authentication and readiness and liveness",
13091198
ArangoDeployment: &api.ArangoDeployment{

0 commit comments

Comments
 (0)