feet: add finalizer
This commit is contained in:
parent
14aba80181
commit
ef7b16af68
@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flink-kube-operator/internal/crd"
|
"flink-kube-operator/internal/crd"
|
||||||
"flink-kube-operator/internal/manager"
|
"flink-kube-operator/internal/managed_job"
|
||||||
"flink-kube-operator/internal/rest"
|
"flink-kube-operator/internal/rest"
|
||||||
"flink-kube-operator/pkg"
|
"flink-kube-operator/pkg"
|
||||||
"log"
|
"log"
|
||||||
@ -31,7 +31,7 @@ func main() {
|
|||||||
pkg.Logger.Info("[main]", zap.Any("cluster-config", clusterConfig))
|
pkg.Logger.Info("[main]", zap.Any("cluster-config", clusterConfig))
|
||||||
|
|
||||||
// init flink job manager
|
// init flink job manager
|
||||||
manager.NewManager(c, crdInstance)
|
managed_job.NewManager(c, crdInstance)
|
||||||
|
|
||||||
// for _, jobDef := range config.Jobs {
|
// for _, jobDef := range config.Jobs {
|
||||||
// managed_job.NewManagedJob(c, db, jobDef)
|
// managed_job.NewManagedJob(c, db, jobDef)
|
||||||
|
|||||||
@ -1,14 +1,60 @@
|
|||||||
package crd
|
package crd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"flink-kube-operator/internal/crd/v1alpha1"
|
||||||
|
"flink-kube-operator/pkg"
|
||||||
|
|
||||||
"github.com/reactivex/rxgo/v2"
|
"github.com/reactivex/rxgo/v2"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var FinalizerChannel chan (types.UID) = make(chan (types.UID))
|
||||||
|
|
||||||
func (crd Crd) manageFinalizer(jobEventObservable rxgo.Observable) {
|
func (crd Crd) manageFinalizer(jobEventObservable rxgo.Observable) {
|
||||||
|
|
||||||
|
finalizerName := "flink-operator.logicamp.tech/finalizer"
|
||||||
for j := range jobEventObservable.Observe() {
|
for j := range jobEventObservable.Observe() {
|
||||||
jobEvent := j.V.(*FlinkJobCrdEvent)
|
jobEvent := j.V.(*FlinkJobCrdEvent)
|
||||||
//pkg.Logger.Debug("[crd] [manage-finalizer] adding finalizer for", zap.String("name", jobEvent.Job.GetName()))
|
|
||||||
controllerutil.AddFinalizer(jobEvent.Job, "")
|
if jobEvent.Job.GetDeletionTimestamp() != nil {
|
||||||
|
// Resource is being deleted
|
||||||
|
if controllerutil.ContainsFinalizer(jobEvent.Job, finalizerName) {
|
||||||
|
// Perform cleanup
|
||||||
|
pkg.Logger.Debug("[finalizer] stopping managed job", zap.String("name", jobEvent.Job.GetName()))
|
||||||
|
if err := crd.cleanupResources(jobEvent.Job); err != nil {
|
||||||
|
pkg.Logger.Error("[crd] [manage-finalizer] cleanup failed", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove finalizer
|
||||||
|
controllerutil.RemoveFinalizer(jobEvent.Job, finalizerName)
|
||||||
|
if err := crd.runtimeClient.Update(context.Background(), jobEvent.Job); err != nil {
|
||||||
|
pkg.Logger.Error("[crd] [manage-finalizer] failed to remove finalizer", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pkg.Logger.Debug("[crd] [manage-finalizer] job removed", zap.String("name", jobEvent.Job.GetName()))
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add finalizer if not present
|
||||||
|
if !controllerutil.ContainsFinalizer(jobEvent.Job, finalizerName) {
|
||||||
|
controllerutil.AddFinalizer(jobEvent.Job, finalizerName)
|
||||||
|
pkg.Logger.Debug("[finalizer] adding job")
|
||||||
|
// Update the resource to add the finalizer
|
||||||
|
if err := crd.runtimeClient.Update(context.Background(), jobEvent.Job); err != nil {
|
||||||
|
pkg.Logger.Error("[finalizer] failed to add", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (crd Crd) cleanupResources(job *v1alpha1.FlinkJob) error {
|
||||||
|
FinalizerChannel <- job.GetUID()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -3,36 +3,48 @@ package crd
|
|||||||
import (
|
import (
|
||||||
"flink-kube-operator/internal/crd/v1alpha1"
|
"flink-kube-operator/internal/crd/v1alpha1"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Crd struct {
|
type Crd struct {
|
||||||
client dynamic.NamespaceableResourceInterface
|
client dynamic.NamespaceableResourceInterface
|
||||||
|
runtimeClient client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *Crd {
|
func New() *Crd {
|
||||||
// Get Kubernetes config
|
// Get Kubernetes config_
|
||||||
config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
|
config_, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
config, err = rest.InClusterConfig()
|
config_, err = rest.InClusterConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create dynamic client
|
// Create dynamic client
|
||||||
dynamicClient, err := dynamic.NewForConfig(config)
|
dynamicClient, err := dynamic.NewForConfig(config_)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shema := runtime.NewScheme()
|
||||||
|
v1alpha1.AddKnownTypes(shema)
|
||||||
// Get FlinkJob resource interface
|
// Get FlinkJob resource interface
|
||||||
flinkJobClient := dynamicClient.Resource(v1alpha1.FlinkJobGVR)
|
flinkJobClient := dynamicClient.Resource(v1alpha1.FlinkJobGVR)
|
||||||
|
runtimeClient, err := client.New(config.GetConfigOrDie(), client.Options{
|
||||||
|
Scheme: shema,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
crd := Crd{
|
crd := Crd{
|
||||||
client: flinkJobClient,
|
client: flinkJobClient,
|
||||||
|
runtimeClient: runtimeClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch for FlinkJob creation
|
// Watch for FlinkJob creation
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
func (crd *Crd) Patch(jobUid types.UID, patchData map[string]interface{}) error {
|
func (crd *Crd) Patch(jobUid types.UID, patchData map[string]interface{}) error {
|
||||||
job := GetJob(jobUid)
|
job := GetJob(jobUid)
|
||||||
pkg.Logger.Debug("[patch-job]", zap.Any("jobUid", jobUid))
|
// pkg.Logger.Debug("[patch-job]", zap.Any("jobUid", jobUid))
|
||||||
|
|
||||||
patchBytes, err := json.Marshal(patchData)
|
patchBytes, err := json.Marshal(patchData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -14,6 +14,10 @@ func (crd *Crd) repsert(job *v1alpha1.FlinkJob) {
|
|||||||
jobs.Store(job.GetUID(), job)
|
jobs.Store(job.GetUID(), job)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (crd *Crd) remove(uid types.UID) {
|
||||||
|
jobs.Delete(uid)
|
||||||
|
}
|
||||||
|
|
||||||
func GetJob(uid types.UID) v1alpha1.FlinkJob {
|
func GetJob(uid types.UID) v1alpha1.FlinkJob {
|
||||||
job, _ := jobs.Load(uid)
|
job, _ := jobs.Load(uid)
|
||||||
return *job.DeepCopy()
|
return *job.DeepCopy()
|
||||||
|
|||||||
@ -20,11 +20,11 @@ var FlinkJobGVR = schema.GroupVersionResource{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
SchemeBuilder = runtime.NewSchemeBuilder(AddKnownTypes)
|
||||||
AddToScheme = SchemeBuilder.AddToScheme
|
AddToScheme = SchemeBuilder.AddToScheme
|
||||||
)
|
)
|
||||||
|
|
||||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
func AddKnownTypes(scheme *runtime.Scheme) error {
|
||||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||||
&FlinkJob{},
|
&FlinkJob{},
|
||||||
&FlinkJobList{},
|
&FlinkJobList{},
|
||||||
|
|||||||
@ -56,6 +56,8 @@ func (crd Crd) watchFlinkJobs() rxgo.Observable {
|
|||||||
//pkg.Logger.Info("[crd] [watch] new flink job created")
|
//pkg.Logger.Info("[crd] [watch] new flink job created")
|
||||||
crd.repsert(job)
|
crd.repsert(job)
|
||||||
case watch.Deleted:
|
case watch.Deleted:
|
||||||
|
crd.remove(job.UID)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (job *ManagedJob) Cycle() {
|
func (job *ManagedJob) Cycle() {
|
||||||
pkg.Logger.Debug("[managed-job] [new] check cycle", zap.String("jobName", job.def.GetName()))
|
// pkg.Logger.Debug("[managed-job] [new] check cycle", zap.String("jobName", job.def.GetName()))
|
||||||
|
|
||||||
// Init job
|
// Init job
|
||||||
if job.def.Status.LifeCycleStatus == "" && job.def.Status.JobStatus == "" {
|
if job.def.Status.LifeCycleStatus == "" && job.def.Status.JobStatus == "" {
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
package manager
|
package managed_job
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flink-kube-operator/internal/crd"
|
"flink-kube-operator/internal/crd"
|
||||||
"flink-kube-operator/internal/crd/v1alpha1"
|
"flink-kube-operator/internal/crd/v1alpha1"
|
||||||
"flink-kube-operator/internal/managed_job"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"flink-kube-operator/pkg"
|
"flink-kube-operator/pkg"
|
||||||
@ -16,7 +15,7 @@ import (
|
|||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
client *api.Client
|
client *api.Client
|
||||||
managedJobs map[types.UID]managed_job.ManagedJob
|
managedJobs map[types.UID]ManagedJob
|
||||||
processingJobsIds []types.UID
|
processingJobsIds []types.UID
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ func NewManager(client *api.Client, crdInstance *crd.Crd) Manager {
|
|||||||
quit := make(chan struct{})
|
quit := make(chan struct{})
|
||||||
mgr = Manager{
|
mgr = Manager{
|
||||||
client: client,
|
client: client,
|
||||||
managedJobs: map[types.UID]managed_job.ManagedJob{},
|
managedJobs: map[types.UID]ManagedJob{},
|
||||||
processingJobsIds: []types.UID{},
|
processingJobsIds: []types.UID{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +46,15 @@ func NewManager(client *api.Client, crdInstance *crd.Crd) Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for event := range crd.FinalizerChannel {
|
||||||
|
manager := mgr.GetJob(event)
|
||||||
|
manager.Stop()
|
||||||
|
delete(mgr.managedJobs, event)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return mgr
|
return mgr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +72,7 @@ func (mgr *Manager) cycle(client *api.Client, crdInstance *crd.Crd) {
|
|||||||
|
|
||||||
// Loop over job definitions as Kubernetes CRD
|
// Loop over job definitions as Kubernetes CRD
|
||||||
for _, uid := range crd.GetAllJobKeys() {
|
for _, uid := range crd.GetAllJobKeys() {
|
||||||
pkg.Logger.Debug("mgr.processingJobsIds", zap.Any("processingJobIds", mgr.processingJobsIds))
|
// pkg.Logger.Debug("mgr.processingJobsIds", zap.Any("processingJobIds", mgr.processingJobsIds))
|
||||||
if lo.Contains(mgr.processingJobsIds, uid) {
|
if lo.Contains(mgr.processingJobsIds, uid) {
|
||||||
pkg.Logger.Warn("[manager] already in process", zap.Any("uid", uid))
|
pkg.Logger.Warn("[manager] already in process", zap.Any("uid", uid))
|
||||||
continue
|
continue
|
||||||
@ -80,7 +88,7 @@ func (mgr *Manager) cycle(client *api.Client, crdInstance *crd.Crd) {
|
|||||||
managedJob.Update(def)
|
managedJob.Update(def)
|
||||||
} else {
|
} else {
|
||||||
// Add job to manager managed job
|
// Add job to manager managed job
|
||||||
managedJob = *managed_job.NewManagedJob(client, def, crdInstance)
|
managedJob = *NewManagedJob(client, def, crdInstance)
|
||||||
}
|
}
|
||||||
if jobManagerJobStatusError != nil {
|
if jobManagerJobStatusError != nil {
|
||||||
|
|
||||||
@ -94,7 +102,7 @@ func (mgr *Manager) cycle(client *api.Client, crdInstance *crd.Crd) {
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
if ok {
|
if ok {
|
||||||
pkg.Logger.Debug("[manager] read status from flink", zap.String("name", jobManagerJobOverview.Name), zap.String("state", jobManagerJobOverview.State))
|
// pkg.Logger.Debug("[manager] read status from flink", zap.String("name", jobManagerJobOverview.Name), zap.String("state", jobManagerJobOverview.State))
|
||||||
patchStatusObj := map[string]interface{}{
|
patchStatusObj := map[string]interface{}{
|
||||||
"jobStatus": v1alpha1.JobStatus(jobManagerJobOverview.State),
|
"jobStatus": v1alpha1.JobStatus(jobManagerJobOverview.State),
|
||||||
}
|
}
|
||||||
@ -117,10 +125,10 @@ func (mgr *Manager) cycle(client *api.Client, crdInstance *crd.Crd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgr *Manager) GetJobs() map[types.UID]managed_job.ManagedJob {
|
func (mgr *Manager) GetJobs() map[types.UID]ManagedJob {
|
||||||
return mgr.managedJobs
|
return mgr.managedJobs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgr *Manager) GetJob(id types.UID) managed_job.ManagedJob {
|
func (mgr *Manager) GetJob(id types.UID) ManagedJob {
|
||||||
return mgr.managedJobs[id]
|
return mgr.managedJobs[id]
|
||||||
}
|
}
|
||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"flink-kube-operator/internal/crd"
|
"flink-kube-operator/internal/crd"
|
||||||
"flink-kube-operator/internal/crd/v1alpha1"
|
"flink-kube-operator/internal/crd/v1alpha1"
|
||||||
"flink-kube-operator/internal/manager"
|
"flink-kube-operator/internal/managed_job"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
)
|
)
|
||||||
@ -39,7 +39,7 @@ type StopJobResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StopJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
func StopJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
||||||
mgr := manager.GetManager()
|
mgr := managed_job.GetManager()
|
||||||
job := mgr.GetJob(types.UID(req.JobUId))
|
job := mgr.GetJob(types.UID(req.JobUId))
|
||||||
err := job.Stop()
|
err := job.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -51,7 +51,7 @@ func StopJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StartJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
func StartJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
||||||
mgr := manager.GetManager()
|
mgr := managed_job.GetManager()
|
||||||
job := mgr.GetJob(types.UID(req.JobUId))
|
job := mgr.GetJob(types.UID(req.JobUId))
|
||||||
err := job.Run(true)
|
err := job.Run(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,7 +63,7 @@ func StartJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RemoveJobJar(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
func RemoveJobJar(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
||||||
mgr := manager.GetManager()
|
mgr := managed_job.GetManager()
|
||||||
job := mgr.GetJob(types.UID(req.JobUId))
|
job := mgr.GetJob(types.UID(req.JobUId))
|
||||||
job.RemoveJar()
|
job.RemoveJar()
|
||||||
return &StopJobResp{Body: StopJobRespBody{
|
return &StopJobResp{Body: StopJobRespBody{
|
||||||
@ -72,7 +72,7 @@ func RemoveJobJar(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PauseJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
func PauseJob(ctx context.Context, req *StopJobReq) (*StopJobResp, error) {
|
||||||
mgr := manager.GetManager()
|
mgr := managed_job.GetManager()
|
||||||
job := mgr.GetJob(types.UID(req.JobUId))
|
job := mgr.GetJob(types.UID(req.JobUId))
|
||||||
job.Pause()
|
job.Pause()
|
||||||
return &StopJobResp{Body: StopJobRespBody{
|
return &StopJobResp{Body: StopJobRespBody{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user