feat: support configurable web terminal rendering (#10095)

* feat: support configurable web terminal rendering

- Added a deployment option for configuring web terminal rendering.
  Valid values are 'webgl', 'canvas', and 'dom'.
This commit is contained in:
Jon Ayers
2023-10-10 13:18:02 -05:00
committed by GitHub
parent 05a393cd06
commit 91555c3a85
14 changed files with 59 additions and 10 deletions
+4
View File
@@ -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.
+4
View File
@@ -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: []
+3
View File
@@ -8209,6 +8209,9 @@ const docTemplate = `{
"verbose": {
"type": "boolean"
},
"web_terminal_renderer": {
"type": "string"
},
"wgtunnel_host": {
"type": "string"
},
+3
View File
@@ -7347,6 +7347,9 @@
"verbose": {
"type": "boolean"
},
"web_terminal_renderer": {
"type": "string"
},
"wgtunnel_host": {
"type": "string"
},
+12
View File
@@ -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"`
@@ -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
}
+1
View File
@@ -389,6 +389,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
"default_schedule": "string"
},
"verbose": true,
"web_terminal_renderer": "string",
"wgtunnel_host": "string",
"wildcard_access_url": {
"forceQuery": true,
+3
View File
@@ -2246,6 +2246,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
"default_schedule": "string"
},
"verbose": true,
"web_terminal_renderer": "string",
"wgtunnel_host": "string",
"wildcard_access_url": {
"forceQuery": true,
@@ -2614,6 +2615,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
"default_schedule": "string"
},
"verbose": true,
"web_terminal_renderer": "string",
"wgtunnel_host": "string",
"wildcard_access_url": {
"forceQuery": true,
@@ -2687,6 +2689,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
| `update_check` | boolean | false | | |
| `user_quiet_hours_schedule` | [codersdk.UserQuietHoursScheduleConfig](#codersdkuserquiethoursscheduleconfig) | false | | |
| `verbose` | boolean | false | | |
| `web_terminal_renderer` | string | false | | |
| `wgtunnel_host` | string | false | | |
| `wildcard_access_url` | [clibase.URL](#clibaseurl) | false | | |
| `write_config` | boolean | false | | |
+11
View File
@@ -997,6 +997,17 @@ Enables trace exporting to Honeycomb.io using the provided API Key.
Periodically check for new releases of Coder and inform the owner. The check is performed once per day.
### --web-terminal-renderer
| | |
| ----------- | ----------------------------------------- |
| Type | <code>string</code> |
| Environment | <code>$CODER_WEB_TERMINAL_RENDERER</code> |
| YAML | <code>client.webTerminalRenderer</code> |
| Default | <code>canvas</code> |
The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'.
### --wildcard-access-url
| | |
+4
View File
@@ -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.
+1
View File
@@ -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,
+1 -1
View File
@@ -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 />} />
+1
View File
@@ -404,6 +404,7 @@ export interface DeploymentValues {
readonly proxy_health_status_interval?: number;
readonly enable_terraform_debug_mode?: boolean;
readonly user_quiet_hours_schedule?: UserQuietHoursScheduleConfig;
readonly web_terminal_renderer?: string;
readonly config?: string;
readonly write_config?: boolean;
readonly address?: string;
@@ -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",
});
+10 -8
View File
@@ -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";
@@ -28,6 +29,8 @@ import {
LoadedScriptsAlert,
LoadingScriptsAlert,
} from "./TerminalAlerts";
import { useQuery } from "react-query";
import { deploymentConfig } from "api/queries/deployment";
export const Language = {
workspaceErrorMessagePrefix: "Unable to fetch workspace: ",
@@ -35,11 +38,7 @@ export const Language = {
websocketErrorMessagePrefix: "WebSocket failed: ",
};
type TerminalPageProps = React.PropsWithChildren<{
renderer: "webgl" | "dom";
}>;
const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
const TerminalPage: FC = () => {
const navigate = useNavigate();
const styles = useStyles();
const { proxy } = useProxy();
@@ -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) => {
@@ -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);
@@ -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