Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

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

## [1.1.0](https://github.com/arangodb/kube-arangodb/tree/master) (2020-10-14)
- Change NumberOfCores and MemoryOverride flags to be set to true by default
Expand Down
20 changes: 10 additions & 10 deletions pkg/apis/deployment/v1/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,37 @@ package v1

import (
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)

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

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

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

// ArangoDeployment contains the entire Kubernetes info for an ArangoDB database deployment.
type ArangoDeployment struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DeploymentSpec `json:"spec,omitempty"`
Status DeploymentStatus `json:"status,omitempty"`
meta.TypeMeta `json:",inline"`
meta.ObjectMeta `json:"metadata,omitempty"`
Spec DeploymentSpec `json:"spec,omitempty"`
Status DeploymentStatus `json:"status,omitempty"`
}

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

// AsOwner creates an OwnerReference for the given deployment
func (d *ArangoDeployment) AsOwner() metav1.OwnerReference {
func (d *ArangoDeployment) AsOwner() meta.OwnerReference {
trueVar := true
return metav1.OwnerReference{
return meta.OwnerReference{
APIVersion: SchemeGroupVersion.String(),
Kind: deployment.ArangoDeploymentResourceKind,
Name: d.Name,
Expand Down
12 changes: 6 additions & 6 deletions pkg/apis/deployment/v1/deployment_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (

"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
core "k8s.io/api/core/v1"
)

var (
Expand All @@ -39,9 +39,9 @@ var (

// validatePullPolicy the image pull policy.
// Return errors when validation fails, nil on success.
func validatePullPolicy(v v1.PullPolicy) error {
func validatePullPolicy(v core.PullPolicy) error {
switch v {
case "", v1.PullAlways, v1.PullNever, v1.PullIfNotPresent:
case "", core.PullAlways, core.PullNever, core.PullIfNotPresent:
return nil
default:
return maskAny(errors.Wrapf(ValidationError, "Unknown pull policy: '%s'", string(v)))
Expand All @@ -54,7 +54,7 @@ type DeploymentSpec struct {
Environment *Environment `json:"environment,omitempty"`
StorageEngine *StorageEngine `json:"storageEngine,omitempty"`
Image *string `json:"image,omitempty"`
ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"`
ImagePullPolicy *core.PullPolicy `json:"imagePullPolicy,omitempty"`
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`
ImageDiscoveryMode *DeploymentImageDiscoveryModeSpec `json:"imageDiscoveryMode,omitempty"`
DowntimeAllowed *bool `json:"downtimeAllowed,omitempty"`
Expand Down Expand Up @@ -161,7 +161,7 @@ func (s DeploymentSpec) GetSyncImage() string {
}

// GetImagePullPolicy returns the value of imagePullPolicy.
func (s DeploymentSpec) GetImagePullPolicy() v1.PullPolicy {
func (s DeploymentSpec) GetImagePullPolicy() core.PullPolicy {
return util.PullPolicyOrDefault(s.ImagePullPolicy)
}

Expand Down Expand Up @@ -253,7 +253,7 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) {
s.Image = util.NewString(DefaultImage)
}
if s.GetImagePullPolicy() == "" {
s.ImagePullPolicy = util.NewPullPolicy(v1.PullIfNotPresent)
s.ImagePullPolicy = util.NewPullPolicy(core.PullIfNotPresent)
}
s.ExternalAccess.SetDefaults()
s.RocksDB.SetDefaults()
Expand Down
45 changes: 24 additions & 21 deletions pkg/apis/deployment/v1/server_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,30 @@ import "time"
type ServerGroup int

const (
ServerGroupUnknown ServerGroup = 0
ServerGroupSingle ServerGroup = 1
ServerGroupAgents ServerGroup = 2
ServerGroupDBServers ServerGroup = 3
ServerGroupCoordinators ServerGroup = 4
ServerGroupSyncMasters ServerGroup = 5
ServerGroupSyncWorkers ServerGroup = 6

ServerGroupSingleString = "single"
ServerGroupAgentsString = "agent"
ServerGroupDBServersString = "dbserver"
ServerGroupCoordinatorsString = "coordinator"
ServerGroupSyncMastersString = "syncmaster"
ServerGroupSyncWorkersString = "syncworker"

ServerGroupSingleAbbreviatedString = "sngl"
ServerGroupAgentsAbbreviatedString = "agnt"
ServerGroupDBServersAbbreviatedString = "prmr"
ServerGroupCoordinatorsAbbreviatedString = "crdn"
ServerGroupSyncMastersAbbreviatedString = "syma"
ServerGroupSyncWorkersAbbreviatedString = "sywo"
ServerGroupUnknown ServerGroup = 0
ServerGroupSingle ServerGroup = 1
ServerGroupAgents ServerGroup = 2
ServerGroupDBServers ServerGroup = 3
ServerGroupCoordinators ServerGroup = 4
ServerGroupSyncMasters ServerGroup = 5
ServerGroupSyncWorkers ServerGroup = 6
ServerGroupImageDiscovery ServerGroup = -1

ServerGroupSingleString = "single"
ServerGroupAgentsString = "agent"
ServerGroupDBServersString = "dbserver"
ServerGroupCoordinatorsString = "coordinator"
ServerGroupSyncMastersString = "syncmaster"
ServerGroupSyncWorkersString = "syncworker"
ServerGroupImageDiscoveryString = "imagediscovery"

ServerGroupSingleAbbreviatedString = "sngl"
ServerGroupAgentsAbbreviatedString = "agnt"
ServerGroupDBServersAbbreviatedString = "prmr"
ServerGroupCoordinatorsAbbreviatedString = "crdn"
ServerGroupSyncMastersAbbreviatedString = "syma"
ServerGroupSyncWorkersAbbreviatedString = "sywo"
ServerGroupImageDiscoveryAbbreviatedString = "id"
)

var (
Expand Down
127 changes: 127 additions & 0 deletions pkg/apis/deployment/v1/server_group_init_containers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//
// DISCLAIMER
//
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Adam Janikowski
//

package v1

import (
"github.com/arangodb/kube-arangodb/pkg/apis/shared"
sharedv1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
"github.com/pkg/errors"
core "k8s.io/api/core/v1"
)

const (
ServerGroupReservedInitContainerNameLifecycle = "init-lifecycle"
ServerGroupReservedInitContainerNameUUID = "uuid"
)

func IsReservedServerGroupInitContainerName(name string) bool {
switch name {
case ServerGroupReservedInitContainerNameLifecycle, ServerGroupReservedInitContainerNameUUID:
return true
default:
return false
}
}

func ValidateServerGroupInitContainerName(name string) error {
if IsReservedServerGroupInitContainerName(name) {
return errors.Errorf("InitContainer name %s is restricted", name)
}

return sharedv1.AsKubernetesResourceName(&name).Validate()
}

type ServerGroupInitContainerMode string

func (s *ServerGroupInitContainerMode) Get() ServerGroupInitContainerMode {
if s == nil {
return ServerGroupInitContainerUpdateMode // default
}

return *s
}

func (s ServerGroupInitContainerMode) New() *ServerGroupInitContainerMode {
return &s
}

func (s *ServerGroupInitContainerMode) Validate() error {
switch v := s.Get(); v {
case ServerGroupInitContainerIgnoreMode, ServerGroupInitContainerUpdateMode:
return nil
default:
return errors.Errorf("Unknown serverGroupInitContainerMode %s", v)
}
}

const (
// ServerGroupInitContainerIgnoreMode ignores init container changes in pod recreation flow
ServerGroupInitContainerIgnoreMode ServerGroupInitContainerMode = "ignore"
// ServerGroupInitContainerUpdateMode enforce update of pod if init container has been changed
ServerGroupInitContainerUpdateMode ServerGroupInitContainerMode = "update"
)

type ServerGroupInitContainers struct {
// Containers contains list of containers
Containers []core.Container `json:"containers,omitempty"`

// Mode keep container replace mode
Mode *ServerGroupInitContainerMode `json:"mode,omitempty"`
}

func (s *ServerGroupInitContainers) GetMode() *ServerGroupInitContainerMode {
if s == nil {
return nil
}

return s.Mode
}

func (s *ServerGroupInitContainers) GetContainers() []core.Container {
if s == nil {
return nil
}

return s.Containers
}

func (s *ServerGroupInitContainers) Validate() error {
if s == nil {
return nil
}

return shared.WithErrors(
shared.PrefixResourceError("mode", s.Mode.Validate()),
shared.PrefixResourceError("containers", s.validateInitContainers()),
)
}

func (s *ServerGroupInitContainers) validateInitContainers() error {
for _, c := range s.Containers {
if err := ValidateServerGroupInitContainerName(c.Name); err != nil {
return err
}
}

return nil
}
21 changes: 21 additions & 0 deletions pkg/apis/deployment/v1/server_group_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type ServerGroupSpec struct {
VolumeMounts ServerGroupSpecVolumeMounts `json:"volumeMounts,omitempty"`
// ExtendedRotationCheck extend checks for rotation
ExtendedRotationCheck *bool `json:"extendedRotationCheck,omitempty"`
// InitContainers Init containers specification
InitContainers *ServerGroupInitContainers `json:"initContainers,omitempty"`
}

// ServerGroupSpecSecurityContext contains specification for pod security context
Expand Down Expand Up @@ -471,6 +473,7 @@ func (s *ServerGroupSpec) validate() error {
return shared.WithErrors(
shared.PrefixResourceError("volumes", s.Volumes.Validate()),
shared.PrefixResourceError("volumeMounts", s.VolumeMounts.Validate()),
shared.PrefixResourceError("initContainers", s.InitContainers.Validate()),
s.validateVolumes(),
)
}
Expand All @@ -482,12 +485,30 @@ func (s *ServerGroupSpec) validateVolumes() error {
volumes[volume.Name] = true
}

volumes["arangod-data"] = true

for _, mount := range s.VolumeMounts {
if _, ok := volumes[mount.Name]; !ok {
return errors.Errorf("Volume %s is not defined, but required by mount", mount.Name)
}
}

for _, container := range s.InitContainers.GetContainers() {
for _, mount := range container.VolumeMounts {
if _, ok := volumes[mount.Name]; !ok {
return errors.Errorf("Volume %s is not defined, but required by mount in init container %s", mount.Name, container.Name)
}
}
}

for _, container := range s.Sidecars {
for _, mount := range s.VolumeMounts {
if _, ok := volumes[mount.Name]; !ok {
return errors.Errorf("Volume %s is not defined, but required by mount in sidecar %s", mount.Name, container.Name)
}
}
}

return nil
}

Expand Down
33 changes: 33 additions & 0 deletions pkg/apis/deployment/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/deployment/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima
return true, maskAny(err)
}

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