Skip to content

Commit 4cbf4e1

Browse files
authored
[Feature] Allow to specify initContainers (#650)
1 parent 06916bf commit 4cbf4e1

File tree

14 files changed

+295
-77
lines changed

14 files changed

+295
-77
lines changed

CHANGELOG.md

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

33
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
44
- Allow to mount EmptyDir
5+
- Allow to specify initContainers in pods
56

67
## [1.1.0](https://github.com/arangodb/kube-arangodb/tree/master) (2020-10-14)
78
- Change NumberOfCores and MemoryOverride flags to be set to true by default

pkg/apis/deployment/v1/deployment.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,37 @@ package v1
2424

2525
import (
2626
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
27-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
)
2929

3030
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
3131

3232
// ArangoDeploymentList is a list of ArangoDB clusters.
3333
type ArangoDeploymentList struct {
34-
metav1.TypeMeta `json:",inline"`
34+
meta.TypeMeta `json:",inline"`
3535
// Standard list metadata
3636
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
37-
metav1.ListMeta `json:"metadata,omitempty"`
38-
Items []ArangoDeployment `json:"items"`
37+
meta.ListMeta `json:"metadata,omitempty"`
38+
Items []ArangoDeployment `json:"items"`
3939
}
4040

4141
// +genclient
4242
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
4343

4444
// ArangoDeployment contains the entire Kubernetes info for an ArangoDB database deployment.
4545
type ArangoDeployment struct {
46-
metav1.TypeMeta `json:",inline"`
47-
metav1.ObjectMeta `json:"metadata,omitempty"`
48-
Spec DeploymentSpec `json:"spec,omitempty"`
49-
Status DeploymentStatus `json:"status,omitempty"`
46+
meta.TypeMeta `json:",inline"`
47+
meta.ObjectMeta `json:"metadata,omitempty"`
48+
Spec DeploymentSpec `json:"spec,omitempty"`
49+
Status DeploymentStatus `json:"status,omitempty"`
5050
}
5151

5252
type ServerGroupFunc func(ServerGroup, ServerGroupSpec, *MemberStatusList) error
5353

5454
// AsOwner creates an OwnerReference for the given deployment
55-
func (d *ArangoDeployment) AsOwner() metav1.OwnerReference {
55+
func (d *ArangoDeployment) AsOwner() meta.OwnerReference {
5656
trueVar := true
57-
return metav1.OwnerReference{
57+
return meta.OwnerReference{
5858
APIVersion: SchemeGroupVersion.String(),
5959
Kind: deployment.ArangoDeploymentResourceKind,
6060
Name: d.Name,

pkg/apis/deployment/v1/deployment_spec.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import (
3030

3131
"github.com/arangodb/kube-arangodb/pkg/util"
3232
"github.com/pkg/errors"
33-
v1 "k8s.io/api/core/v1"
33+
core "k8s.io/api/core/v1"
3434
)
3535

3636
var (
@@ -39,9 +39,9 @@ var (
3939

4040
// validatePullPolicy the image pull policy.
4141
// Return errors when validation fails, nil on success.
42-
func validatePullPolicy(v v1.PullPolicy) error {
42+
func validatePullPolicy(v core.PullPolicy) error {
4343
switch v {
44-
case "", v1.PullAlways, v1.PullNever, v1.PullIfNotPresent:
44+
case "", core.PullAlways, core.PullNever, core.PullIfNotPresent:
4545
return nil
4646
default:
4747
return maskAny(errors.Wrapf(ValidationError, "Unknown pull policy: '%s'", string(v)))
@@ -54,7 +54,7 @@ type DeploymentSpec struct {
5454
Environment *Environment `json:"environment,omitempty"`
5555
StorageEngine *StorageEngine `json:"storageEngine,omitempty"`
5656
Image *string `json:"image,omitempty"`
57-
ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"`
57+
ImagePullPolicy *core.PullPolicy `json:"imagePullPolicy,omitempty"`
5858
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`
5959
ImageDiscoveryMode *DeploymentImageDiscoveryModeSpec `json:"imageDiscoveryMode,omitempty"`
6060
DowntimeAllowed *bool `json:"downtimeAllowed,omitempty"`
@@ -161,7 +161,7 @@ func (s DeploymentSpec) GetSyncImage() string {
161161
}
162162

163163
// GetImagePullPolicy returns the value of imagePullPolicy.
164-
func (s DeploymentSpec) GetImagePullPolicy() v1.PullPolicy {
164+
func (s DeploymentSpec) GetImagePullPolicy() core.PullPolicy {
165165
return util.PullPolicyOrDefault(s.ImagePullPolicy)
166166
}
167167

@@ -253,7 +253,7 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) {
253253
s.Image = util.NewString(DefaultImage)
254254
}
255255
if s.GetImagePullPolicy() == "" {
256-
s.ImagePullPolicy = util.NewPullPolicy(v1.PullIfNotPresent)
256+
s.ImagePullPolicy = util.NewPullPolicy(core.PullIfNotPresent)
257257
}
258258
s.ExternalAccess.SetDefaults()
259259
s.RocksDB.SetDefaults()

pkg/apis/deployment/v1/server_group.go

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,30 @@ import "time"
2727
type ServerGroup int
2828

2929
const (
30-
ServerGroupUnknown ServerGroup = 0
31-
ServerGroupSingle ServerGroup = 1
32-
ServerGroupAgents ServerGroup = 2
33-
ServerGroupDBServers ServerGroup = 3
34-
ServerGroupCoordinators ServerGroup = 4
35-
ServerGroupSyncMasters ServerGroup = 5
36-
ServerGroupSyncWorkers ServerGroup = 6
37-
38-
ServerGroupSingleString = "single"
39-
ServerGroupAgentsString = "agent"
40-
ServerGroupDBServersString = "dbserver"
41-
ServerGroupCoordinatorsString = "coordinator"
42-
ServerGroupSyncMastersString = "syncmaster"
43-
ServerGroupSyncWorkersString = "syncworker"
44-
45-
ServerGroupSingleAbbreviatedString = "sngl"
46-
ServerGroupAgentsAbbreviatedString = "agnt"
47-
ServerGroupDBServersAbbreviatedString = "prmr"
48-
ServerGroupCoordinatorsAbbreviatedString = "crdn"
49-
ServerGroupSyncMastersAbbreviatedString = "syma"
50-
ServerGroupSyncWorkersAbbreviatedString = "sywo"
30+
ServerGroupUnknown ServerGroup = 0
31+
ServerGroupSingle ServerGroup = 1
32+
ServerGroupAgents ServerGroup = 2
33+
ServerGroupDBServers ServerGroup = 3
34+
ServerGroupCoordinators ServerGroup = 4
35+
ServerGroupSyncMasters ServerGroup = 5
36+
ServerGroupSyncWorkers ServerGroup = 6
37+
ServerGroupImageDiscovery ServerGroup = -1
38+
39+
ServerGroupSingleString = "single"
40+
ServerGroupAgentsString = "agent"
41+
ServerGroupDBServersString = "dbserver"
42+
ServerGroupCoordinatorsString = "coordinator"
43+
ServerGroupSyncMastersString = "syncmaster"
44+
ServerGroupSyncWorkersString = "syncworker"
45+
ServerGroupImageDiscoveryString = "imagediscovery"
46+
47+
ServerGroupSingleAbbreviatedString = "sngl"
48+
ServerGroupAgentsAbbreviatedString = "agnt"
49+
ServerGroupDBServersAbbreviatedString = "prmr"
50+
ServerGroupCoordinatorsAbbreviatedString = "crdn"
51+
ServerGroupSyncMastersAbbreviatedString = "syma"
52+
ServerGroupSyncWorkersAbbreviatedString = "sywo"
53+
ServerGroupImageDiscoveryAbbreviatedString = "id"
5154
)
5255

5356
var (
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2020 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+
// Author Adam Janikowski
21+
//
22+
23+
package v1
24+
25+
import (
26+
"github.com/arangodb/kube-arangodb/pkg/apis/shared"
27+
sharedv1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
28+
"github.com/pkg/errors"
29+
core "k8s.io/api/core/v1"
30+
)
31+
32+
const (
33+
ServerGroupReservedInitContainerNameLifecycle = "init-lifecycle"
34+
ServerGroupReservedInitContainerNameUUID = "uuid"
35+
)
36+
37+
func IsReservedServerGroupInitContainerName(name string) bool {
38+
switch name {
39+
case ServerGroupReservedInitContainerNameLifecycle, ServerGroupReservedInitContainerNameUUID:
40+
return true
41+
default:
42+
return false
43+
}
44+
}
45+
46+
func ValidateServerGroupInitContainerName(name string) error {
47+
if IsReservedServerGroupInitContainerName(name) {
48+
return errors.Errorf("InitContainer name %s is restricted", name)
49+
}
50+
51+
return sharedv1.AsKubernetesResourceName(&name).Validate()
52+
}
53+
54+
type ServerGroupInitContainerMode string
55+
56+
func (s *ServerGroupInitContainerMode) Get() ServerGroupInitContainerMode {
57+
if s == nil {
58+
return ServerGroupInitContainerUpdateMode // default
59+
}
60+
61+
return *s
62+
}
63+
64+
func (s ServerGroupInitContainerMode) New() *ServerGroupInitContainerMode {
65+
return &s
66+
}
67+
68+
func (s *ServerGroupInitContainerMode) Validate() error {
69+
switch v := s.Get(); v {
70+
case ServerGroupInitContainerIgnoreMode, ServerGroupInitContainerUpdateMode:
71+
return nil
72+
default:
73+
return errors.Errorf("Unknown serverGroupInitContainerMode %s", v)
74+
}
75+
}
76+
77+
const (
78+
// ServerGroupInitContainerIgnoreMode ignores init container changes in pod recreation flow
79+
ServerGroupInitContainerIgnoreMode ServerGroupInitContainerMode = "ignore"
80+
// ServerGroupInitContainerUpdateMode enforce update of pod if init container has been changed
81+
ServerGroupInitContainerUpdateMode ServerGroupInitContainerMode = "update"
82+
)
83+
84+
type ServerGroupInitContainers struct {
85+
// Containers contains list of containers
86+
Containers []core.Container `json:"containers,omitempty"`
87+
88+
// Mode keep container replace mode
89+
Mode *ServerGroupInitContainerMode `json:"mode,omitempty"`
90+
}
91+
92+
func (s *ServerGroupInitContainers) GetMode() *ServerGroupInitContainerMode {
93+
if s == nil {
94+
return nil
95+
}
96+
97+
return s.Mode
98+
}
99+
100+
func (s *ServerGroupInitContainers) GetContainers() []core.Container {
101+
if s == nil {
102+
return nil
103+
}
104+
105+
return s.Containers
106+
}
107+
108+
func (s *ServerGroupInitContainers) Validate() error {
109+
if s == nil {
110+
return nil
111+
}
112+
113+
return shared.WithErrors(
114+
shared.PrefixResourceError("mode", s.Mode.Validate()),
115+
shared.PrefixResourceError("containers", s.validateInitContainers()),
116+
)
117+
}
118+
119+
func (s *ServerGroupInitContainers) validateInitContainers() error {
120+
for _, c := range s.Containers {
121+
if err := ValidateServerGroupInitContainerName(c.Name); err != nil {
122+
return err
123+
}
124+
}
125+
126+
return nil
127+
}

pkg/apis/deployment/v1/server_group_spec.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ type ServerGroupSpec struct {
100100
VolumeMounts ServerGroupSpecVolumeMounts `json:"volumeMounts,omitempty"`
101101
// ExtendedRotationCheck extend checks for rotation
102102
ExtendedRotationCheck *bool `json:"extendedRotationCheck,omitempty"`
103+
// InitContainers Init containers specification
104+
InitContainers *ServerGroupInitContainers `json:"initContainers,omitempty"`
103105
}
104106

105107
// ServerGroupSpecSecurityContext contains specification for pod security context
@@ -471,6 +473,7 @@ func (s *ServerGroupSpec) validate() error {
471473
return shared.WithErrors(
472474
shared.PrefixResourceError("volumes", s.Volumes.Validate()),
473475
shared.PrefixResourceError("volumeMounts", s.VolumeMounts.Validate()),
476+
shared.PrefixResourceError("initContainers", s.InitContainers.Validate()),
474477
s.validateVolumes(),
475478
)
476479
}
@@ -482,12 +485,30 @@ func (s *ServerGroupSpec) validateVolumes() error {
482485
volumes[volume.Name] = true
483486
}
484487

488+
volumes["arangod-data"] = true
489+
485490
for _, mount := range s.VolumeMounts {
486491
if _, ok := volumes[mount.Name]; !ok {
487492
return errors.Errorf("Volume %s is not defined, but required by mount", mount.Name)
488493
}
489494
}
490495

496+
for _, container := range s.InitContainers.GetContainers() {
497+
for _, mount := range container.VolumeMounts {
498+
if _, ok := volumes[mount.Name]; !ok {
499+
return errors.Errorf("Volume %s is not defined, but required by mount in init container %s", mount.Name, container.Name)
500+
}
501+
}
502+
}
503+
504+
for _, container := range s.Sidecars {
505+
for _, mount := range s.VolumeMounts {
506+
if _, ok := volumes[mount.Name]; !ok {
507+
return errors.Errorf("Volume %s is not defined, but required by mount in sidecar %s", mount.Name, container.Name)
508+
}
509+
}
510+
}
511+
491512
return nil
492513
}
493514

pkg/apis/deployment/v1/zz_generated.deepcopy.go

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

pkg/deployment/images.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima
218218
return true, maskAny(err)
219219
}
220220

221-
if _, _, err := resources.CreateArangoPod(ib.KubeCli, ib.APIObject, pod); err != nil {
221+
if _, err := resources.CreateArangoPod(ib.KubeCli, ib.APIObject, ib.Spec, api.ServerGroupImageDiscovery, pod); err != nil {
222222
log.Debug().Err(err).Msg("Failed to create image ID pod")
223223
return true, maskAny(err)
224224
}

0 commit comments

Comments
 (0)