Skip to content

Commit

Permalink
fix: loading exercises/labs
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Lauber <[email protected]>
  • Loading branch information
janlauber committed Oct 29, 2023
1 parent ff5d57f commit 36a87e3
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 96 deletions.
2 changes: 1 addition & 1 deletion kubelab-backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/caarlos0/env/v8 v8.0.0
github.com/pocketbase/dbx v1.10.1
github.com/pocketbase/pocketbase v0.19.0
github.com/pocketbase/pocketbase v0.19.1
helm.sh/helm/v3 v3.11.2
k8s.io/api v0.27.2
k8s.io/apimachinery v0.27.2
Expand Down
4 changes: 2 additions & 2 deletions kubelab-backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA=
github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
github.com/pocketbase/pocketbase v0.19.0 h1:PvRsABvNgJhafShpXZNXeF/BdkmiwEIcc/+r9QsONdg=
github.com/pocketbase/pocketbase v0.19.0/go.mod h1:iNGsMmhAtmiH4X9aYPK4nTS56XL1HhQPBkmZaWRyQ8Q=
github.com/pocketbase/pocketbase v0.19.1 h1:VudGjdB3lI/y/2t5utIAu+qjEBHLBsd9otN/xpr7SaY=
github.com/pocketbase/pocketbase v0.19.1/go.mod h1:iNGsMmhAtmiH4X9aYPK4nTS56XL1HhQPBkmZaWRyQ8Q=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/poy/onpar v0.0.0-20200406201722-06f95a1c68e8/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
Expand Down
2 changes: 1 addition & 1 deletion kubelab-backend/vcluster-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ isolation:
limitRange:
enabled: false
networkPolicy:
enabled: true
enabled: false
outgoingConnections:
ipBlock:
cidr: 8.8.8.8/32
Expand Down
23 changes: 23 additions & 0 deletions kubelab-fill/userlist_november.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
firstname,lastname,email,password
Elias,Abderhalden,[email protected],dateorange
Thomas,Petersen,[email protected],xiguamango
Yavuz,Polat,[email protected],zucchinitangerine
Flavius,Savan,[email protected],strawberryzucchini
Matthias,Zybach,[email protected],raspberrydate
Andrea,Aramini,[email protected],orangegrape
Salomé,Gagnaux,[email protected],honeydewwatermelon
Angelo,Trombetta,[email protected],quincevine
Paolo,Meraviglia,[email protected],vinedate
Michel,Cadotsch,[email protected],yuzubanana
Elia,Di Comun,[email protected],elderberrystrawberry
Luigi,Verderame,[email protected],watermelonorange
Viktor,Steinmann,[email protected],lemonorange
Andrea,Leoni,[email protected],xiguastrawberry
Andrei,Cornea,[email protected],quincecherry
Catalin,Mares,[email protected],mangoelderberry
Aniello,Merola,[email protected],watermelonugli
Janos,Buzasi,[email protected],bananatangerine
Klaus,Yazigi,[email protected],bananastrawberry
Ibraima,Abramani,[email protected],tangerinemango
Hol,Michel,[email protected],xiguayuzu
Whooley,Donal,[email protected],honeydewpapaya
77 changes: 52 additions & 25 deletions kubelab-ui/src/lib/components/base/SideOver.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@
import toast from "svelte-french-toast";
import { loadingExercises, loadingLabs } from "$lib/stores/loading";
import { client } from "$lib/pocketbase";
import {
sidebar_exercise_sessions,
sidebar_lab,
sidebar_lab_session
} from "$lib/stores/sidebar";
import { sidebar_exercise_sessions, sidebar_lab, sidebar_lab_session } from "$lib/stores/sidebar";
import Exercise from "../labs/Exercise.svelte";
let docs: string;
Expand All @@ -35,18 +31,23 @@
});
}
async function startLab() {
async function startLab(lab_session_id: string) {
// if there is more than one lab_session clusterRunning = true, fail
if ($lab_sessions.filter((lab_session) => lab_session.clusterRunning).length > 1) {
toast.error("There are already two lab running");
return;
}
if ($loadingLabs.length > 0) {
toast.error("There is already a lab starting");
if ($loadingLabs.size > 1) {
toast.error("There are already 2 labs starting/stopping");
return;
}
loadingLabs.update((labs) => {
labs.add(lab_session_id);
return new Set(labs); // Required for Svelte's reactivity
});
const data: LabSessionsRecord = {
clusterRunning: true,
// @ts-ignore
Expand All @@ -55,15 +56,15 @@
startTime: new Date().toISOString()
};
$loadingLabs = $loadingLabs.concat($sidebar_lab_session.id);
await client
.collection("lab_sessions")
.update($sidebar_lab_session.id, data)
.update(lab_session_id, data)
// @ts-ignore
.then((record: LabSessionsResponse) => {
toast.success("Lab started");
$sidebar_lab_session = record;
lab_sessions.update((lab_sessions) => {
return lab_sessions.map((lab_session) => {
if (lab_session.id === record.id) {
Expand All @@ -81,12 +82,20 @@
updateDataStores().catch((error) => {
toast.error(error);
});
$loadingLabs = $loadingLabs.filter((id) => id !== $sidebar_lab_session.id);
loadingLabs.update((labs) => {
labs.delete(lab_session_id);
return new Set(labs); // Required for Svelte's reactivity
});
});
}
// TODO: add modal to confirm stop lab
async function stopLab() {
async function stopLab(lab_session_id: string) {
loadingLabs.update((labs) => {
labs.add(lab_session_id);
return new Set(labs); // Required for Svelte's reactivity
});
const data: LabSessionsRecord = {
clusterRunning: false,
// @ts-ignore
Expand All @@ -95,8 +104,6 @@
endTime: new Date().toISOString()
};
$loadingLabs = $loadingLabs.concat($sidebar_lab_session.id);
// update each exercise session to stop agentRunning = false
$sidebar_exercise_sessions.forEach(async (sidebar_exercise_session) => {
const exercise_session_data: ExerciseSessionsRecord = {
Expand All @@ -105,7 +112,12 @@
user: client.authStore.model?.id,
exercise: sidebar_exercise_session.exercise
};
$loadingExercises = $loadingExercises.concat(sidebar_exercise_session.id);
loadingExercises.update((exercises) => {
exercises.add(sidebar_exercise_session.id);
return new Set(exercises); // Required for Svelte's reactivity
});
await client
.collection("exercise_sessions")
.update(sidebar_exercise_session.id, exercise_session_data)
Expand Down Expand Up @@ -133,7 +145,13 @@
console.error(error);
})
.finally(() => {
$loadingExercises = $loadingExercises.filter((id) => id !== sidebar_exercise_session.id);
updateDataStores().catch((error) => {
toast.error(error);
});
loadingExercises.update((exercises) => {
exercises.delete(sidebar_exercise_session.id);
return new Set(exercises); // Required for Svelte's reactivity
});
});
});
Expand All @@ -143,7 +161,9 @@
// @ts-ignore
.then((record: LabSessionsResponse) => {
toast.success("Lab stopped");
$sidebar_lab_session = record;
lab_sessions.update((lab_sessions) => {
return lab_sessions.map((lab_session) => {
if (lab_session.id === record.id) {
Expand All @@ -161,7 +181,10 @@
updateDataStores().catch((error) => {
toast.error(error);
});
$loadingLabs = $loadingLabs.filter((id) => id !== $sidebar_lab_session.id);
loadingLabs.update((labs) => {
labs.delete(lab_session_id);
return new Set(labs); // Required for Svelte's reactivity
});
});
}
</script>
Expand All @@ -181,9 +204,7 @@
</h2>
</div>
<div
class="badge badge-outline {$sidebar_lab_session.clusterRunning
? 'badge-success'
: ''}"
class="badge badge-outline {$sidebar_lab_session.clusterRunning ? 'badge-success' : ''}"
>
{#if $sidebar_lab_session.clusterRunning}
<Play class="w-4 h-4 mr-1 inline-block" />
Expand All @@ -194,17 +215,23 @@
</div>
<div class="grid grid-cols-1 gap-2 mt-4">
{#if !$sidebar_lab_session.clusterRunning}
<button class="btn btn-outline btn-success" on:click={() => startLab()}>
{#if $loadingLabs.includes($sidebar_lab_session.id)}
<button
class="btn btn-outline btn-success"
on:click={() => startLab($sidebar_lab_session.id)}
>
{#if $loadingLabs.has($sidebar_lab_session.id)}
<span class="loading loading-dots loading-md" />
{:else}
<Play class="w-5 h-5 mr-2 inline-block" />
Start lab
{/if}
</button>
{:else}
<button class="btn btn-outline btn-error" on:click={() => stopLab()}>
{#if $loadingLabs.includes($sidebar_lab_session.id)}
<button
class="btn btn-outline btn-error"
on:click={() => stopLab($sidebar_lab_session.id)}
>
{#if $loadingLabs.has($sidebar_lab_session.id)}
<span class="loading loading-dots loading-md" />
{:else}
<Pause class="w-5 h-5 mr-2 inline-block" />
Expand Down
68 changes: 42 additions & 26 deletions kubelab-ui/src/lib/components/labs/Exercise.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,8 @@
sidebar_lab,
sidebar_lab_session
} from "$lib/stores/sidebar";
import { getDeltaTime, getTimeAgo } from "$lib/utils/time";
import {
CheckCircle,
MoreHorizontal,
Pause,
Play,
Terminal,
TerminalSquare
} from "lucide-svelte";
import { getDeltaTime } from "$lib/utils/time";
import { CheckCircle, Info, MoreHorizontal, Pause, Play, Terminal } from "lucide-svelte";
import { onMount } from "svelte";
import toast from "svelte-french-toast";
export let this_exercise_session: ExerciseSessionsResponse;
Expand All @@ -56,7 +49,10 @@
agentRunning: false
};
$loadingExercises = $loadingExercises.concat(exercise_id);
loadingExercises.update((exercises) => {
exercises.add(exercise_id);
return new Set(exercises); // Required for Svelte's reactivity
});
// const labId = window.location.pathname.split("/")[2];
Expand Down Expand Up @@ -91,7 +87,10 @@
toast.error(error.message);
})
.finally(() => {
$loadingExercises = $loadingExercises.filter((id) => id !== exercise_id);
loadingExercises.update((exercises) => {
exercises.delete(exercise_id);
return new Set(exercises); // Required for Svelte's reactivity
});
});
}
}
Expand All @@ -106,7 +105,10 @@
agentRunning: true
};
$loadingExercises = $loadingExercises.concat(exercise_id);
loadingExercises.update((exercises) => {
exercises.add(exercise_id);
return new Set(exercises); // Required for Svelte's reactivity
});
// const labId = window.location.pathname.split("/")[2];
Expand All @@ -117,7 +119,6 @@
.update(exercise_session_id, data)
// @ts-ignore
.then((response: any) => {
// goto(`/labs/${labId}/${exercise_id}`);
toast.success("Exercise started");
this_exercise_session = response;
$sidebar_exercise_sessions = $sidebar_exercise_sessions.map((exercise_session) => {
Expand Down Expand Up @@ -150,7 +151,7 @@
.collection("exercise_session_logs")
.create(exercise_session_log_data)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
Expand All @@ -160,7 +161,10 @@
toast.error(error.message);
})
.finally(() => {
$loadingExercises = $loadingExercises.filter((id) => id !== exercise_id);
loadingExercises.update((exercises) => {
exercises.delete(exercise_id);
return new Set(exercises); // Required for Svelte's reactivity
});
});
}
}
Expand All @@ -175,10 +179,20 @@
{#if $sidebar_lab_session.clusterRunning}
<div class="relative ml-auto dropdown dropdown-end dropdown-bottom">
<button class="btn btn-neutral flex justify-center items-center relative">
{#if $loadingExercises.includes(this_exercise.id)}
<span
class="capitalize"
>Actions</span> <span class="loading loading-dots loading-sm inline-block p-2" />
{#if $loadingExercises.has(this_exercise.id)}
<span class="capitalize">Actions</span>
<span class="loading loading-dots loading-sm inline-block p-2" />
<ul class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52 gap-2">
<li>
<!-- exercise is starting... -->
<button
class="border-2 "
>
<Info class="w-4 h-4 mr-1 inline-block" />
Starting Exercise</button
>
</li>
</ul>
{:else}
<button class="-m-3 block p-2.5">
Actions <MoreHorizontal class="w-6 h-6 inline-block" strokeWidth={3} />
Expand All @@ -202,14 +216,20 @@
</li>
{#if this_exercise_session.agentRunning}
<li>
<button class="border-2 text-error border-error hover:bg-error hover:text-primary" on:click={() => stopExercise(this_exercise.id)}>
<button
class="border-2 text-error border-error hover:bg-error hover:text-primary"
on:click={() => stopExercise(this_exercise.id)}
>
<Pause class="w-4 h-4 mr-1 inline-block" />
Stop Exercise</button
>
</li>
{:else}
<li>
<button class="border-2 text-success border-success hover:bg-success hover:text-primary" on:click={() => startExercise(this_exercise.id)}>
<button
class="border-2 text-success border-success hover:bg-success hover:text-primary"
on:click={() => startExercise(this_exercise.id)}
>
<Play class="w-4 h-4 mr-1 inline-block" />
Start Exercise</button
>
Expand All @@ -234,11 +254,7 @@
<dl class="-my-3 divide-y divide-gray-100 px-6 py-4 text-sm leading-6">
<div class="flex justify-between gap-x-4 py-3">
<dt class="">Status</dt>
<dd
class="badge badge-outline {this_exercise_session.agentRunning
? 'badge-success'
: ''}"
>
<dd class="badge badge-outline {this_exercise_session.agentRunning ? 'badge-success' : ''}">
{#if this_exercise_session.agentRunning}
<Play class="w-4 h-4 mr-1 inline-block" />
{:else}
Expand Down
Loading

0 comments on commit 36a87e3

Please sign in to comment.