Skip to content

Commit

Permalink
fix(ws): update JSON payload for listing workspaces (#134)
Browse files Browse the repository at this point in the history
* fix(ws): update JSON payload for listing workspaces

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): fix workspaceKind type to POD_TEMPLATE

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): ensure podMetadata labels/annotations are not null

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): fetch and use WorkspaceKind for determining home mount paths

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): fix Volumes.Home values and tests

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): fix PodConfig desired value

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* chore: remove lint warnings by cleaning up comments and formatting

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): refactor workspace model creation to include WorkspaceKind

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

* fix(ws): Move NewWorkspaceModelFromWorkspace from models to repositories

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>

---------

Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>
  • Loading branch information
mohamedch7 authored Jan 24, 2025
1 parent 6fe7716 commit d06762d
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 98 deletions.
87 changes: 63 additions & 24 deletions workspaces/backend/api/workspaces_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,13 @@ var _ = Describe("Workspaces Handler", func() {
workspace3 := &kubefloworgv1beta1.Workspace{}
Expect(k8sClient.Get(ctx, workspaceKey3, workspace3)).To(Succeed())

workspaceKind := &kubefloworgv1beta1.WorkspaceKind{}
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: workspaceKindName}, workspaceKind)).To(Succeed())

expectedWorkspaces := []models.WorkspaceModel{
models.NewWorkspaceModelFromWorkspace(workspace1),
models.NewWorkspaceModelFromWorkspace(workspace2),
models.NewWorkspaceModelFromWorkspace(workspace3),
repositories.NewWorkspaceModelFromWorkspace(workspace1, workspaceKind),
repositories.NewWorkspaceModelFromWorkspace(workspace2, workspaceKind),
repositories.NewWorkspaceModelFromWorkspace(workspace3, workspaceKind),
}
Expect(workspaces).To(ConsistOf(expectedWorkspaces))

Expand Down Expand Up @@ -255,9 +258,12 @@ var _ = Describe("Workspaces Handler", func() {
workspace2 := &kubefloworgv1beta1.Workspace{}
Expect(k8sClient.Get(ctx, workspaceKey2, workspace2)).To(Succeed())

workspaceKind := &kubefloworgv1beta1.WorkspaceKind{}
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: workspaceKindName}, workspaceKind)).To(Succeed())

expectedWorkspaces := []models.WorkspaceModel{
models.NewWorkspaceModelFromWorkspace(workspace1),
models.NewWorkspaceModelFromWorkspace(workspace2),
repositories.NewWorkspaceModelFromWorkspace(workspace1, workspaceKind),
repositories.NewWorkspaceModelFromWorkspace(workspace2, workspaceKind),
}
Expect(workspaces).To(ConsistOf(expectedWorkspaces))

Expand Down Expand Up @@ -379,26 +385,60 @@ var _ = Describe("Workspaces Handler", func() {
By("creating the workspace via the API")
workspaceName := "dora"
workspaceModel := models.WorkspaceModel{
Name: workspaceName,
Namespace: namespaceNameCrud,
Paused: false,
Name: workspaceName,
Namespace: namespaceNameCrud,
WorkspaceKind: models.WorkspaceKind{
Name: workspaceKindName,
Type: "POD_TEMPLATE",
},
DeferUpdates: false,
Kind: "jupyterlab",
ImageConfig: "jupyterlab_scipy_190",
PodConfig: "tiny_cpu",
HomeVolume: "workspace-home-bella",
DataVolumes: []models.DataVolumeModel{
{
PvcName: "workspace-data-bella",
MountPath: "/data/my-data",
ReadOnly: false,
Paused: false,
PausedTime: 0,
State: "",
StateMessage: "",
PodTemplate: models.PodTemplate{
PodMetadata: &models.PodMetadata{
Labels: map[string]string{
"app": "dora",
},
Annotations: map[string]string{
"app": "dora",
},
},
Volumes: &models.Volumes{
Home: &models.DataVolumeModel{
PvcName: "my-data-pvc",
MountPath: "/home/jovyan",
ReadOnly: false,
},
Data: []models.DataVolumeModel{
{
PvcName: "my-data-pvc",
MountPath: "/data",
ReadOnly: false,
},
},
},
ImageConfig: &models.ImageConfig{
Current: "WorkspaceKind",
Desired: "", // Status is coming with empty value
RedirectChain: []*models.RedirectChain{},
},
PodConfig: &models.PodConfig{
Current: "WorkspaceKind",
Desired: "WorkspaceKind",
RedirectChain: []*models.RedirectChain{},
},
},
Labels: map[string]string{
"app": "jupyter",
},
Annotations: map[string]string{
"environment": "dev",
Activity: models.Activity{
LastActivity: 0,
LastUpdate: 0,
LastProbe: &models.Probe{
StartTimeMs: 0,
EndTimeMs: 0,
Result: "default_result",
Message: "default_message",
},
},
}

Expand Down Expand Up @@ -461,8 +501,7 @@ var _ = Describe("Workspaces Handler", func() {
err = json.Unmarshal(body, &response)
Expect(err).NotTo(HaveOccurred(), "Error unmarshalling response JSON")

// remove auto generated fields from comparison
response.Data.LastActivity = ""
response.Data.Activity.LastActivity = 0

By("checking if the retrieved workspace matches the expected workspace")
retrievedWorkspaceJSON, err := json.Marshal(response.Data)
Expand Down
108 changes: 59 additions & 49 deletions workspaces/backend/internal/models/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,71 @@ limitations under the License.

package models

import (
"time"
type WorkspaceModel struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
WorkspaceKind WorkspaceKind `json:"workspace_kind"`
DeferUpdates bool `json:"defer_updates"`
Paused bool `json:"paused"`
PausedTime int64 `json:"paused_time"`
State string `json:"state"`
StateMessage string `json:"state_message"`
PodTemplate PodTemplate `json:"pod_template"`
Activity Activity `json:"activity"`
}
type PodTemplate struct {
PodMetadata *PodMetadata `json:"pod_metadata"`
Volumes *Volumes `json:"volumes"`
ImageConfig *ImageConfig `json:"image_config"`
PodConfig *PodConfig `json:"pod_config"`
}

type PodMetadata struct {
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
}
type Volumes struct {
Home *DataVolumeModel `json:"home"`
Data []DataVolumeModel `json:"data"`
}

kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"
)
type ImageConfig struct {
Current string `json:"current"`
Desired string `json:"desired"`
RedirectChain []*RedirectChain `json:"redirect_chain"`
}

type WorkspaceModel struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
Paused bool `json:"paused"`
DeferUpdates bool `json:"defer_updates"`
Kind string `json:"kind"`
ImageConfig string `json:"image_config"`
PodConfig string `json:"pod_config"`
HomeVolume string `json:"home_volume"`
DataVolumes []DataVolumeModel `json:"data_volumes"`
Labels map[string]string `json:"labels,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
Status string `json:"status"`
LastActivity string `json:"last_activity"`
type PodConfig struct {
Current string `json:"current"`
Desired string `json:"desired"`
RedirectChain []*RedirectChain `json:"redirect_chain"`
}

type RedirectChain struct {
Source string `json:"source"`
Target string `json:"target"`
}

type Activity struct {
LastActivity int64 `json:"last_activity"` // Unix Epoch time
LastUpdate int64 `json:"last_update"` // Unix Epoch time
LastProbe *Probe `json:"last_probe"`
}

type Probe struct {
StartTimeMs int64 `json:"start_time_ms"` // Unix Epoch time in milliseconds
EndTimeMs int64 `json:"end_time_ms"` // Unix Epoch time in milliseconds
Result string `json:"result"`
Message string `json:"message"`
}

type WorkspaceKind struct {
Name string `json:"name"`
Type string `json:"type"`
}

type DataVolumeModel struct {
PvcName string `json:"pvc_name"`
MountPath string `json:"mount_path"`
ReadOnly bool `json:"read_only"`
}

func NewWorkspaceModelFromWorkspace(item *kubefloworgv1beta1.Workspace) WorkspaceModel {
t := time.Unix(item.Status.Activity.LastActivity, 0)
formattedLastActivity := t.Format("2006-01-02 15:04:05 MST")

dataVolumes := make([]DataVolumeModel, len(item.Spec.PodTemplate.Volumes.Data))
for i, volume := range item.Spec.PodTemplate.Volumes.Data {
dataVolumes[i] = DataVolumeModel{
PvcName: volume.PVCName,
MountPath: volume.MountPath,
ReadOnly: *volume.ReadOnly,
}
}
// TODO: review all fields
workspaceModel := WorkspaceModel{
Namespace: item.Namespace,
Name: item.ObjectMeta.Name,
Paused: *item.Spec.Paused,
DeferUpdates: *item.Spec.DeferUpdates,
Kind: item.Spec.Kind,
ImageConfig: item.Spec.PodTemplate.Options.ImageConfig,
PodConfig: item.Spec.PodTemplate.Options.PodConfig,
HomeVolume: *item.Spec.PodTemplate.Volumes.Home,
DataVolumes: dataVolumes,
Labels: item.ObjectMeta.Labels,
Annotations: item.ObjectMeta.Annotations,
Status: string(item.Status.State),
LastActivity: formattedLastActivity,
}
return workspaceModel
}
Loading

0 comments on commit d06762d

Please sign in to comment.