Skip to content

Commit 45d250f

Browse files
committed
Pull startup script logs on frontend
1 parent 1cc3e9d commit 45d250f

File tree

6 files changed

+66
-2
lines changed

6 files changed

+66
-2
lines changed

site/src/api/api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,15 @@ export const getAgentListeningPorts = async (
773773
return response.data
774774
}
775775

776+
export const getStartupScriptLogs = async (
777+
workspaceBuildId: string,
778+
): Promise<TypesGen.StartupScriptLog[]> => {
779+
const response = await axios.get(
780+
`/api/v2/workspacebuilds/${workspaceBuildId}/startup-script-logs`,
781+
)
782+
return response.data
783+
}
784+
776785
export const getDeploymentConfig =
777786
async (): Promise<TypesGen.DeploymentConfig> => {
778787
const response = await axios.get(`/api/v2/config/deployment`)

site/src/components/Workspace/Workspace.stories.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,13 @@ CancellationError.args = {
132132
}),
133133
},
134134
}
135+
136+
export const StartupLogsError = Template.bind({})
137+
StartupLogsError.args = {
138+
StartupLogs: new Error("Unable to fetch startup logs"),
139+
}
140+
141+
export const StartupLogs = Template.bind({})
142+
StartupLogs.args = {
143+
StartupLogs: [{ agent_id: "agent", job_id: "job", output: "startup logs" }],
144+
}

site/src/components/Workspace/Workspace.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { makeStyles } from "@material-ui/core/styles"
22
import { WorkspaceStatusBadge } from "components/WorkspaceStatusBadge/WorkspaceStatusBadge"
3-
import { FC } from "react"
3+
import { FC, useEffect, useState } from "react"
44
import { useNavigate } from "react-router-dom"
55
import * as TypesGen from "../../api/typesGenerated"
66
import { BuildsTable } from "../BuildsTable/BuildsTable"
@@ -24,6 +24,7 @@ import {
2424
} from "components/WorkspaceBuildProgress/WorkspaceBuildProgress"
2525
import { AgentRow } from "components/Resources/AgentRow"
2626
import { Avatar } from "components/Avatar/Avatar"
27+
import { CodeBlock } from "components/CodeBlock/CodeBlock"
2728

2829
export enum WorkspaceErrors {
2930
GET_RESOURCES_ERROR = "getResourcesError",
@@ -60,6 +61,7 @@ export interface WorkspaceProps {
6061
template?: TypesGen.Template
6162
templateParameters?: TypesGen.TemplateVersionParameter[]
6263
quota_budget?: number
64+
startupScriptLogs?: TypesGen.StartupScriptLog[] | Error | unknown
6365
}
6466

6567
/**
@@ -87,6 +89,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
8789
template,
8890
templateParameters,
8991
quota_budget,
92+
startupScriptLogs,
9093
}) => {
9194
const { t } = useTranslation("workspacePage")
9295
const styles = useStyles()
@@ -233,6 +236,19 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
233236
/>
234237
)}
235238

239+
{typeof startupScriptLogs !== "undefined" &&
240+
(Array.isArray(startupScriptLogs) ? (
241+
startupScriptLogs.map((log) => (
242+
<CodeBlock
243+
key={log.agent_id}
244+
className={styles.logs}
245+
lines={log.output ? log.output.split("\n") : "No output"}
246+
/>
247+
))
248+
) : (
249+
<AlertBanner severity="error" error={startupScriptLogs} />
250+
))}
251+
236252
{workspaceErrors[WorkspaceErrors.GET_BUILDS_ERROR] ? (
237253
<AlertBanner
238254
severity="error"
@@ -279,5 +295,8 @@ export const useStyles = makeStyles((theme) => {
279295
timelineContents: {
280296
margin: 0,
281297
},
298+
logs: {
299+
border: `1px solid ${theme.palette.divider}`,
300+
},
282301
}
283302
})

site/src/pages/WorkspacePage/WorkspacePage.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { makeStyles } from "@material-ui/core/styles"
22
import { useMachine } from "@xstate/react"
3+
import * as API from "api/api"
34
import { AlertBanner } from "components/AlertBanner/AlertBanner"
45
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"
5-
import { FC, useEffect } from "react"
6+
import { FC, useEffect, useState } from "react"
67
import { useParams } from "react-router-dom"
78
import { Loader } from "components/Loader/Loader"
89
import { firstOrItem } from "util/array"
@@ -27,6 +28,10 @@ export const WorkspacePage: FC = () => {
2728
const { getQuotaError } = quotaState.context
2829
const styles = useStyles()
2930

31+
const [startupScriptLogs, setStartupScriptLogs] = useState<
32+
Record<string, string> | Error | undefined | unknown
33+
>(undefined)
34+
3035
/**
3136
* Get workspace, template, and organization on mount and whenever workspaceId changes.
3237
* workspaceSend should not change.
@@ -41,6 +46,22 @@ export const WorkspacePage: FC = () => {
4146
username && quotaSend({ type: "GET_QUOTA", username })
4247
}, [username, quotaSend])
4348

49+
// Get startup logs once we have agents or when the agents change.
50+
// TODO: Should use xstate? Or that new thing?
51+
// TODO: Does not stream yet.
52+
// TODO: Should maybe add to the existing SSE endpoint instead?
53+
useEffect(() => {
54+
if (workspace?.latest_build) {
55+
API.getStartupScriptLogs(workspace.latest_build.id)
56+
.then((logs) => {
57+
setStartupScriptLogs(logs)
58+
})
59+
.catch((error) => {
60+
setStartupScriptLogs(error)
61+
})
62+
}
63+
}, [workspace])
64+
4465
return (
4566
<ChooseOne>
4667
<Cond condition={workspaceState.matches("error")}>
@@ -76,6 +97,7 @@ export const WorkspacePage: FC = () => {
7697
workspaceState={workspaceState}
7798
quotaState={quotaState}
7899
workspaceSend={workspaceSend}
100+
startupScriptLogs={startupScriptLogs}
79101
/>
80102
</Cond>
81103
<Cond>

site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ interface WorkspaceReadyPageProps {
3030
workspaceState: StateFrom<typeof workspaceMachine>
3131
quotaState: StateFrom<typeof quotaMachine>
3232
workspaceSend: (event: WorkspaceEvent) => void
33+
startupScriptLogs?: Record<string, string> | Error
3334
}
3435

3536
export const WorkspaceReadyPage = ({
3637
workspaceState,
3738
quotaState,
3839
workspaceSend,
40+
startupScriptLogs,
3941
}: WorkspaceReadyPageProps): JSX.Element => {
4042
const [_, bannerSend] = useActor(
4143
workspaceState.children["scheduleBannerMachine"],
@@ -129,6 +131,7 @@ export const WorkspaceReadyPage = ({
129131
template={template}
130132
templateParameters={templateParameters}
131133
quota_budget={quotaState.context.quota?.budget}
134+
startupScriptLogs={startupScriptLogs}
132135
/>
133136
<DeleteDialog
134137
entity="workspace"

site/src/xServices/workspace/workspaceXService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ export const workspaceMachine = createMachine(
751751
checkRefresh: true,
752752
data: JSON.parse(event.data),
753753
})
754+
// refresh
754755
})
755756

756757
// handle any error events returned by our sse

0 commit comments

Comments
 (0)