1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00
kube-arangodb/lifecycle.go
2018-05-11 14:58:49 +02:00

150 lines
4 KiB
Go

//
// DISCLAIMER
//
// Copyright 2018 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 Ewout Prangsma
//
package main
import (
"io"
"os"
"path/filepath"
"time"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)
var (
cmdLifecycle = &cobra.Command{
Use: "lifecycle",
Run: cmdUsage,
Hidden: true,
}
cmdLifecyclePreStop = &cobra.Command{
Use: "preStop",
Run: cmdLifecyclePreStopRun,
Hidden: true,
}
cmdLifecycleCopy = &cobra.Command{
Use: "copy",
Run: cmdLifecycleCopyRun,
Hidden: true,
}
lifecycleCopyOptions struct {
TargetDir string
}
)
func init() {
cmdMain.AddCommand(cmdLifecycle)
cmdLifecycle.AddCommand(cmdLifecyclePreStop)
cmdLifecycle.AddCommand(cmdLifecycleCopy)
cmdLifecycleCopy.Flags().StringVar(&lifecycleCopyOptions.TargetDir, "target", "", "Target directory to copy the executable to")
}
// Wait until all finalizers of the current pod have been removed.
func cmdLifecyclePreStopRun(cmd *cobra.Command, args []string) {
cliLog.Info().Msgf("Starting arangodb-operator, lifecycle preStop, version %s build %s", projectVersion, projectBuild)
// Get environment
namespace := os.Getenv(constants.EnvOperatorPodNamespace)
if len(namespace) == 0 {
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodNamespace)
}
name := os.Getenv(constants.EnvOperatorPodName)
if len(name) == 0 {
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodName)
}
// Create kubernetes client
kubecli, err := k8sutil.NewKubeClient()
if err != nil {
cliLog.Fatal().Err(err).Msg("Failed to create Kubernetes client")
}
pods := kubecli.CoreV1().Pods(namespace)
recentErrors := 0
for {
p, err := pods.Get(name, metav1.GetOptions{})
if k8sutil.IsNotFound(err) {
cliLog.Warn().Msg("Pod not found")
return
} else if err != nil {
recentErrors++
cliLog.Error().Err(err).Msg("Failed to get pod")
if recentErrors > 20 {
cliLog.Fatal().Err(err).Msg("Too many recent errors")
return
}
} else {
// We got our pod
finalizerCount := len(p.GetFinalizers())
if finalizerCount == 0 {
// No more finalizers, we're done
cliLog.Info().Msg("All finalizers gone, we can stop now")
return
}
cliLog.Info().Msgf("Waiting for %d more finalizers to be removed", finalizerCount)
}
// Wait a bit
time.Sleep(time.Second)
}
}
// Copy the executable to a given place.
func cmdLifecycleCopyRun(cmd *cobra.Command, args []string) {
cliLog.Info().Msgf("Starting arangodb-operator, lifecycle copy, version %s build %s", projectVersion, projectBuild)
exePath, err := os.Executable()
if err != nil {
cliLog.Fatal().Err(err).Msg("Failed to get executable path")
}
// Open source
rd, err := os.Open(exePath)
if err != nil {
cliLog.Fatal().Err(err).Msg("Failed to open executable file")
}
defer rd.Close()
// Open target
targetPath := filepath.Join(lifecycleCopyOptions.TargetDir, filepath.Base(exePath))
wr, err := os.Create(targetPath)
if err != nil {
cliLog.Fatal().Err(err).Msg("Failed to create target file")
}
defer wr.Close()
if _, err := io.Copy(wr, rd); err != nil {
cliLog.Fatal().Err(err).Msg("Failed to copy")
}
// Set file mode
if err := os.Chmod(targetPath, 0755); err != nil {
cliLog.Fatal().Err(err).Msg("Failed to chmod")
}
}