Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion workspaces/backend/api/workspaces_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ var _ = Describe("Workspaces Handler", func() {
By("ensuring the model for Workspace with missing WorkspaceKind is as expected")
workspaceMissingWskModel := models.NewWorkspaceListItemFromWorkspace(a.Config, workspaceMissingWsk, nil)
Expect(workspaceMissingWskModel.WorkspaceKind.Missing).To(BeTrue())
Expect(workspaceMissingWskModel.PodTemplate.Volumes.Home.MountPath).To(Equal(models.UnknownHomeMountPath))
Expect(workspaceMissingWskModel.PodTemplate.Options.PodConfig.Current.DisplayName).To(Equal(models.UnknownPodConfig))
Expect(workspaceMissingWskModel.PodTemplate.Options.PodConfig.Current.Description).To(Equal(models.UnknownPodConfig))
Expect(workspaceMissingWskModel.PodTemplate.Options.ImageConfig.Current.DisplayName).To(Equal(models.UnknownImageConfig))
Expand Down
51 changes: 0 additions & 51 deletions workspaces/backend/internal/models/workspaces/common/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"maps"

kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"
"k8s.io/utils/ptr"
)

// WskExists checks if a WorkspaceKind is non-nil and has a valid UID.
Expand All @@ -42,59 +41,9 @@ func ExtractPodMetadata(ws *kubefloworgv1beta1.Workspace) PodMetadata {
}
}

// BuildDataVolumes creates a PodVolumeInfo slice from a workspace's data volumes.
func BuildDataVolumes(ws *kubefloworgv1beta1.Workspace) []PodVolumeInfo {
var dataVolumes []PodVolumeInfo
if len(ws.Spec.PodTemplate.Volumes.Data) > 0 {
dataVolumes = make([]PodVolumeInfo, 0, len(ws.Spec.PodTemplate.Volumes.Data))
for _, v := range ws.Spec.PodTemplate.Volumes.Data {
dataVolumes = append(dataVolumes, PodVolumeInfo{
PVCName: v.PVCName,
MountPath: v.MountPath,
ReadOnly: ptr.Deref(v.ReadOnly, false),
})
}
}
return dataVolumes
}

// BuildSecretVolumes creates a PodSecretInfo slice from a workspace's secret volumes.
func BuildSecretVolumes(ws *kubefloworgv1beta1.Workspace) []PodSecretInfo {
var secretVolumes []PodSecretInfo
if len(ws.Spec.PodTemplate.Volumes.Secrets) > 0 {
secretVolumes = make([]PodSecretInfo, len(ws.Spec.PodTemplate.Volumes.Secrets))
for i, s := range ws.Spec.PodTemplate.Volumes.Secrets {
secretVolumes[i] = PodSecretInfo{
SecretName: s.SecretName,
MountPath: s.MountPath,
DefaultMode: s.DefaultMode,
}
}
}
return secretVolumes
}

// EnsureWskMatchesWorkspace panics if the provided WorkspaceKind exists but does not match the Workspace.
func EnsureWskMatchesWorkspace(ws *kubefloworgv1beta1.Workspace, wsk *kubefloworgv1beta1.WorkspaceKind) {
if WskExists(wsk) && ws.Spec.Kind != wsk.Name {
panic("provided WorkspaceKind does not match the Workspace")
}
}

// BuildHomeVolume creates a PodVolumeInfo for the workspace's home volume.
func BuildHomeVolume(ws *kubefloworgv1beta1.Workspace, wsk *kubefloworgv1beta1.WorkspaceKind) *PodVolumeInfo {
if ws.Spec.PodTemplate.Volumes.Home == nil {
return nil
}

mountPath := UnknownHomeMountPath
if WskExists(wsk) {
mountPath = wsk.Spec.PodTemplate.VolumeMounts.Home
}

return &PodVolumeInfo{
PVCName: *ws.Spec.PodTemplate.Volumes.Home,
MountPath: mountPath,
ReadOnly: false,
}
}
14 changes: 0 additions & 14 deletions workspaces/backend/internal/models/workspaces/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,7 @@ limitations under the License.

package common

const UnknownHomeMountPath = "__UNKNOWN_HOME_MOUNT_PATH__"

type PodMetadata struct {
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
}

type PodVolumeInfo struct {
PVCName string `json:"pvcName"`
MountPath string `json:"mountPath"`
ReadOnly bool `json:"readOnly"`
}

type PodSecretInfo struct {
SecretName string `json:"secretName"`
MountPath string `json:"mountPath"`
DefaultMode int32 `json:"defaultMode,omitempty"`
}
26 changes: 8 additions & 18 deletions workspaces/backend/internal/models/workspaces/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,17 @@ import (
)

const (
UnknownHomeMountPath = commonWorkspaces.UnknownHomeMountPath
UnknownImageConfig = "__UNKNOWN_IMAGE_CONFIG__"
UnknownPodConfig = "__UNKNOWN_POD_CONFIG__"
UnknownIconURL = "__UNKNOWN_ICON_URL__"
UnknownLogoURL = "__UNKNOWN_LOGO_URL__"
UnknownImageConfig = "__UNKNOWN_IMAGE_CONFIG__"
UnknownPodConfig = "__UNKNOWN_POD_CONFIG__"
UnknownIconURL = "__UNKNOWN_ICON_URL__"
UnknownLogoURL = "__UNKNOWN_LOGO_URL__"
)

// NewWorkspaceListItemFromWorkspace creates a WorkspaceListItem model from a Workspace and WorkspaceKind object.
// NOTE: the WorkspaceKind might not exist, so we handle the case where it is nil or has no UID.
func NewWorkspaceListItemFromWorkspace(cfg *config.EnvConfig, ws *kubefloworgv1beta1.Workspace, wsk *kubefloworgv1beta1.WorkspaceKind) WorkspaceListItem {
commonWorkspaces.EnsureWskMatchesWorkspace(ws, wsk)

podMetadata := commonWorkspaces.ExtractPodMetadata(ws)
dataVolumes := commonWorkspaces.BuildDataVolumes(ws)

imageConfigModel, imageConfigValue := buildImageConfig(ws, wsk)
podConfigModel, _ := buildPodConfig(ws, wsk)
wskPodTemplatePorts := make(map[kubefloworgv1beta1.PortId]kubefloworgv1beta1.WorkspaceKindPort)
Expand All @@ -62,17 +58,11 @@ func NewWorkspaceListItemFromWorkspace(cfg *config.EnvConfig, ws *kubefloworgv1b
Icon: buildIconImageRef(cfg, ws, wsk),
Logo: buildLogoImageRef(cfg, ws, wsk),
},
Paused: ptr.Deref(ws.Spec.Paused, false),
PausedTime: ws.Status.PauseTime,
PendingRestart: ws.Status.PendingRestart,
State: ws.Status.State,
StateMessage: ws.Status.StateMessage,
Paused: ptr.Deref(ws.Spec.Paused, false),
PausedTime: ws.Status.PauseTime,
State: ws.Status.State,
StateMessage: ws.Status.StateMessage,
PodTemplate: PodTemplate{
PodMetadata: podMetadata,
Volumes: PodVolumes{
Home: commonWorkspaces.BuildHomeVolume(ws, wsk),
Data: dataVolumes,
},
Options: PodTemplateOptions{
ImageConfig: imageConfigModel,
PodConfig: podConfigModel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package details

import (
"k8s.io/utils/ptr"

kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"

commonWorkspaces "github.com/kubeflow/notebooks/workspaces/backend/internal/models/workspaces/common"
Expand Down Expand Up @@ -55,10 +57,60 @@ func NewWorkspaceDetailsFromWorkspace(
return WorkspaceDetails{
PodMetadata: commonWorkspaces.ExtractPodMetadata(ws),
Volumes: WorkspaceDetailVolumes{
Home: commonWorkspaces.BuildHomeVolume(ws, wsk),
Data: commonWorkspaces.BuildDataVolumes(ws),
Secrets: commonWorkspaces.BuildSecretVolumes(ws),
Home: BuildHomeVolume(ws, wsk),
Data: BuildDataVolumes(ws),
Secrets: BuildSecretVolumes(ws),
},
Pod: pod,
}
}

// BuildHomeVolume creates a PodVolumeInfo for the workspace's home volume.
func BuildHomeVolume(ws *kubefloworgv1beta1.Workspace, wsk *kubefloworgv1beta1.WorkspaceKind) *PodVolumeInfo {
if ws.Spec.PodTemplate.Volumes.Home == nil {
return nil
}

mountPath := UnknownHomeMountPath
if commonWorkspaces.WskExists(wsk) {
mountPath = wsk.Spec.PodTemplate.VolumeMounts.Home
}

return &PodVolumeInfo{
PVCName: *ws.Spec.PodTemplate.Volumes.Home,
MountPath: mountPath,
ReadOnly: false,
}
}

// BuildDataVolumes creates a PodVolumeInfo slice from a workspace's data volumes.
func BuildDataVolumes(ws *kubefloworgv1beta1.Workspace) []PodVolumeInfo {
var dataVolumes []PodVolumeInfo
if len(ws.Spec.PodTemplate.Volumes.Data) > 0 {
dataVolumes = make([]PodVolumeInfo, 0, len(ws.Spec.PodTemplate.Volumes.Data))
for _, v := range ws.Spec.PodTemplate.Volumes.Data {
dataVolumes = append(dataVolumes, PodVolumeInfo{
PVCName: v.PVCName,
MountPath: v.MountPath,
ReadOnly: ptr.Deref(v.ReadOnly, false),
})
}
}
return dataVolumes
}

// BuildSecretVolumes creates a PodSecretInfo slice from a workspace's secret volumes.
func BuildSecretVolumes(ws *kubefloworgv1beta1.Workspace) []PodSecretInfo {
var secretVolumes []PodSecretInfo
if len(ws.Spec.PodTemplate.Volumes.Secrets) > 0 {
secretVolumes = make([]PodSecretInfo, len(ws.Spec.PodTemplate.Volumes.Secrets))
for i, s := range ws.Spec.PodTemplate.Volumes.Secrets {
secretVolumes[i] = PodSecretInfo{
SecretName: s.SecretName,
MountPath: s.MountPath,
DefaultMode: s.DefaultMode,
}
}
}
return secretVolumes
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with the introduction of these types in podtemplate/details - we can now actually REMOVE the types we had originally added to common/

  • admittedly it was a weird dance - but the right one to ensure at any given time code was optimal!

So I think the following can be cleaned up from common/types.go (can't directly comment on it since that file isn't presently included in this PR):

  • const UnknownHomeMountPath
  • type PodVolumeInfo struct
  • type PodSecretInfo struct

PodMetadata SHOULD REMAIN in common/types.go

Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ import (
commonWorkspaces "github.com/kubeflow/notebooks/workspaces/backend/internal/models/workspaces/common"
)

const UnknownHomeMountPath = "__UNKNOWN_HOME_MOUNT_PATH__"

type WorkspaceDetails struct {
PodMetadata commonWorkspaces.PodMetadata `json:"podMetadata"`
Volumes WorkspaceDetailVolumes `json:"volumes"`
Pod *WorkspaceDetailPod `json:"pod,omitempty"`
}

type WorkspaceDetailVolumes struct {
Home *commonWorkspaces.PodVolumeInfo `json:"home"`
Data []commonWorkspaces.PodVolumeInfo `json:"data,omitempty"`
Secrets []commonWorkspaces.PodSecretInfo `json:"secrets,omitempty"`
Home *PodVolumeInfo `json:"home"`
Data []PodVolumeInfo `json:"data,omitempty"`
Secrets []PodSecretInfo `json:"secrets,omitempty"`
}

type WorkspaceDetailPod struct {
Expand All @@ -42,3 +44,15 @@ type WorkspaceDetailPod struct {
type WorkspaceDetailContainer struct {
Name string `json:"name"`
}

type PodVolumeInfo struct {
Comment thread
Snehadas2005 marked this conversation as resolved.
PVCName string `json:"pvcName"`
MountPath string `json:"mountPath"`
ReadOnly bool `json:"readOnly"`
}

type PodSecretInfo struct {
SecretName string `json:"secretName"`
MountPath string `json:"mountPath"`
DefaultMode int32 `json:"defaultMode,omitempty"`
}
34 changes: 12 additions & 22 deletions workspaces/backend/internal/models/workspaces/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,24 @@ import (

commonCore "github.com/kubeflow/notebooks/workspaces/backend/internal/models/common"
commonAssets "github.com/kubeflow/notebooks/workspaces/backend/internal/models/common/assets"
commonWorkspaces "github.com/kubeflow/notebooks/workspaces/backend/internal/models/workspaces/common"
)

// WorkspaceListItem represents a workspace in the system, and is returned by LIST operations.
// NOTE: this type is not used for GET, CREATE or UPDATE operations, see WorkspaceUpdate and WorkspaceCreate
// TODO: we need to validate which fields should actually be returned in the response
// - should only be returning fields relevant to the list view in the UI
type WorkspaceListItem struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
WorkspaceKind WorkspaceKindInfo `json:"workspaceKind"`
Paused bool `json:"paused"`
PausedTime int64 `json:"pausedTime"`
PendingRestart bool `json:"pendingRestart"`
State kubefloworgv1beta1.WorkspaceState `json:"state"`
StateMessage string `json:"stateMessage"`
PodTemplate PodTemplate `json:"podTemplate"`
Activity Activity `json:"activity"`
Services []Service `json:"services"`
Audit commonCore.Audit `json:"audit"`
Name string `json:"name"`
Namespace string `json:"namespace"`
WorkspaceKind WorkspaceKindInfo `json:"workspaceKind"`
Paused bool `json:"paused"`
PausedTime int64 `json:"pausedTime"`
State kubefloworgv1beta1.WorkspaceState `json:"state"`
StateMessage string `json:"stateMessage"`
PodTemplate PodTemplate `json:"podTemplate"`
Activity Activity `json:"activity"`
Services []Service `json:"services"`
Audit commonCore.Audit `json:"audit"`
}

type WorkspaceKindInfo struct {
Expand All @@ -51,15 +49,7 @@ type WorkspaceKindInfo struct {
}

type PodTemplate struct {
PodMetadata commonWorkspaces.PodMetadata `json:"podMetadata"`
Volumes PodVolumes `json:"volumes"`
Options PodTemplateOptions `json:"options"`
}

type PodVolumes struct {
Home *commonWorkspaces.PodVolumeInfo `json:"home,omitempty"`
Data []commonWorkspaces.PodVolumeInfo `json:"data,omitempty"`
Secrets []commonWorkspaces.PodSecretInfo `json:"secrets,omitempty"`
Options PodTemplateOptions `json:"options"`
}

type PodTemplateOptions struct {
Expand Down
Loading