Propagate executor OS into turn environments (#41207)

## What changed

- Add the optional `platformOs` field to exec-server environment metadata, with
  local exec servers reporting `std::env::consts::OS` and legacy servers
  remaining compatible when the field is absent.
- Preserve the reported OS in each selected turn environment, including the
  local environment.

## Testing

- Extend protocol serialization and environment-selection coverage for remote
  and local platform values.

GitOrigin-RevId: 0f325f6cb83cd8f8c7ec1ce2a4041f45a29e8f38
This commit is contained in:
iceweasel-oai authored and copyberry committed 2026-08-27 21:05:40 +00:00
1 parent 7f135e1314
commit 19321435b1
3 files changed
+26

No files matched your search

@@ -138,6 +138,7 @@ struct ResolvedEnvironment {
environment: Arc<Environment>,
shell: Option<Shell>,
user_home_dir: Option<PathUri>,
executor_platform_os: Option<String>,
temporary_directories: Option<Vec<PathUri>>,
shell_snapshot: ShellSnapshotTask,
shell_snapshot_v2_supported: bool,
@@ -259,6 +260,7 @@ impl ThreadEnvironments {
environment: environment.environment,
shell: environment.shell,
user_home_dir: environment.user_home_dir,
executor_platform_os: environment.executor_platform_os,
temporary_directories: environment.temporary_directories,
shell_snapshot: environment.shell_snapshot,
shell_snapshot_v2_supported: environment.shell_snapshot_v2_supported,
@@ -625,9 +627,11 @@ impl ThreadEnvironments {
};
// Resolve the attachment only after both prerequisites are ready.
let ((), installed_config) = tokio::try_join!(connection_ready, configuration_ready)?;
let executor_platform_os;
let (shell, user_home_dir, temporary_dirs, snapshot_v2) = if environment.is_remote() {
match environment.info().await {
Ok(info) => {
executor_platform_os = info.platform_os;
let user_home_dir = info.user_home_dir;
let temporary_directories = info.temporary_directories;
let shell_snapshot_v2_supported = info.capabilities.shell_snapshot_v2;
@@ -648,11 +652,13 @@ impl ThreadEnvironments {
)
}
Err(err) => {
executor_platform_os = None;
tracing::warn!("failed to get info for environment `{environment_id}`: {err}");
(None, None, None, false)
}
}
} else {
executor_platform_os = Some(std::env::consts::OS.to_string());
(
Some(local_shell),
PathUri::from_host_native_path("~").ok(),
@@ -671,6 +677,7 @@ impl ThreadEnvironments {
environment,
shell,
user_home_dir,
executor_platform_os,
temporary_directories: temporary_dirs,
shell_snapshot: task,
shell_snapshot_v2_supported: snapshot_v2,
@@ -748,6 +755,7 @@ impl TurnEnvironmentState {
environment.environment,
environment.shell,
);
turn_environment.executor_platform_os = environment.executor_platform_os;
turn_environment.shell_snapshot = environment.shell_snapshot;
turn_environment.shell_snapshot_v2_supported =
environment.shell_snapshot_v2_supported;
@@ -1029,6 +1037,7 @@ mod tests {
"result": {
"shell": { "name": "zsh", "path": "/bin/zsh" },
"userHomeDir": "file:///home/remote",
"platformOs": "windows",
"temporaryDirectories": ["file:///tmp/remote"],
}
})
@@ -1483,6 +1492,13 @@ url = "ws://127.0.0.1:8765"
.collect::<Vec<_>>(),
vec![expected_config.clone(), expected_config]
);
assert_eq!(
attached
.turn_environments()
.map(|environment| environment.executor_platform_os.as_deref())
.collect::<Vec<_>>(),
vec![Some("windows"), Some(std::env::consts::OS)]
);
assert_eq!(attached.to_selections(), vec![remote, local]);
let environment = attached.primary().expect("remote environment");
let expected_user_home_dir = PathUri::parse("file:///home/remote").expect("remote home");
@@ -53,6 +53,8 @@ pub(crate) struct TurnEnvironment {
/// Cached from the selected executor; `None` means it did not report them.
pub(crate) temporary_directories: Option<Vec<PathUri>>,
pub(crate) shell: Option<shell::Shell>,
/// OS reported by the selected executor; `None` for legacy executors.
pub(crate) executor_platform_os: Option<String>,
pub(crate) shell_snapshot: ShellSnapshotTask,
pub(crate) shell_snapshot_v2_supported: bool,
}
@@ -72,6 +74,7 @@ impl TurnEnvironment {
user_home_dir: None,
temporary_directories: None,
shell,
executor_platform_os: None,
shell_snapshot: futures::future::ready(None).boxed().shared(),
shell_snapshot_v2_supported: false,
}
@@ -172,6 +175,7 @@ impl std::fmt::Debug for TurnEnvironment {
.field("user_home_dir", &self.user_home_dir)
.field("temporary_directories", &self.temporary_directories)
.field("shell", &self.shell)
.field("executor_platform_os", &self.executor_platform_os)
.field("config", self.config())
.field("config_origin", &self.config_origin)
.finish_non_exhaustive()