1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-15 17:51:03 +00:00
kube-arangodb/pkg/storage/daemon_set.go

170 lines
4.7 KiB
Go
Raw Normal View History

2018-03-05 09:00:23 +00:00
//
// DISCLAIMER
//
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
2018-03-05 09:00:23 +00:00
//
// 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
//
package storage
import (
2021-03-23 15:47:28 +00:00
"context"
2018-03-05 09:00:23 +00:00
"fmt"
2018-03-06 09:54:12 +00:00
"strconv"
2018-03-05 09:00:23 +00:00
2020-09-08 07:40:44 +00:00
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
2018-03-05 09:00:23 +00:00
2018-03-13 15:25:33 +00:00
api "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha"
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner"
"github.com/arangodb/kube-arangodb/pkg/util"
2018-03-13 15:25:33 +00:00
"github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
2018-03-13 15:25:33 +00:00
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors"
2018-03-05 09:00:23 +00:00
)
2018-03-06 09:54:12 +00:00
const (
roleProvisioner = "provisioner"
)
2018-03-05 09:00:23 +00:00
// ensureDaemonSet ensures that a daemonset is created for the given local storage.
// If it already exists, it is updated.
func (ls *LocalStorage) ensureDaemonSet(apiObject *api.ArangoLocalStorage) error {
ns := ls.config.Namespace
2020-09-08 07:40:44 +00:00
c := core.Container{
2018-03-06 09:54:12 +00:00
Name: "provisioner",
Image: ls.image,
ImagePullPolicy: ls.imagePullPolicy,
2018-03-05 09:00:23 +00:00
Args: []string{
"storage",
"provisioner",
2018-03-06 09:54:12 +00:00
"--port=" + strconv.Itoa(provisioner.DefaultPort),
},
2020-09-08 07:40:44 +00:00
Ports: []core.ContainerPort{
core.ContainerPort{
2018-03-06 09:54:12 +00:00
ContainerPort: int32(provisioner.DefaultPort),
},
},
2020-09-08 07:40:44 +00:00
Env: []core.EnvVar{
core.EnvVar{
2018-03-06 09:54:12 +00:00
Name: constants.EnvOperatorNodeName,
2020-09-08 07:40:44 +00:00
ValueFrom: &core.EnvVarSource{
FieldRef: &core.ObjectFieldSelector{
2018-03-06 09:54:12 +00:00
FieldPath: "spec.nodeName",
},
},
},
2018-03-05 09:00:23 +00:00
},
}
2020-09-08 07:40:44 +00:00
if apiObject.Spec.GetPrivileged() {
c.SecurityContext = &core.SecurityContext{
Privileged: util.NewType[bool](true),
2020-09-08 07:40:44 +00:00
}
}
2018-03-06 09:54:12 +00:00
dsLabels := k8sutil.LabelsForLocalStorage(apiObject.GetName(), roleProvisioner)
2020-09-08 07:40:44 +00:00
dsSpec := apps.DaemonSetSpec{
Selector: &meta.LabelSelector{
MatchLabels: dsLabels,
2018-03-05 09:00:23 +00:00
},
2020-09-08 07:40:44 +00:00
Template: core.PodTemplateSpec{
ObjectMeta: meta.ObjectMeta{
Labels: dsLabels,
2018-03-06 09:54:12 +00:00
},
2020-09-08 07:40:44 +00:00
Spec: core.PodSpec{
Containers: []core.Container{
c,
2018-03-05 09:00:23 +00:00
},
NodeSelector: apiObject.Spec.NodeSelector,
ImagePullSecrets: ls.imagePullSecrets,
Priority: apiObject.Spec.PodCustomization.GetPriority(),
Tolerations: apiObject.Spec.Tolerations,
2018-03-05 09:00:23 +00:00
},
},
}
2020-09-08 07:40:44 +00:00
2018-03-05 09:00:23 +00:00
for i, lp := range apiObject.Spec.LocalPath {
volName := fmt.Sprintf("local-path-%d", i)
c := &dsSpec.Template.Spec.Containers[0]
2018-03-05 09:00:23 +00:00
c.VolumeMounts = append(c.VolumeMounts,
2020-09-08 07:40:44 +00:00
core.VolumeMount{
2018-03-06 09:54:12 +00:00
Name: volName,
MountPath: lp,
2018-03-05 09:00:23 +00:00
})
2020-09-08 07:40:44 +00:00
hostPathType := core.HostPathDirectoryOrCreate
dsSpec.Template.Spec.Volumes = append(dsSpec.Template.Spec.Volumes, core.Volume{
2018-03-05 09:00:23 +00:00
Name: volName,
2020-09-08 07:40:44 +00:00
VolumeSource: core.VolumeSource{
HostPath: &core.HostPathVolumeSource{
2018-03-05 09:00:23 +00:00
Path: lp,
Type: &hostPathType,
},
},
})
}
2020-09-08 07:40:44 +00:00
ds := &apps.DaemonSet{
ObjectMeta: meta.ObjectMeta{
Name: apiObject.GetName(),
Labels: dsLabels,
},
Spec: dsSpec,
}
2018-03-06 13:53:22 +00:00
// Attach DS to ArangoLocalStorage
2018-03-06 09:54:12 +00:00
ds.SetOwnerReferences(append(ds.GetOwnerReferences(), apiObject.AsOwner()))
// Create DS
if _, err := ls.deps.Client.Kubernetes().AppsV1().DaemonSets(ns).Create(context.Background(), ds, meta.CreateOptions{}); err != nil {
if kerrors.IsAlreadyExists(err) {
// Already exists, update it
} else {
2021-01-08 14:35:38 +00:00
return errors.WithStack(err)
}
} else {
// We're done
2022-06-14 07:26:07 +00:00
ls.log.Debug("Created DaemonSet")
return nil
}
// Update existing DS
attempt := 0
for {
attempt++
// Load current DS
current, err := ls.deps.Client.Kubernetes().AppsV1().DaemonSets(ns).Get(context.Background(), ds.GetName(), meta.GetOptions{})
if err != nil {
2021-01-08 14:35:38 +00:00
return errors.WithStack(err)
}
// Update it
current.Spec = dsSpec
if _, err := ls.deps.Client.Kubernetes().AppsV1().DaemonSets(ns).Update(context.Background(), current, meta.UpdateOptions{}); kerrors.IsConflict(err) && attempt < 10 {
ls.log.Err(err).Debug("failed to patch DaemonSet spec")
// Failed to update, try again
continue
} else if err != nil {
2022-06-14 07:26:07 +00:00
ls.log.Err(err).Debug("failed to patch DaemonSet spec")
2021-01-08 14:35:38 +00:00
return errors.WithStack(errors.Newf("failed to patch DaemonSet spec: %v", err))
} else {
// Update was a success
2022-06-14 07:26:07 +00:00
ls.log.Debug("Updated DaemonSet")
return nil
}
2018-03-05 09:00:23 +00:00
}
}