Skip to content

Commit c69b062

Browse files
committed
get ws port
Signed-off-by: Adem Baccara <[email protected]>
1 parent 4934408 commit c69b062

File tree

2 files changed

+52
-29
lines changed

2 files changed

+52
-29
lines changed

workspaces/controller/config/samples/jupyterlab_v1beta1_workspacekind.yaml

+27-27
Original file line numberDiff line numberDiff line change
@@ -99,38 +99,38 @@ spec:
9999
## - if the Workspace had activity in the last 60 seconds this command
100100
## should return status 0, otherwise it should return status 1
101101
##
102-
exec:
103-
outputPath: "/tmp/activity_probe.json"
104-
timeoutSeconds: 60
105-
script: |-
106-
#!/usr/bin/env bash
107-
108-
set -euo pipefail
109-
110-
# Define the output path
111-
output_path="/tmp/activity_probe.json"
112-
113-
# Find the most recent modification time in the $HOME directory
114-
last_activity_epoch=$(find "$HOME" -type f -printf '%T@\n' 2>/dev/null | awk 'max < $1 { max = $1 } END { print max }')
115-
116-
# Write the last activity time to the output path
117-
if [ -n "$last_activity_epoch" ]; then
118-
# Convert epoch time to ISO 8601 format
119-
last_activity=$(date -d "@$last_activity_epoch" -Iseconds)
120-
echo "{\"last_activity\": \"$last_activity\"}" > "$output_path"
121-
else
122-
# Handle the case where no files are found
123-
echo "{\"last_activity\": null}" > "$output_path"
124-
fi
102+
# exec:
103+
# outputPath: "/tmp/activity_probe.json"
104+
# timeoutSeconds: 60
105+
# script: |-
106+
# #!/usr/bin/env bash
107+
#
108+
# set -euo pipefail
109+
#
110+
# # Define the output path
111+
# output_path="/tmp/activity_probe.json"
112+
#
113+
# # Find the most recent modification time in the $HOME directory
114+
# last_activity_epoch=$(find "$HOME" -type f -printf '%T@\n' 2>/dev/null | awk 'max < $1 { max = $1 } END { print max }')
115+
#
116+
# # Write the last activity time to the output path
117+
# if [ -n "$last_activity_epoch" ]; then
118+
# # Convert epoch time to ISO 8601 format
119+
# last_activity=$(date -d "@$last_activity_epoch" -Iseconds)
120+
# echo "{\"last_activity\": \"$last_activity\"}" > "$output_path"
121+
# else
122+
# # Handle the case where no files are found
123+
# echo "{\"last_activity\": null}" > "$output_path"
124+
# fi
125125
## OPTION 2: a Jupyter-specific probe
126126
## - will poll the `/api/status` endpoint of the Jupyter API, and use the `last_activity` field
127127
## https://github.com/jupyter-server/jupyter_server/blob/v2.13.0/jupyter_server/services/api/handlers.py#L62-L67
128128
## - note, users need to be careful that their other probes don't trigger a "last_activity" update
129129
## e.g. they should only check the health of Jupyter using the `/api/status` endpoint
130-
##
131-
# jupyter:
132-
# lastActivity: true
133-
# portId: jupyterlab
130+
#
131+
jupyter:
132+
lastActivity: true
133+
portId: jupyterlab
134134

135135
## standard probes to determine Container health (MUTABLE)
136136
## - spec for Probe:

workspaces/controller/internal/controller/culling_controller.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,17 @@ func (r *CullingReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
174174
Message: "Failed to fetch service name for workspace",
175175
}, nil, nil)
176176
}
177-
port := "8888"
178-
jupyterAPIEndpoint := fmt.Sprintf("http://%s.%s.svc.%s:%s/workspace/%s/%s/jupyterlab/api/status", serviceName, workspace.Namespace, defaultClusterDomain, port, workspace.Namespace, workspace.Name)
177+
port, err := r.getWorkspacePort(ctx, workspace, workspaceKind)
178+
if err != nil {
179+
log.Error(err, "Error fetching port for workspace")
180+
return r.updateWorkspaceActivityStatus(ctx, log, workspace, &minRequeueAfter, &kubefloworgv1beta1.ProbeStatus{
181+
StartTimeMs: probeStartTime.UnixMilli(),
182+
EndTimeMs: time.Now().UnixMilli(),
183+
Result: kubefloworgv1beta1.ProbeResultFailure,
184+
Message: "Failed to fetch port for workspace",
185+
}, nil, nil)
186+
}
187+
jupyterAPIEndpoint := fmt.Sprintf("http://%s.%s.svc.%s:%d/workspace/%s/%s/jupyterlab/api/status", serviceName, workspace.Namespace, defaultClusterDomain, port, workspace.Namespace, workspace.Name)
179188

180189
lastActivity, err, probeMessage, probeResult := fetchLastActivityFromJupyterAPI(jupyterAPIEndpoint)
181190
if err != nil {
@@ -211,6 +220,7 @@ func (r *CullingReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
211220
}, ptr.To(probeStartTime.Unix()), ptr.To(lastActivity.Unix()))
212221
}
213222

223+
// Check if Bash probing is enabled
214224
if workspaceKind.Spec.PodTemplate.Culling.ActivityProbe.Exec != nil {
215225
probeStartTime := time.Now()
216226
podName, err := r.getPodName(ctx, workspace)
@@ -369,6 +379,19 @@ func (r *CullingReconciler) getServiceName(ctx context.Context, workspace *kubef
369379
return ownedServices.Items[0].Name, nil
370380
}
371381

382+
func (r *CullingReconciler) getWorkspacePort(ctx context.Context, workspace *kubefloworgv1beta1.Workspace, workspaceKind *kubefloworgv1beta1.WorkspaceKind) (int32, error) {
383+
for _, imageConfigValue := range workspaceKind.Spec.PodTemplate.Options.ImageConfig.Values {
384+
if imageConfigValue.Id == workspace.Spec.PodTemplate.Options.ImageConfig {
385+
for _, port := range imageConfigValue.Spec.Ports {
386+
if port.Id == workspaceKind.Spec.PodTemplate.Culling.ActivityProbe.Jupyter.PortId {
387+
return port.Port, nil
388+
}
389+
}
390+
}
391+
}
392+
return 0, errors.New("port not found")
393+
}
394+
372395
func (r *CullingReconciler) getPodName(ctx context.Context, workspace *kubefloworgv1beta1.Workspace) (string, error) {
373396
var statefulSetName string
374397
ownedStatefulSets := &appsv1.StatefulSetList{}

0 commit comments

Comments
 (0)