Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(scheduler): Background check for pod status in permit plugin #124

Merged
merged 9 commits into from
Oct 10, 2022
Merged
2 changes: 1 addition & 1 deletion scheduler/cmd/scheduler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func main() {

rand.Seed(time.Now().UnixNano())
command := app.NewSchedulerCommand(
app.WithPlugin(klcpermit.Name, klcpermit.New),
app.WithPlugin(klcpermit.PluginName, klcpermit.New),
)

code := cli.Run(command)
Expand Down
3 changes: 3 additions & 0 deletions scheduler/manifests/install/base/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ rules:
- apiGroups: ["lifecycle.keptn.sh"]
resources: ["keptnworkloadinstances"]
verbs: ["get", "list", "watch"]
- apiGroups: [ "" ]
resources: [ "configmaps" ]
verbs: [ "list", "watch" ]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
39 changes: 26 additions & 13 deletions scheduler/pkg/klcpermit/permit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,59 @@ import (
"k8s.io/kubernetes/pkg/scheduler/framework"
)

// Name is the name of the plugin used in the plugin registry and configurations.
// PluginName is the name of the plugin used in the plugin registry and configurations.
const (
Name = "KLCPermit"
PluginName = "KLCPermit"
)

// Permit is a plugin that implements a wait for pre-deployment checks
// Permit is a plugin that waits for pre-deployment checks
RealAnna marked this conversation as resolved.
Show resolved Hide resolved
type Permit struct {
handler framework.Handle
workloadManager *WorkloadManager
}

var _ framework.PermitPlugin = &Permit{}

// Name returns name of the plugin.
// PluginName returns name of the plugin.
func (pl *Permit) Name() string {
return Name
return PluginName
}

func (pl *Permit) Permit(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (*framework.Status, time.Duration) {

klog.InfoS("[Keptn Permit Plugin] waiting for pre-deployment checks on", p.GetObjectMeta().GetName())
klog.Infof("[Keptn Permit Plugin] waiting for pre-deployment checks on %s", p.GetObjectMeta().GetName())

// check the permit immediately, to fail early in case the pod cannot be queued
switch pl.workloadManager.Permit(ctx, p) {

case Wait:
klog.Infof("[Keptn Permit Plugin] waiting for pre-deployment checks on", p.GetObjectMeta().GetName())
return framework.NewStatus(framework.Wait), 30 * time.Second
case Failure:
klog.Infof("[Keptn Permit Plugin] failed pre-deployment checks on", p.GetObjectMeta().GetName())
klog.Infof("[Keptn Permit Plugin] failed pre-deployment checks on %s", p.GetObjectMeta().GetName())
return framework.NewStatus(framework.Error), 0 * time.Second
case Success:
klog.Infof("[Keptn Permit Plugin] passed pre-deployment checks on", p.GetObjectMeta().GetName())
klog.Infof("[Keptn Permit Plugin] passed pre-deployment checks on %s", p.GetObjectMeta().GetName())
return framework.NewStatus(framework.Success), 0 * time.Second
default:
klog.Infof("[Keptn Permit Plugin] unknown status of pre-deployment checks for", p.GetObjectMeta().GetName())
return framework.NewStatus(framework.Wait), 30 * time.Second
klog.Infof("[Keptn Permit Plugin] waiting for pre-deployment checks on %s", p.GetObjectMeta().GetName())
go pl.monitorPod(ctx, p)
return framework.NewStatus(framework.Wait), 5 * time.Minute
}

}

func (pl *Permit) monitorPod(ctx context.Context, p *v1.Pod) {
waitingPodHandler := pl.handler.GetWaitingPod(p.UID)
thisthat marked this conversation as resolved.
Show resolved Hide resolved

switch pl.workloadManager.Permit(ctx, p) {
case Failure:
waitingPodHandler.Reject(PluginName, "Pre Deployment Check failed")
case Success:
waitingPodHandler.Allow(PluginName)
thisthat marked this conversation as resolved.
Show resolved Hide resolved
default:
time.Sleep(10 * time.Second)
pl.monitorPod(ctx, p)
thisthat marked this conversation as resolved.
Show resolved Hide resolved
}
}

// New initializes a new plugin and returns it.
func New(_ runtime.Object, h framework.Handle) (framework.Plugin, error) {
client, err := newClient()
Expand Down