1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00
kube-arangodb/pkg/deployment/resources/pod_finalizers.go

137 lines
5.5 KiB
Go
Raw Normal View History

2018-05-11 08:07:00 +00:00
//
// DISCLAIMER
//
2020-03-04 10:25:14 +00:00
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
2018-05-11 08:07:00 +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
//
// Author Ewout Prangsma
//
package resources
import (
"context"
"time"
2018-05-11 08:07:00 +00:00
"github.com/rs/zerolog"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2018-05-11 08:07:00 +00:00
2019-11-04 07:49:24 +00:00
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
2018-08-30 14:57:08 +00:00
"github.com/arangodb/kube-arangodb/pkg/util"
2018-05-11 08:07:00 +00:00
"github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)
2018-08-25 10:08:44 +00:00
const (
2018-08-30 14:57:08 +00:00
podFinalizerRemovedInterval = util.Interval(time.Second / 2) // Interval used (until new inspection) when Pod finalizers have been removed
recheckPodFinalizerInterval = util.Interval(time.Second * 10) // Interval used when Pod finalizers need to be rechecked soon
2018-08-25 10:08:44 +00:00
)
2018-05-11 08:07:00 +00:00
// runPodFinalizers goes through the list of pod finalizers to see if they can be removed.
2018-08-25 10:08:44 +00:00
// Returns: Interval_till_next_inspection, error
2018-08-30 14:57:08 +00:00
func (r *Resources) runPodFinalizers(ctx context.Context, p *v1.Pod, memberStatus api.MemberStatus, updateMember func(api.MemberStatus) error) (util.Interval, error) {
2018-05-11 08:07:00 +00:00
log := r.log.With().Str("pod-name", p.GetName()).Logger()
var removalList []string
for _, f := range p.ObjectMeta.GetFinalizers() {
switch f {
2018-05-14 08:50:06 +00:00
case constants.FinalizerPodAgencyServing:
log.Debug().Msg("Inspecting agency-serving finalizer")
2018-08-30 08:15:42 +00:00
if err := r.inspectFinalizerPodAgencyServing(ctx, log, p, memberStatus, updateMember); err == nil {
2018-05-14 08:50:06 +00:00
removalList = append(removalList, f)
} else {
log.Debug().Err(err).Str("finalizer", f).Msg("Cannot remove finalizer yet")
}
case constants.FinalizerPodDrainDBServer:
2018-05-11 08:07:00 +00:00
log.Debug().Msg("Inspecting drain dbserver finalizer")
2018-05-14 09:59:18 +00:00
if err := r.inspectFinalizerPodDrainDBServer(ctx, log, p, memberStatus, updateMember); err == nil {
2018-05-11 08:07:00 +00:00
removalList = append(removalList, f)
} else {
2018-08-25 10:08:44 +00:00
log.Debug().Err(err).Str("finalizer", f).Msg("Cannot remove Pod finalizer yet")
2018-05-11 08:07:00 +00:00
}
}
}
// Remove finalizers (if needed)
if len(removalList) > 0 {
kubecli := r.context.GetKubeCli()
2018-06-12 11:30:43 +00:00
ignoreNotFound := false
if err := k8sutil.RemovePodFinalizers(log, kubecli, p, removalList, ignoreNotFound); err != nil {
2018-05-11 08:07:00 +00:00
log.Debug().Err(err).Msg("Failed to update pod (to remove finalizers)")
2018-08-25 10:08:44 +00:00
return 0, maskAny(err)
2018-05-11 08:07:00 +00:00
}
log.Debug().Strs("finalizers", removalList).Msg("Removed finalizer(s) from Pod")
2018-08-30 14:57:08 +00:00
// Let's do the next inspection quickly, since things may have changed now.
return podFinalizerRemovedInterval, nil
2018-05-11 08:07:00 +00:00
}
2018-08-30 14:57:08 +00:00
// Check again at given interval
return recheckPodFinalizerInterval, nil
2018-05-11 08:07:00 +00:00
}
2018-05-14 08:50:06 +00:00
// inspectFinalizerPodAgencyServing checks the finalizer condition for agency-serving.
// It returns nil if the finalizer can be removed.
2018-08-30 08:15:42 +00:00
func (r *Resources) inspectFinalizerPodAgencyServing(ctx context.Context, log zerolog.Logger, p *v1.Pod, memberStatus api.MemberStatus, updateMember func(api.MemberStatus) error) error {
if err := r.prepareAgencyPodTermination(ctx, log, p, memberStatus, func(update api.MemberStatus) error {
if err := updateMember(update); err != nil {
return maskAny(err)
}
memberStatus = update
return nil
}); err != nil {
// Pod cannot be terminated yet
2018-05-14 08:50:06 +00:00
return maskAny(err)
}
2018-08-30 08:15:42 +00:00
// Remaining agents are healthy, if we need to perform complete recovery
// of the agent, also remove the PVC
if memberStatus.Conditions.IsTrue(api.ConditionTypeAgentRecoveryNeeded) {
pvcs := r.context.GetKubeCli().CoreV1().PersistentVolumeClaims(r.context.GetNamespace())
if err := pvcs.Delete(memberStatus.PersistentVolumeClaimName, &metav1.DeleteOptions{}); err != nil && !k8sutil.IsNotFound(err) {
log.Warn().Err(err).Msg("Failed to delete PVC for member")
return maskAny(err)
}
2018-08-25 10:08:44 +00:00
log.Debug().Str("pvc-name", memberStatus.PersistentVolumeClaimName).Msg("Removed PVC of member so agency can be completely replaced")
}
2018-05-14 08:50:06 +00:00
return nil
}
// inspectFinalizerPodDrainDBServer checks the finalizer condition for drain-dbserver.
2018-05-11 08:07:00 +00:00
// It returns nil if the finalizer can be removed.
2018-05-14 09:59:18 +00:00
func (r *Resources) inspectFinalizerPodDrainDBServer(ctx context.Context, log zerolog.Logger, p *v1.Pod, memberStatus api.MemberStatus, updateMember func(api.MemberStatus) error) error {
2018-08-30 08:15:42 +00:00
if err := r.prepareDBServerPodTermination(ctx, log, p, memberStatus, func(update api.MemberStatus) error {
if err := updateMember(update); err != nil {
return maskAny(err)
}
memberStatus = update
return nil
}); err != nil {
2018-08-27 08:24:19 +00:00
// Pod cannot be terminated yet
return maskAny(err)
}
2018-08-30 08:15:42 +00:00
// If this DBServer is cleaned out, we need to remove the PVC.
if memberStatus.Conditions.IsTrue(api.ConditionTypeCleanedOut) || memberStatus.Phase == api.MemberPhaseDrain {
2018-08-30 08:15:42 +00:00
pvcs := r.context.GetKubeCli().CoreV1().PersistentVolumeClaims(r.context.GetNamespace())
if err := pvcs.Delete(memberStatus.PersistentVolumeClaimName, &metav1.DeleteOptions{}); err != nil && !k8sutil.IsNotFound(err) {
log.Warn().Err(err).Msg("Failed to delete PVC for member")
return maskAny(err)
}
2018-08-27 08:24:19 +00:00
log.Debug().Str("pvc-name", memberStatus.PersistentVolumeClaimName).Msg("Removed PVC of member")
2018-05-11 08:07:00 +00:00
}
2018-08-27 08:24:19 +00:00
return nil
2018-05-11 08:07:00 +00:00
}