diff --git a/build.assets/macos/tsh/tsh.app/Contents/Library/LaunchDaemons/com.gravitational.teleport.tsh.vnetd.plist b/build.assets/macos/tsh/tsh.app/Contents/Library/LaunchDaemons/com.gravitational.teleport.tsh.vnetd.plist
index 5bd6b0884a1ce..6ee39856cb2af 100644
--- a/build.assets/macos/tsh/tsh.app/Contents/Library/LaunchDaemons/com.gravitational.teleport.tsh.vnetd.plist
+++ b/build.assets/macos/tsh/tsh.app/Contents/Library/LaunchDaemons/com.gravitational.teleport.tsh.vnetd.plist
@@ -22,5 +22,12 @@
/var/log/vnet.log
ThrottleInterval
5
+ EnvironmentVariables
+
+
+ TELEPORT_TOOLS_VERSION
+ off
+
diff --git a/build.assets/macos/tshdev/tsh.app/Contents/Library/LaunchDaemons/com.goteleport.tshdev.vnetd.plist b/build.assets/macos/tshdev/tsh.app/Contents/Library/LaunchDaemons/com.goteleport.tshdev.vnetd.plist
index 8b51b2a044191..90d6139ac96ad 100644
--- a/build.assets/macos/tshdev/tsh.app/Contents/Library/LaunchDaemons/com.goteleport.tshdev.vnetd.plist
+++ b/build.assets/macos/tshdev/tsh.app/Contents/Library/LaunchDaemons/com.goteleport.tshdev.vnetd.plist
@@ -22,5 +22,12 @@
/var/log/vnet.log
ThrottleInterval
5
+ EnvironmentVariables
+
+
+ TELEPORT_TOOLS_VERSION
+ off
+
diff --git a/web/packages/teleterm/src/mainProcess/mainProcess.ts b/web/packages/teleterm/src/mainProcess/mainProcess.ts
index 665fa2cccc357..2987f4e5c7dc9 100644
--- a/web/packages/teleterm/src/mainProcess/mainProcess.ts
+++ b/web/packages/teleterm/src/mainProcess/mainProcess.ts
@@ -53,6 +53,10 @@ import * as grpcCreds from 'teleterm/services/grpcCredentials';
import { createTshdClient, TshdClient } from 'teleterm/services/tshd';
import { loggingInterceptor } from 'teleterm/services/tshd/interceptors';
import { staticConfig } from 'teleterm/staticConfig';
+import {
+ TSH_AUTOUPDATE_ENV_VAR,
+ TSH_AUTOUPDATE_OFF,
+} from 'teleterm/node/tshAutoupdate';
import {
ConfigService,
@@ -188,6 +192,7 @@ export default class MainProcess {
env: {
...process.env,
TELEPORT_HOME: homeDir,
+ [TSH_AUTOUPDATE_ENV_VAR]: TSH_AUTOUPDATE_OFF,
},
}
);
diff --git a/web/packages/teleterm/src/node/README.md b/web/packages/teleterm/src/node/README.md
new file mode 100644
index 0000000000000..28ea74a4d8d5c
--- /dev/null
+++ b/web/packages/teleterm/src/node/README.md
@@ -0,0 +1,2 @@
+Files in this directory are executed within a Node.js process, be it the main process or the shared
+process.
diff --git a/web/packages/teleterm/src/node/tshAutoupdate.ts b/web/packages/teleterm/src/node/tshAutoupdate.ts
new file mode 100644
index 0000000000000..8ac6d73d9b8b2
--- /dev/null
+++ b/web/packages/teleterm/src/node/tshAutoupdate.ts
@@ -0,0 +1,27 @@
+/**
+ * Teleport
+ * Copyright (C) 2024 Gravitational, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * An env var which controls whether tsh is going to download an up-to-date version of itself
+ * to ~/.tsh/bin and re-execute itself. In Connect, we always want it to be set to 'off', as Connect
+ * needs to use the bundled tsh where the version of tsh matches exactly the version of Connect.
+ *
+ * See RFD 144 for more details.
+ */
+export const TSH_AUTOUPDATE_ENV_VAR = 'TELEPORT_TOOLS_VERSION';
+export const TSH_AUTOUPDATE_OFF = 'off';
diff --git a/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.test.ts b/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.test.ts
index 1b910e59c94b0..4c3ccc926f40e 100644
--- a/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.test.ts
+++ b/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.test.ts
@@ -331,7 +331,7 @@ describe('buildPtyOptions', () => {
});
expect(processOptions.env.WSLENV).toBe(
- 'CUSTOM_VAR:TERM_PROGRAM:TERM_PROGRAM_VERSION:TELEPORT_CLUSTER:TELEPORT_PROXY:TELEPORT_HOME/p:KUBECONFIG/p'
+ 'CUSTOM_VAR:KUBECONFIG/p:TERM_PROGRAM:TERM_PROGRAM_VERSION:TELEPORT_CLUSTER:TELEPORT_PROXY:TELEPORT_HOME/p:TELEPORT_TOOLS_VERSION'
);
});
});
diff --git a/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.ts b/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.ts
index 0019f255ee44a..d73f888ebefb0 100644
--- a/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.ts
+++ b/web/packages/teleterm/src/services/pty/ptyHost/buildPtyOptions.ts
@@ -21,9 +21,12 @@ import path, { delimiter } from 'path';
import { RuntimeSettings } from 'teleterm/mainProcess/types';
import { PtyProcessOptions } from 'teleterm/sharedProcess/ptyHost';
import { assertUnreachable } from 'teleterm/ui/utils';
-
import { Shell, makeCustomShellFromPath } from 'teleterm/mainProcess/shell';
import { CUSTOM_SHELL_ID } from 'teleterm/services/config/appConfigSchema';
+import {
+ TSH_AUTOUPDATE_ENV_VAR,
+ TSH_AUTOUPDATE_OFF,
+} from 'teleterm/node/tshAutoupdate';
import {
PtyCommand,
@@ -92,6 +95,9 @@ export async function buildPtyOptions({
throw error;
})
.then(({ shellEnv, creationStatus }) => {
+ // combinedEnv is going to be used as env by every command coming out of buildPtyOptions. Some
+ // commands might add extra variables, but they shouldn't remove any of the env vars that are
+ // added here.
const combinedEnv = {
...processEnv,
...shellEnv,
@@ -100,6 +106,7 @@ export async function buildPtyOptions({
TELEPORT_HOME: settings.tshd.homeDir,
TELEPORT_CLUSTER: cmd.clusterName,
TELEPORT_PROXY: cmd.proxyHost,
+ [TSH_AUTOUPDATE_ENV_VAR]: TSH_AUTOUPDATE_OFF,
};
// The regular env vars are not available in WSL,
@@ -108,12 +115,13 @@ export async function buildPtyOptions({
// https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/
if (settings.platform === 'win32' && shell.binName === 'wsl.exe') {
const wslEnv = [
+ 'KUBECONFIG/p',
'TERM_PROGRAM',
'TERM_PROGRAM_VERSION',
'TELEPORT_CLUSTER',
'TELEPORT_PROXY',
'TELEPORT_HOME/p',
- 'KUBECONFIG/p',
+ TSH_AUTOUPDATE_ENV_VAR,
];
// Preserve the user defined WSLENV and add ours (ours takes precedence).
combinedEnv[WSLENV_VAR] = [combinedEnv[WSLENV_VAR], wslEnv]