Skip to content

Commit

Permalink
Edit event (#80)
Browse files Browse the repository at this point in the history
* reschedule and edit events

* delete ac

* Update scheduled events.

Moved rescheduleScheduledEvent functionality from scheduledeventcontroller to scheduledeventserver. Now not only the start date of an event can be edited, but also the end date, courses and scenarios, etc.

* Delete scheduled events

* namespace in labels, deleteCollection instead of list and delete

* Delete VMs

* Finish sessions.
Now, when a scheduled event is deleted, the associated sessions to the event's courses/scenarios are terminated. Terminating a session also deletes the corresponding VMs.

* invalidate sessions for finished events

* Delete DBRs when cleaning up session

* Change Label for DBRs to Session instead of VMClaim

Co-authored-by: Jan-Gerrit Goebel <[email protected]>
  • Loading branch information
PhilipAB and jggoebel authored Aug 9, 2021
1 parent b0c2211 commit c0d557e
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 70 deletions.
16 changes: 9 additions & 7 deletions pkg/controllers/dynamicbindcontroller/dynamicbindcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
hfClientset "github.com/hobbyfarm/gargantua/pkg/client/clientset/versioned"
hfInformers "github.com/hobbyfarm/gargantua/pkg/client/informers/externalversions"
hfListers "github.com/hobbyfarm/gargantua/pkg/client/listers/hobbyfarm.io/v1"
"github.com/hobbyfarm/gargantua/pkg/controllers/scheduledevent"
"github.com/hobbyfarm/gargantua/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
Expand Down Expand Up @@ -271,13 +272,14 @@ func (d *DynamicBindController) reconcileDynamicBindRequest(dynamicBindRequest *
},
},
Labels: map[string]string{
"dynamic": "true",
"dynamicbindrequest": dynamicBindRequest.Name,
"dynamicbindconfiguration": chosenDynamicBindConfiguration.Spec.Id,
"template": vmX.Template,
"environment": chosenDynamicBindConfiguration.Spec.Environment,
"bound": "true",
"ready": "false",
"dynamic": "true",
"dynamicbindrequest": dynamicBindRequest.Name,
"dynamicbindconfiguration": chosenDynamicBindConfiguration.Spec.Id,
"template": vmX.Template,
"environment": chosenDynamicBindConfiguration.Spec.Environment,
"bound": "true",
"ready": "false",
scheduledevent.ScheduledEventLabel: chosenDynamicBindConfiguration.ObjectMeta.Labels[scheduledevent.ScheduledEventLabel],
},
},
Spec: hfv1.VirtualMachineSpec{
Expand Down
77 changes: 62 additions & 15 deletions pkg/controllers/scheduledevent/scheduledeventcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
hfv1 "github.com/hobbyfarm/gargantua/pkg/apis/hobbyfarm.io/v1"
hfClientset "github.com/hobbyfarm/gargantua/pkg/client/clientset/versioned"
hfInformers "github.com/hobbyfarm/gargantua/pkg/client/informers/externalversions"
"github.com/hobbyfarm/gargantua/pkg/sessionserver"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
Expand All @@ -33,6 +34,7 @@ var baseNameDynamicPrefix string
const (
ScheduledEventBaseDelay = 5 * time.Millisecond
ScheduledEventMaxDelay = 300 * time.Second
ScheduledEventLabel = "scheduledevent.hobbyfarm.io"
)

func init() {
Expand Down Expand Up @@ -146,20 +148,17 @@ func (s *ScheduledEventController) processNextScheduledEvent() bool {
func (s ScheduledEventController) completeScheduledEvent(se *hfv1.ScheduledEvent) error {
glog.V(6).Infof("ScheduledEvent %s is done, deleting corresponding VMSets and marking as finished", se.Name)
// scheduled event is finished, we need to set the scheduled event to finished and delete the vm's
// get a list of the vmsets corresponding to this scheduled event
vmsList, err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets().List(metav1.ListOptions{
LabelSelector: fmt.Sprintf("scheduledevent=%s", se.Name),
})

err := s.deleteVMSetsFromScheduledEvent(se)

if err != nil {
return err
}

// for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset
for _, vms := range vmsList.Items {
err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets().Delete(vms.Name, &metav1.DeleteOptions{})
if err != nil {
glog.Errorf("error deleting virtualmachineset %v", err)
}
err = s.finishSessionsFromScheduledEvent(se)

if err != nil {
return err
}

// update the scheduled event and set the various flags accordingly (provisioned, ready, finished)
Expand Down Expand Up @@ -187,6 +186,51 @@ func (s ScheduledEventController) completeScheduledEvent(se *hfv1.ScheduledEvent
return nil // break (return) here because we're done with this SE.
}

func (s ScheduledEventController) deleteVMSetsFromScheduledEvent(se *hfv1.ScheduledEvent) error {
// for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset
err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets().DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s=%s", ScheduledEventLabel, se.Name),
})
if err != nil {
return err
}

return nil
}

func (s ScheduledEventController) finishSessionsFromScheduledEvent(se *hfv1.ScheduledEvent) error {
// get a list of sessions for the user
sessionList, err := s.hfClientSet.HobbyfarmV1().Sessions().List(metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s=%s", sessionserver.AccessCodeLabel, se.Spec.AccessCode),
})

now := time.Now().Format(time.UnixDate)

for _, session := range sessionList.Items {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
result, getErr := s.hfClientSet.HobbyfarmV1().Sessions().Get(session.Spec.Id, metav1.GetOptions{})
if getErr != nil {
return fmt.Errorf("error retrieving latest version of session %s: %v", session.Spec.Id, getErr)
}

result.Status.ExpirationTime = now
result.Status.Active = false
result.Status.Finished = false

_, updateErr := s.hfClientSet.HobbyfarmV1().Sessions().Update(result)
glog.V(4).Infof("updated result for session")

return updateErr
})

if retryErr != nil {
glog.Errorf("error updating session %v", err)
return fmt.Errorf("error attempting to update")
}
}
return nil
}

func (s ScheduledEventController) provisionScheduledEvent(templates *hfv1.VirtualMachineTemplateList, se *hfv1.ScheduledEvent) error {
glog.V(6).Infof("ScheduledEvent %s is ready to be provisioned", se.Name)
// start creating resources related to this
Expand Down Expand Up @@ -249,8 +293,8 @@ func (s ScheduledEventController) provisionScheduledEvent(templates *hfv1.Virtua
},
},
Labels: map[string]string{
"environment": env.Name,
"scheduledevent": se.Name,
"environment": env.Name,
ScheduledEventLabel: se.Name,
},
},
Spec: hfv1.VirtualMachineSetSpec{
Expand Down Expand Up @@ -314,8 +358,8 @@ func (s ScheduledEventController) provisionScheduledEvent(templates *hfv1.Virtua
},
},
Labels: map[string]string{
"environment": env.Name,
"scheduledevent": se.Name,
"environment": env.Name,
ScheduledEventLabel: se.Name,
},
},
Spec: hfv1.DynamicBindConfigurationSpec{
Expand Down Expand Up @@ -353,6 +397,9 @@ func (s ScheduledEventController) provisionScheduledEvent(templates *hfv1.Virtua
UID: se.UID,
},
},
Labels: map[string]string{
ScheduledEventLabel: se.Name,
},
},
Spec: hfv1.AccessCodeSpec{
Code: se.Spec.AccessCode,
Expand Down Expand Up @@ -406,7 +453,7 @@ func (s ScheduledEventController) verifyScheduledEvent(se *hfv1.ScheduledEvent)
// check the state of the vmset and mark the sevent as ready if everything is OK
glog.V(6).Infof("ScheduledEvent %s is in provisioned status, checking status of VMSet Provisioning", se.Name)
vmsList, err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets().List(metav1.ListOptions{
LabelSelector: fmt.Sprintf("scheduledevent=%s", se.Name),
LabelSelector: fmt.Sprintf("%s=%s", ScheduledEventLabel, se.Name),
})
if err != nil {
return err
Expand Down
18 changes: 14 additions & 4 deletions pkg/controllers/session/sessioncontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package session

import (
"fmt"
"time"

"github.com/golang/glog"
hfClientset "github.com/hobbyfarm/gargantua/pkg/client/clientset/versioned"
hfInformers "github.com/hobbyfarm/gargantua/pkg/client/informers/externalversions"
Expand All @@ -12,7 +14,6 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/retry"
"k8s.io/client-go/util/workqueue"
"time"
)

const (
Expand Down Expand Up @@ -151,8 +152,17 @@ func (s *SessionController) reconcileSession(ssName string) error {

// clean up old (3 hours later) sessions, and only if they are finished
if expires.Add(SessionExpireTime).Before(now) && ss.Status.Finished {
// first we need to delete the vmclaims
err := s.hfClientSet.HobbyfarmV1().VirtualMachineClaims().DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{
// first we need to delete the DynamicBindRequests
err := s.hfClientSet.HobbyfarmV1().DynamicBindRequests().DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: fmt.Sprintf("hobbyfarm.io/session=%s", ss.Name),
})

if err != nil {
return fmt.Errorf("error deleting dynamicbindrequests with session label %s: %s", ss.Name, err)
}

// then we need to delete the vmclaims
err = s.hfClientSet.HobbyfarmV1().VirtualMachineClaims().DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: fmt.Sprintf("hobbyfarm.io/session=%s", ss.Name),
})

Expand All @@ -175,7 +185,7 @@ func (s *SessionController) reconcileSession(ssName string) error {

if expires.Before(now) && !ss.Status.Finished {
// we need to set the session to finished and delete the vm's
if ss.Status.Paused && ss.Status.PausedTime != "" {
if ss.Status.Active && ss.Status.Paused && ss.Status.PausedTime != "" {
pausedExpiration, err := time.Parse(time.UnixDate, ss.Status.PausedTime)
if err != nil {
glog.Error(err)
Expand Down
10 changes: 7 additions & 3 deletions pkg/controllers/vmclaimcontroller/vmclaimcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package vmclaimcontroller

import (
"fmt"
"math/rand"
"strings"
"time"

"github.com/golang/glog"
hfv1 "github.com/hobbyfarm/gargantua/pkg/apis/hobbyfarm.io/v1"
hfClientset "github.com/hobbyfarm/gargantua/pkg/client/clientset/versioned"
Expand All @@ -14,9 +18,6 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/retry"
"k8s.io/client-go/util/workqueue"
"math/rand"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -349,6 +350,9 @@ func (v *VMClaimController) processNextVMClaim() bool {
UID: vmClaim.UID,
},
},
Labels: map[string]string{
"hobbyfarm.io/session": vmClaim.Labels["hobbyfarm.io/session"],
},
},
Spec: hfv1.DynamicBindRequestSpec{
Id: dbrName,
Expand Down
14 changes: 8 additions & 6 deletions pkg/controllers/vmsetcontroller/vmsetcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
hfClientset "github.com/hobbyfarm/gargantua/pkg/client/clientset/versioned"
hfInformers "github.com/hobbyfarm/gargantua/pkg/client/informers/externalversions"
hfListers "github.com/hobbyfarm/gargantua/pkg/client/listers/hobbyfarm.io/v1"
"github.com/hobbyfarm/gargantua/pkg/controllers/scheduledevent"
"github.com/hobbyfarm/gargantua/pkg/util"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -246,12 +247,13 @@ func (v *VirtualMachineSetController) reconcileVirtualMachineSet(vmset *hfv1.Vir
},
},
Labels: map[string]string{
"dynamic": "false",
"vmset": vmset.Name,
"template": vmt.Spec.Id,
"environment": env.Name,
"bound": "false",
"ready": "false",
"dynamic": "false",
"vmset": vmset.Name,
"template": vmt.Spec.Id,
"environment": env.Name,
"bound": "false",
"ready": "false",
scheduledevent.ScheduledEventLabel: vmset.ObjectMeta.Labels[scheduledevent.ScheduledEventLabel],
},
},
Spec: hfv1.VirtualMachineSpec{
Expand Down
Loading

0 comments on commit c0d557e

Please sign in to comment.