mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
+4
@@ -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
@@ -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: []
|
||||
|
||||
Generated
+3
@@ -8209,6 +8209,9 @@ const docTemplate = `{
|
||||
"verbose": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"web_terminal_renderer": {
|
||||
"type": "string"
|
||||
},
|
||||
"wgtunnel_host": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
Generated
+3
@@ -7347,6 +7347,9 @@
|
||||
"verbose": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"web_terminal_renderer": {
|
||||
"type": "string"
|
||||
},
|
||||
"wgtunnel_host": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Generated
+1
@@ -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,
|
||||
|
||||
Generated
+3
@@ -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 | | |
|
||||
|
||||
Generated
+11
@@ -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
|
||||
|
||||
| | |
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 />} />
|
||||
|
||||
Generated
+1
@@ -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",
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user