Skip to content

feat: support configurable web terminal rendering #10095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 10, 2023
Merged
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
4 changes: 4 additions & 0 deletions cli/testdata/coder_server_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ Clients include the coder cli, vs code extension, and the web UI.
--ssh-hostname-prefix string, $CODER_SSH_HOSTNAME_PREFIX (default: coder.)
The SSH deployment prefix is used in the Host of the ssh config.

--web-terminal-renderer string, $CODER_WEB_TERMINAL_RENDERER (default: canvas)
The renderer to use when opening a web terminal. Valid values are
'canvas', 'webgl', or 'dom'.

CONFIG OPTIONS:
Use a YAML configuration file when your server launch become unwieldy.

Expand Down
4 changes: 4 additions & 0 deletions cli/testdata/server-config.yaml.golden
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,10 @@ client:
# incorrectly can break SSH to your deployment, use cautiously.
# (default: <unset>, type: string-array)
sshConfigOptions: []
# The renderer to use when opening a web terminal. Valid values are 'canvas',
# 'webgl', or 'dom'.
# (default: canvas, type: string)
webTerminalRenderer: canvas
# Support links to display in the top right drop down menu.
# (default: <unset>, type: struct[[]codersdk.LinkConfig])
supportLinks: []
Expand Down
3 changes: 3 additions & 0 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions codersdk/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ type DeploymentValues struct {
ProxyHealthStatusInterval clibase.Duration `json:"proxy_health_status_interval,omitempty" typescript:",notnull"`
EnableTerraformDebugMode clibase.Bool `json:"enable_terraform_debug_mode,omitempty" typescript:",notnull"`
UserQuietHoursSchedule UserQuietHoursScheduleConfig `json:"user_quiet_hours_schedule,omitempty" typescript:",notnull"`
WebTerminalRenderer clibase.String `json:"web_terminal_renderer,omitempty" typescript:",notnull"`

Config clibase.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"`
WriteConfig clibase.Bool `json:"write_config,omitempty" typescript:",notnull"`
Expand Down Expand Up @@ -1762,7 +1763,18 @@ Write out the current server config as YAML to stdout.`,
Group: &deploymentGroupUserQuietHoursSchedule,
YAML: "defaultQuietHoursSchedule",
},
{
Name: "Web Terminal Renderer",
Description: "The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'.",
Flag: "web-terminal-renderer",
Env: "CODER_WEB_TERMINAL_RENDERER",
Default: "canvas",
Value: &c.WebTerminalRenderer,
Group: &deploymentGroupClient,
YAML: "webTerminalRenderer",
},
}

return opts
}

Expand Down
1 change: 1 addition & 0 deletions docs/api/general.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions docs/api/schemas.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions docs/cli/server.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions enterprise/cli/testdata/coder_server_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Clients include the coder cli, vs code extension, and the web UI.
--ssh-hostname-prefix string, $CODER_SSH_HOSTNAME_PREFIX (default: coder.)
The SSH deployment prefix is used in the Host of the ssh config.

--web-terminal-renderer string, $CODER_WEB_TERMINAL_RENDERER (default: canvas)
The renderer to use when opening a web terminal. Valid values are
'canvas', 'webgl', or 'dom'.

CONFIG OPTIONS:
Use a YAML configuration file when your server launch become unwieldy.

Expand Down
1 change: 1 addition & 0 deletions site/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default defineConfig({
`--dangerous-disable-rate-limits ` +
`--provisioner-daemons 10 ` +
`--provisioner-daemons-echo ` +
`--web-terminal-renderer=dom ` +
`--pprof-enable`,
env: {
...process.env,
Expand Down
2 changes: 1 addition & 1 deletion site/src/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ export const AppRouter: FC = () => {
{/* Terminal and CLI auth pages don't have the dashboard layout */}
<Route
path="/:username/:workspace/terminal"
element={<TerminalPage renderer="webgl" />}
element={<TerminalPage />}
/>
<Route path="/cli-auth" element={<CliAuthenticationPage />} />
<Route path="/icons" element={<IconsPage />} />
Expand Down
1 change: 1 addition & 0 deletions site/src/api/typesGenerated.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion site/src/pages/TerminalPage/TerminalPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Object.defineProperty(window, "TextEncoder", {
const renderTerminal = async (
route = `/${MockUser.username}/${MockWorkspace.name}/terminal`,
) => {
const utils = renderWithAuth(<TerminalPage renderer="dom" />, {
const utils = renderWithAuth(<TerminalPage />, {
route,
path: "/:username/:workspace/terminal",
});
Expand Down
18 changes: 10 additions & 8 deletions site/src/pages/TerminalPage/TerminalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { colors } from "theme/colors";
import { v4 as uuidv4 } from "uuid";
import * as XTerm from "xterm";
import { WebglAddon } from "xterm-addon-webgl";
import { CanvasAddon } from "xterm-addon-canvas";
import { FitAddon } from "xterm-addon-fit";
import { WebLinksAddon } from "xterm-addon-web-links";
import { Unicode11Addon } from "xterm-addon-unicode11";
Expand All @@ -28,18 +29,16 @@ import {
LoadedScriptsAlert,
LoadingScriptsAlert,
} from "./TerminalAlerts";
import { useQuery } from "react-query";
import { deploymentConfig } from "api/queries/deployment";

export const Language = {
workspaceErrorMessagePrefix: "Unable to fetch workspace: ",
workspaceAgentErrorMessagePrefix: "Unable to fetch workspace agent: ",
websocketErrorMessagePrefix: "WebSocket failed: ",
};

type TerminalPageProps = React.PropsWithChildren<{
renderer: "webgl" | "dom";
}>;

const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
const TerminalPage: FC = () => {
Copy link
Member

Choose a reason for hiding this comment

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

I think we are getting a test failure because the test looks for HTML elements so it relies on the dom renderer being used (see webTerminal.spec.ts). Maybe we can start the e2e tests with dom set as the renderer? Looks like we would do that in playwright.config.ts if I understand correctly.

const navigate = useNavigate();
const styles = useStyles();
const { proxy } = useProxy();
Expand Down Expand Up @@ -101,6 +100,8 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
prevLifecycleState.current = lifecycleState;
}, [lifecycleState]);

const config = useQuery(deploymentConfig());

// handleWebLink handles opening of URLs in the terminal!
const handleWebLink = useCallback(
(uri: string) => {
Expand Down Expand Up @@ -166,9 +167,10 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
background: colors.gray[16],
},
});
// DOM is the default renderer.
if (renderer === "webgl") {
if (config.data?.config.web_terminal_renderer === "webgl") {
terminal.loadAddon(new WebglAddon());
} else if (config.data?.config.web_terminal_renderer === "canvas") {
terminal.loadAddon(new CanvasAddon());
}
const fitAddon = new FitAddon();
setFitAddon(fitAddon);
Expand Down Expand Up @@ -208,7 +210,7 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
window.removeEventListener("resize", listener);
terminal.dispose();
};
}, [renderer, sendEvent, xtermRef, handleWebLink]);
}, [config.data, sendEvent, xtermRef, handleWebLink]);

// Triggers the initial terminal connection using
// the reconnection token and workspace name found
Expand Down