Skip to content

Commit 50fe395

Browse files
committed
[wsman-mk2] Emit workspace events
1 parent ace513a commit 50fe395

File tree

6 files changed

+50
-13
lines changed

6 files changed

+50
-13
lines changed

components/ws-daemon/pkg/controller/workspace_controller.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2727
"k8s.io/apimachinery/pkg/types"
2828
"k8s.io/apimachinery/pkg/util/wait"
29+
"k8s.io/client-go/tools/record"
2930
"k8s.io/client-go/util/retry"
3031
ctrl "sigs.k8s.io/controller-runtime"
3132
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -58,9 +59,10 @@ type WorkspaceController struct {
5859
operations *WorkspaceOperations
5960
metrics *workspaceMetrics
6061
secretNamespace string
62+
recorder record.EventRecorder
6163
}
6264

63-
func NewWorkspaceController(c client.Client, nodeName, secretNamespace string, maxConcurrentReconciles int, ops *WorkspaceOperations, reg prometheus.Registerer) (*WorkspaceController, error) {
65+
func NewWorkspaceController(c client.Client, recorder record.EventRecorder, nodeName, secretNamespace string, maxConcurrentReconciles int, ops *WorkspaceOperations, reg prometheus.Registerer) (*WorkspaceController, error) {
6466
metrics := newWorkspaceMetrics()
6567
reg.Register(metrics)
6668

@@ -71,6 +73,7 @@ func NewWorkspaceController(c client.Client, nodeName, secretNamespace string, m
7173
operations: ops,
7274
metrics: metrics,
7375
secretNamespace: secretNamespace,
76+
recorder: recorder,
7477
}, nil
7578
}
7679

@@ -182,6 +185,7 @@ func (wsc *WorkspaceController) handleWorkspaceInit(ctx context.Context, ws *wor
182185
wsc.metrics.recordInitializeTime(time.Since(initStart).Seconds(), ws)
183186
}
184187

188+
wsc.emitEvent(ws, "Content init", initErr)
185189
return ctrl.Result{}, err
186190
}
187191

@@ -277,6 +281,7 @@ func (wsc *WorkspaceController) handleWorkspaceStop(ctx context.Context, ws *wor
277281
wsc.metrics.recordFinalizeTime(time.Since(disposeStart).Seconds(), ws)
278282
}
279283

284+
wsc.emitEvent(ws, "Backup", disposeErr)
280285
return ctrl.Result{}, err
281286
}
282287

@@ -301,6 +306,12 @@ func (wsc *WorkspaceController) prepareInitializer(ctx context.Context, ws *work
301306
return &init, nil
302307
}
303308

309+
func (wsc *WorkspaceController) emitEvent(ws *workspacev1.Workspace, operation string, failure error) {
310+
if failure != nil {
311+
wsc.recorder.Eventf(ws, corev1.EventTypeWarning, "Failed", "%s failed: %s", operation, failure.Error())
312+
}
313+
}
314+
304315
func toWorkspaceGitStatus(status *csapi.GitStatus) *workspacev1.GitStatus {
305316
if status == nil {
306317
return nil

components/ws-daemon/pkg/daemon/daemon.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func NewDaemon(config Config) (*Daemon, error) {
210210
}
211211

212212
wsctrl, err := controller.NewWorkspaceController(
213-
mgr.GetClient(), nodename, config.Runtime.SecretsNamespace, config.WorkspaceController.MaxConcurrentReconciles, workspaceOps, wrappedReg)
213+
mgr.GetClient(), mgr.GetEventRecorderFor("workspace"), nodename, config.Runtime.SecretsNamespace, config.WorkspaceController.MaxConcurrentReconciles, workspaceOps, wrappedReg)
214214
if err != nil {
215215
return nil, err
216216
}
@@ -219,7 +219,8 @@ func NewDaemon(config Config) (*Daemon, error) {
219219
return nil, err
220220
}
221221

222-
ssctrl := controller.NewSnapshotController(mgr.GetClient(), nodename, config.WorkspaceController.MaxConcurrentReconciles, workspaceOps)
222+
ssctrl := controller.NewSnapshotController(
223+
mgr.GetClient(), mgr.GetEventRecorderFor("snapshot"), nodename, config.WorkspaceController.MaxConcurrentReconciles, workspaceOps)
223224
err = ssctrl.SetupWithManager(mgr)
224225
if err != nil {
225226
return nil, err

components/ws-manager-mk2/controllers/status.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const (
3131
containerUnknownExitCode = 255
3232
)
3333

34-
func updateWorkspaceStatus(ctx context.Context, workspace *workspacev1.Workspace, pods corev1.PodList, cfg *config.Configuration) error {
34+
func (r *WorkspaceReconciler) updateWorkspaceStatus(ctx context.Context, workspace *workspacev1.Workspace, pods corev1.PodList, cfg *config.Configuration) error {
3535
log := log.FromContext(ctx)
3636

3737
switch len(pods.Items) {
@@ -104,6 +104,8 @@ func updateWorkspaceStatus(ctx context.Context, workspace *workspacev1.Workspace
104104
LastTransitionTime: metav1.Now(),
105105
Message: failure,
106106
})
107+
108+
r.Recorder.Event(workspace, corev1.EventTypeWarning, "Failed", failure)
107109
}
108110

109111
switch {

components/ws-manager-mk2/controllers/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ var _ = BeforeSuite(func() {
105105
Expect(err).ToNot(HaveOccurred())
106106

107107
conf := newTestConfig()
108-
wsReconciler, err := NewWorkspaceReconciler(k8sManager.GetClient(), k8sManager.GetScheme(), &conf, metrics.Registry, &fakeMaintenance{enabled: false})
108+
wsReconciler, err := NewWorkspaceReconciler(k8sManager.GetClient(), k8sManager.GetScheme(), k8sManager.GetEventRecorderFor("workspace"), &conf, metrics.Registry, &fakeMaintenance{enabled: false})
109109
wsMetrics = wsReconciler.metrics
110110
Expect(err).ToNot(HaveOccurred())
111111
Expect(wsReconciler.SetupWithManager(k8sManager)).To(Succeed())

components/ws-manager-mk2/controllers/workspace_controller.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"k8s.io/apimachinery/pkg/runtime"
1717
"k8s.io/apimachinery/pkg/types"
1818
"k8s.io/apimachinery/pkg/util/wait"
19+
"k8s.io/client-go/tools/record"
1920
ctrl "sigs.k8s.io/controller-runtime"
2021
"sigs.k8s.io/controller-runtime/pkg/client"
2122
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -37,12 +38,13 @@ const (
3738
maintenanceRequeue = 1 * time.Minute
3839
)
3940

40-
func NewWorkspaceReconciler(c client.Client, scheme *runtime.Scheme, cfg *config.Configuration, reg prometheus.Registerer, maintenance maintenance.Maintenance) (*WorkspaceReconciler, error) {
41+
func NewWorkspaceReconciler(c client.Client, scheme *runtime.Scheme, recorder record.EventRecorder, cfg *config.Configuration, reg prometheus.Registerer, maintenance maintenance.Maintenance) (*WorkspaceReconciler, error) {
4142
reconciler := &WorkspaceReconciler{
4243
Client: c,
4344
Scheme: scheme,
4445
Config: cfg,
4546
maintenance: maintenance,
47+
Recorder: recorder,
4648
}
4749

4850
metrics, err := newControllerMetrics(reconciler)
@@ -63,6 +65,7 @@ type WorkspaceReconciler struct {
6365
Config *config.Configuration
6466
metrics *controllerMetrics
6567
maintenance maintenance.Maintenance
68+
Recorder record.EventRecorder
6669
OnReconcile func(ctx context.Context, ws *workspacev1.Workspace)
6770
}
6871

@@ -114,12 +117,14 @@ func (r *WorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
114117
return ctrl.Result{}, err
115118
}
116119

117-
err = updateWorkspaceStatus(ctx, &workspace, workspacePods, r.Config)
120+
oldStatus := workspace.Status
121+
err = r.updateWorkspaceStatus(ctx, &workspace, workspacePods, r.Config)
118122
if err != nil {
119123
return ctrl.Result{}, err
120124
}
121125

122126
r.updateMetrics(ctx, &workspace)
127+
r.emitPhaseEvents(ctx, &workspace, oldStatus)
123128

124129
log.V(1).Info("updated workspace status", "status", workspace.Status)
125130
err = r.Status().Update(ctx, &workspace)
@@ -185,6 +190,8 @@ func (r *WorkspaceReconciler) actOnStatus(ctx context.Context, workspace *worksp
185190
log.Error(err, "Failed to patch PodStarts in workspace status")
186191
return ctrl.Result{}, err
187192
}
193+
194+
r.Recorder.Event(workspace, corev1.EventTypeNormal, "Creating", "")
188195
}
189196
r.metrics.rememberWorkspace(workspace, nil)
190197

@@ -203,6 +210,7 @@ func (r *WorkspaceReconciler) actOnStatus(ctx context.Context, workspace *worksp
203210

204211
// Workspace might have already been in a deleting state,
205212
// but not guaranteed, so try deleting anyway.
213+
r.Recorder.Event(workspace, corev1.EventTypeNormal, "Deleting", "")
206214
err := r.Client.Delete(ctx, workspace)
207215
return ctrl.Result{}, client.IgnoreNotFound(err)
208216
}
@@ -340,6 +348,20 @@ func (r *WorkspaceReconciler) updateMetrics(ctx context.Context, workspace *work
340348
r.metrics.rememberWorkspace(workspace, &lastState)
341349
}
342350

351+
func (r *WorkspaceReconciler) emitPhaseEvents(ctx context.Context, ws *workspacev1.Workspace, old workspacev1.WorkspaceStatus) {
352+
if ws.Status.Phase == workspacev1.WorkspacePhaseInitializing && old.Phase != workspacev1.WorkspacePhaseInitializing {
353+
r.Recorder.Event(ws, corev1.EventTypeNormal, "Initializing", "")
354+
}
355+
356+
if ws.Status.Phase == workspacev1.WorkspacePhaseRunning && old.Phase != workspacev1.WorkspacePhaseRunning {
357+
r.Recorder.Event(ws, corev1.EventTypeNormal, "Running", "")
358+
}
359+
360+
if ws.Status.Phase == workspacev1.WorkspacePhaseStopping && old.Phase != workspacev1.WorkspacePhaseStopping {
361+
r.Recorder.Event(ws, corev1.EventTypeNormal, "Stopping", "")
362+
}
363+
}
364+
343365
func (r *WorkspaceReconciler) deleteWorkspacePod(ctx context.Context, pod *corev1.Pod, reason string) (ctrl.Result, error) {
344366
log := log.FromContext(ctx).WithValues("workspace", pod.Name, "reason", reason)
345367
log.V(1).Info("deleting workspace pod")

components/ws-manager-mk2/main.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,14 @@ func main() {
113113
os.Exit(1)
114114
}
115115

116-
maintenance, err := controllers.NewMaintenanceReconciler(mgr.GetClient())
116+
maintenanceReconciler, err := controllers.NewMaintenanceReconciler(mgr.GetClient())
117117
if err != nil {
118118
setupLog.Error(err, "unable to create maintenance controller", "controller", "Maintenance")
119119
os.Exit(1)
120120
}
121121

122-
reconciler, err := controllers.NewWorkspaceReconciler(mgr.GetClient(), mgr.GetScheme(), &cfg.Manager, metrics.Registry, maintenance)
122+
workspaceReconciler, err := controllers.NewWorkspaceReconciler(
123+
mgr.GetClient(), mgr.GetScheme(), mgr.GetEventRecorderFor("workspace"), &cfg.Manager, metrics.Registry, maintenanceReconciler)
123124
if err != nil {
124125
setupLog.Error(err, "unable to create controller", "controller", "Workspace")
125126
os.Exit(1)
@@ -132,22 +133,22 @@ func main() {
132133
os.Exit(1)
133134
}
134135

135-
wsmanService, err := setupGRPCService(cfg, mgr.GetClient(), activity, maintenance)
136+
wsmanService, err := setupGRPCService(cfg, mgr.GetClient(), activity, maintenanceReconciler)
136137
if err != nil {
137138
setupLog.Error(err, "unable to start manager service")
138139
os.Exit(1)
139140
}
140141

141-
reconciler.OnReconcile = wsmanService.OnWorkspaceReconcile
142-
if err = reconciler.SetupWithManager(mgr); err != nil {
142+
workspaceReconciler.OnReconcile = wsmanService.OnWorkspaceReconcile
143+
if err = workspaceReconciler.SetupWithManager(mgr); err != nil {
143144
setupLog.Error(err, "unable to setup workspace controller with manager", "controller", "Workspace")
144145
os.Exit(1)
145146
}
146147
if err = timeoutReconciler.SetupWithManager(mgr); err != nil {
147148
setupLog.Error(err, "unable to setup timeout controller with manager", "controller", "Timeout")
148149
os.Exit(1)
149150
}
150-
if err = maintenance.SetupWithManager(mgr); err != nil {
151+
if err = maintenanceReconciler.SetupWithManager(mgr); err != nil {
151152
setupLog.Error(err, "unable to setup maintenance controller with manager", "controller", "Maintenance")
152153
os.Exit(1)
153154
}

0 commit comments

Comments
 (0)