Skip to content

Commit dfe22c9

Browse files
committed
fix: default empty workspace state to Unknown in API responses
The list-workspaces API was copying ws.Status.State verbatim, so a workspace whose controller had not yet reconciled a status was serialised with "state": "" — leaving frontend label cells visually empty (the symptom in #1104) and contradicting the generated OpenAPI contract, which declares the field as the non-empty V1Beta1WorkspaceState enum. Default ws.Status.State to WorkspaceStateUnknown when it is the zero value so the API always honours the contract, and remove the need for defensive fallbacks in clients. Also adds a unit test for the helper. Refs #1104 Assisted-by: Claude (Anthropic) Signed-off-by: Ian Moog <ianmoog42@gmail.com>
1 parent 02c5bd2 commit dfe22c9

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

workspaces/backend/internal/models/workspaces/funcs.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func NewWorkspaceListItemFromWorkspace(cfg *config.EnvConfig, ws *kubefloworgv1b
8686
Paused: ptr.Deref(ws.Spec.Paused, false),
8787
PausedTime: ws.Status.PauseTime,
8888
PendingRestart: ws.Status.PendingRestart,
89-
State: ws.Status.State,
89+
State: defaultWorkspaceState(ws.Status.State),
9090
StateMessage: ws.Status.StateMessage,
9191
PodTemplate: PodTemplate{
9292
PodMetadata: PodMetadata{
@@ -119,6 +119,15 @@ func wskExists(wsk *kubefloworgv1beta1.WorkspaceKind) bool {
119119
return wsk != nil && wsk.UID != ""
120120
}
121121

122+
// defaultWorkspaceState returns WorkspaceStateUnknown when the controller has not
123+
// yet reconciled a workspace's status, so API consumers never see an empty state.
124+
func defaultWorkspaceState(state kubefloworgv1beta1.WorkspaceState) kubefloworgv1beta1.WorkspaceState {
125+
if state == "" {
126+
return kubefloworgv1beta1.WorkspaceStateUnknown
127+
}
128+
return state
129+
}
130+
122131
func buildHomeVolume(ws *kubefloworgv1beta1.Workspace, wsk *kubefloworgv1beta1.WorkspaceKind) *PodVolumeInfo {
123132
if ws.Spec.PodTemplate.Volumes.Home == nil {
124133
return nil
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2024.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package workspaces
18+
19+
import (
20+
"testing"
21+
22+
. "github.com/onsi/ginkgo/v2"
23+
. "github.com/onsi/gomega"
24+
25+
kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"
26+
)
27+
28+
func TestWorkspacesModels(t *testing.T) {
29+
RegisterFailHandler(Fail)
30+
RunSpecs(t, "Workspaces Models Suite")
31+
}
32+
33+
var _ = Describe("defaultWorkspaceState", func() {
34+
It("returns WorkspaceStateUnknown for the empty string", func() {
35+
Expect(defaultWorkspaceState("")).To(Equal(kubefloworgv1beta1.WorkspaceStateUnknown))
36+
})
37+
38+
It("returns the original state when it is already set", func() {
39+
for _, state := range []kubefloworgv1beta1.WorkspaceState{
40+
kubefloworgv1beta1.WorkspaceStateRunning,
41+
kubefloworgv1beta1.WorkspaceStateTerminating,
42+
kubefloworgv1beta1.WorkspaceStatePaused,
43+
kubefloworgv1beta1.WorkspaceStatePending,
44+
kubefloworgv1beta1.WorkspaceStateError,
45+
kubefloworgv1beta1.WorkspaceStateUnknown,
46+
} {
47+
Expect(defaultWorkspaceState(state)).To(Equal(state))
48+
}
49+
})
50+
})

0 commit comments

Comments
 (0)