From 76b07ee0e8f7c239319c305c986be8cb2d7313b1 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Mon, 11 Dec 2023 13:21:36 +0200 Subject: [PATCH] delete all expired node on exeeding expiration date --- server/app/app.go | 2 ++ server/deployer/deployer.go | 64 +++++++++++++++++++++++++++++++++ server/deployer/k8s_deployer.go | 2 ++ server/models/k8s.go | 15 ++++---- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/server/app/app.go b/server/app/app.go index 1a6a310e..554ac2b3 100644 --- a/server/app/app.go +++ b/server/app/app.go @@ -88,6 +88,8 @@ func (a *App) startBackgroundWorkers(ctx context.Context) { go a.deployer.PeriodicDeploy(ctx, substrateBlockDiffInSeconds) // remove expired vms and k8s + go a.deployer.CleanExpiredVMs(ctx) + go a.deployer.CleanExpiredK8S(ctx) // check pending deployments a.deployer.ConsumeVMRequest(ctx, true) diff --git a/server/deployer/deployer.go b/server/deployer/deployer.go index 01b20bd2..f32eeac3 100644 --- a/server/deployer/deployer.go +++ b/server/deployer/deployer.go @@ -166,6 +166,70 @@ func (d *Deployer) CancelDeployment(contractID uint64, netContractID uint64, dlT return nil } +func (d *Deployer) CleanExpiredVMs(ctx context.Context) { + ticker := time.NewTicker(24 * time.Hour) + for range ticker.C { + users, err := d.db.ListAllUsers() + if err != nil { + log.Error().Err(err).Msg("failed to get all users") + return + } + + for _, user := range users { + vms, err := d.db.GetAllVms(user.UserID) + if err != nil { + log.Error().Err(err).Msg("failed to get all user vms") + continue + } + + for _, vm := range vms { + if vm.ExpirationDate.Before(time.Now()) { + err = d.CancelDeployment(vm.ContractID, vm.NetworkContractID, "vm", vm.Name) + if err != nil { + log.Error().Err(err).Msg("failed to cancel contract of expired vm") + } + err := d.db.DeleteVMByID(vm.ID) + if err != nil { + log.Error().Err(err).Msg("failed to delete expired vm") + } + } + } + } + } +} + +func (d *Deployer) CleanExpiredK8S(ctx context.Context) { + ticker := time.NewTicker(24 * time.Hour) + for range ticker.C { + users, err := d.db.ListAllUsers() + if err != nil { + log.Error().Err(err).Msg("failed to get all users") + return + } + + for _, user := range users { + k8s, err := d.db.GetAllK8s(user.UserID) + if err != nil { + log.Error().Err(err).Msg("failed to get all user k8s clusters") + continue + } + + for _, k := range k8s { + if k.ExpirationDate.Before(time.Now()) { + err = d.CancelDeployment(uint64(k.ClusterContract), uint64(k.NetworkContract), "k8s", k.Master.Name) + if err != nil { + log.Error().Err(err).Msg("failed to cancel contract of expired k8s cluster") + } + err := d.db.DeleteVMByID(k.ID) + if err != nil { + log.Error().Err(err).Msg("failed to delete expired k8s cluster") + } + } + } + } + } +} + func buildNetwork(node uint32, name string) workloads.ZNet { return workloads.ZNet{ Name: name, diff --git a/server/deployer/k8s_deployer.go b/server/deployer/k8s_deployer.go index bb059ac3..ac448d42 100644 --- a/server/deployer/k8s_deployer.go +++ b/server/deployer/k8s_deployer.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "net/http" + "time" "github.com/codescalers/cloud4students/middlewares" "github.com/codescalers/cloud4students/models" @@ -154,6 +155,7 @@ func (d *Deployer) loadK8s(k8sDeployInput models.K8sDeployInput, userID string, ClusterContract: int(k8sContractID), Master: master, Workers: workers, + ExpirationDate: time.Now().Add(time.Duration(k8sDeployInput.Duration) * 30 * 24 * time.Hour).Truncate(24 * time.Hour), } return k8sCluster, nil diff --git a/server/models/k8s.go b/server/models/k8s.go index c6347623..d1b4a321 100644 --- a/server/models/k8s.go +++ b/server/models/k8s.go @@ -1,14 +1,17 @@ // Package models for database models package models +import "time" + // K8sCluster holds all cluster data type K8sCluster struct { - ID int `json:"id" gorm:"primaryKey"` - UserID string `json:"userID"` - NetworkContract int `json:"network_contract_id"` - ClusterContract int `json:"contract_id"` - Master Master `json:"master" gorm:"foreignKey:ClusterID"` - Workers []Worker `json:"workers" gorm:"foreignKey:ClusterID"` + ID int `json:"id" gorm:"primaryKey"` + UserID string `json:"userID"` + NetworkContract int `json:"network_contract_id"` + ClusterContract int `json:"contract_id"` + Master Master `json:"master" gorm:"foreignKey:ClusterID"` + Workers []Worker `json:"workers" gorm:"foreignKey:ClusterID"` + ExpirationDate time.Time `json:"expiration_date"` } // Master struct for kubernetes master data