pvc-reaper/main.go
2019-12-01 01:12:22 +01:00

97 lines
2.6 KiB
Go

// Copyright (C) 2019 Marius Schellenberger
package main
import (
"log"
"os"
"os/signal"
"syscall"
"time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
)
func init() {
log.SetFlags(log.Flags() | log.Lshortfile)
}
var emptyFinalizers = []byte(`{"metadata":{"finalizers":null}}`)
func main() {
cfg, err := rest.InClusterConfig()
if err != nil {
log.Fatalf("error configuring kube client: %s\n", err)
}
cl, err := kubernetes.NewForConfig(cfg)
if err != nil {
log.Fatalf("error creating new kube client: %s\n", err)
}
factory := informers.NewSharedInformerFactory(cl, time.Second*30)
pvcInformer := factory.Core().V1().PersistentVolumeClaims().Informer()
pvcInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
pvc, ok := obj.(*corev1.PersistentVolumeClaim)
if ok {
log.Printf("pvc added: %s/%s\n", pvc.Namespace, pvc.Name)
}
},
DeleteFunc: func(obj interface{}) {
pvc, ok := obj.(*corev1.PersistentVolumeClaim)
if ok {
log.Printf("pvc deleted: %s/%s\n", pvc.Namespace, pvc.Name)
}
},
UpdateFunc: func(_, obj interface{}) {
pvc, ok := obj.(*corev1.PersistentVolumeClaim)
owner := pvc.OwnerReferences
if !ok || pvc.DeletionTimestamp == nil || owner == nil {
return
}
if owner[0].APIVersion == "tekton.dev/v1alpha1" &&
owner[0].Kind == "PipelineRun" {
pvs := cl.CoreV1().PersistentVolumes()
pv, err := pvs.Get(pvc.Spec.VolumeName, metav1.GetOptions{})
if err != nil {
log.Printf("error getting pv %s: %s\n", pvc.Spec.VolumeName, err)
return
}
if pv.Finalizers != nil {
_, err = pvs.Patch(pv.Name, types.MergePatchType, emptyFinalizers)
if err != nil {
log.Printf("error patching pv %s: %s\n", pv.Name, err)
return
}
}
pvcs := cl.CoreV1().PersistentVolumeClaims(pvc.Namespace)
if pvc.Finalizers != nil {
_, err = pvcs.Patch(pvc.Name, types.MergePatchType, emptyFinalizers)
if err != nil {
log.Printf("error patching pvc %s/%s: %s\n", pvc.Namespace, pvc.Name, err)
return
}
}
log.Printf("pvc patched: %s/%s\n", pvc.Namespace, pvc.Name)
}
},
})
stop := make(chan struct{})
factory.Start(stop)
log.Println("started pvc watcher")
sigs := make(chan os.Signal)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
log.Println("started signal handler")
sig := <-sigs
close(stop)
log.Printf("signal: %s\n", sig.String())
}