From aff1c1b7840fba6ceb6a287b7707336818cbdbc6 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Fri, 21 Aug 2026 06:56:11 +0000 Subject: [PATCH 1/8] feat(sandbox): support rootfs tar as --from source for VM driver Accept flat rootfs tar archives (.tar, .tar.gz, .tgz) via the --from flag for VM-backed gateways. The CLI detects the archive extension, validates that the gateway uses the VM compute driver, and passes the tar path through driver_config. The VM driver copies the tar into its staging area and feeds it into the existing rootfs extraction and ext4 disk creation pipeline, skipping the container image pull/export steps. Closes #2175 Signed-off-by: Philippe Martin --- crates/openshell-cli/src/main.rs | 8 +- crates/openshell-cli/src/run.rs | 239 ++++++++++++++++++++--- crates/openshell-driver-vm/src/driver.rs | 161 +++++++++++++-- docs/sandboxes/manage-sandboxes.mdx | 9 +- e2e/rust/Cargo.toml | 5 + e2e/rust/tests/rootfs_tar.rs | 116 +++++++++++ 6 files changed, 497 insertions(+), 41 deletions(-) create mode 100644 e2e/rust/tests/rootfs_tar.rs diff --git a/crates/openshell-cli/src/main.rs b/crates/openshell-cli/src/main.rs index befac54759..ac3fd1c70d 100644 --- a/crates/openshell-cli/src/main.rs +++ b/crates/openshell-cli/src/main.rs @@ -1356,15 +1356,17 @@ enum SandboxCommands { template: Option, /// Sandbox source: a community sandbox name (e.g., `ollama`), a path - /// to a Dockerfile or directory containing one, or a full container - /// image reference (e.g., `myregistry.com/img:tag`). + /// to a Dockerfile or directory containing one, a rootfs tar archive + /// (`.tar`, `.tar.gz`, or `.tgz`), or a full container image reference + /// (e.g., `myregistry.com/img:tag`). /// /// Community names are resolved to /// `ghcr.io/nvidia/openshell-community/sandboxes/:latest` /// (override the prefix with `OPENSHELL_COMMUNITY_REGISTRY`). /// /// When given a Dockerfile or directory, the image is built into the - /// local Docker daemon before creating the sandbox. + /// local Docker daemon before creating the sandbox. When given a + /// rootfs tar, it is passed directly to the VM compute driver. #[arg(long, value_hint = ValueHint::AnyPath)] from: Option, diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index 78a794aa30..62d73762f6 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -48,7 +48,7 @@ use openshell_core::proto::{ CreateSandboxRequest, CreateSandboxTemplateRequest, CreateSshSessionRequest, DeleteInferenceRouteRequest, DeleteSandboxRequest, DeleteSandboxTemplateRequest, DeleteServiceRequest, ExecSandboxRequest, ExposeServiceRequest, GetCurrentUserRequest, - GetDraftHistoryRequest, GetDraftPolicyRequest, GetGatewayConfigRequest, + GetDraftHistoryRequest, GetDraftPolicyRequest, GetGatewayConfigRequest, GetGatewayInfoRequest, GetInferenceRouteRequest, GetSandboxConfigRequest, GetSandboxConfigResponse, GetSandboxLogsRequest, GetSandboxPolicyStatusRequest, GetSandboxRequest, GetSandboxTemplateRequest, GetServiceRequest, GpuResourceRequirements, @@ -526,27 +526,32 @@ pub async fn sandbox_create( } // Resolve the --from flag into a container image reference, building from - // a Dockerfile first if necessary. Template creates resolve workload shape - // on the gateway and skip local image handling. - let image: Option = if template.is_some() { - None + // a Dockerfile first if necessary, or a rootfs tar path for the VM driver. + // Template creates resolve workload shape on the gateway and skip local + // image handling. + let (image, rootfs_tar_path): (Option, Option) = if template.is_some() { + (None, None) } else { match from { Some(val) => { let resolved = resolve_from(val)?; match resolved { - ResolvedSource::Image(img) => Some(img), + ResolvedSource::Image(img) => (Some(img), None), ResolvedSource::Dockerfile { dockerfile, context, } => { let tag = build_from_dockerfile(&dockerfile, &context, gateway_name).await?; - Some(tag) + (Some(tag), None) + } + ResolvedSource::RootfsTar { path } => { + validate_rootfs_tar_source(gateway_name, &mut client, &path).await?; + (None, Some(path)) } } } - None => None, + None => (None, None), } }; let inferred_types: Vec = inferred_provider_type(command).into_iter().collect(); @@ -565,7 +570,7 @@ pub async fn sandbox_create( } else { None }; - let driver_config = if template.is_none() { + let mut driver_config = if template.is_none() { driver_config_json .map(parse_driver_config_json) .transpose()? @@ -573,7 +578,15 @@ pub async fn sandbox_create( None }; - let inline_template = if image.is_some() || resource_limits.is_some() || driver_config.is_some() + if let Some(tar_path) = &rootfs_tar_path { + let rootfs_config = rootfs_tar_driver_config(tar_path)?; + driver_config = Some(merge_driver_config(driver_config, rootfs_config)); + } + + let inline_template = if image.is_some() + || resource_limits.is_some() + || driver_config.is_some() + || rootfs_tar_path.is_some() { Some(SandboxTemplate { image: image.unwrap_or_default(), @@ -1149,17 +1162,23 @@ enum ResolvedSource { dockerfile: PathBuf, context: PathBuf, }, + /// A flat rootfs tar archive (`.tar`, `.tar.gz`, `.tgz`) to pass directly + /// to the VM compute driver. + RootfsTar { path: PathBuf }, } -/// Classify the `--from` value into an image reference or a Dockerfile that -/// needs building. +/// Classify the `--from` value into an image reference, a Dockerfile that +/// needs building, or a rootfs tar to pass to the VM driver. /// /// Resolution order: -/// 1. Existing file whose name contains "Dockerfile" → build from file. +/// 1. Existing file whose name contains "dockerfile" → build from Dockerfile. /// 2. Existing directory that contains a `Dockerfile` → build from directory. -/// 3. Missing explicit local paths → local error, not image pull. -/// 4. Value contains `/`, `:`, or `.` → treat as a full image reference. -/// 5. Otherwise → community sandbox name, expanded via the registry prefix. +/// 3. Existing file with `.tar`, `.tar.gz`, or `.tgz` extension → rootfs tar archive. +/// 4. Other existing local paths → error. +/// 5. Non-existent path-like values (`./…`, `../…`, `/…`, `~/…`) → local +/// error, so they don't reach the gateway as broken image-pull requests. +/// 6. Value contains `/`, `:`, or `.` → treat as a full image reference. +/// 7. Otherwise → community sandbox name, expanded via the registry prefix. fn resolve_from(value: &str) -> Result { let path = Path::new(value); @@ -1180,9 +1199,17 @@ fn resolve_from(value: &str) -> Result { }); } + if filename_looks_like_rootfs_tar(path) { + let tar_path = path + .canonicalize() + .into_diagnostic() + .wrap_err_with(|| format!("failed to resolve path: {}", path.display()))?; + return Ok(ResolvedSource::RootfsTar { path: tar_path }); + } + if value_looks_like_local_source(value) { return Err(miette::miette!( - "local --from file is not a Dockerfile: {}", + "local --from file is not a Dockerfile or rootfs tar (.tar/.tar.gz/.tgz): {}", path.display() )); } @@ -1221,7 +1248,7 @@ fn resolve_from(value: &str) -> Result { if value_looks_like_local_source(value) { return Err(miette::miette!( "local --from path does not exist: {}\n\ - Use an existing Dockerfile, a directory containing Dockerfile, or a container image reference.", + Use an existing Dockerfile, directory containing Dockerfile, rootfs tar (.tar/.tar.gz/.tgz), or a container image reference.", path.display() )); } @@ -1239,7 +1266,17 @@ fn filename_looks_like_dockerfile(path: &Path) -> bool { .map(|n| n.to_string_lossy()) .unwrap_or_default(); let lower = name.to_lowercase(); - lower.contains("dockerfile") || lower.ends_with(".dockerfile") + lower.contains("dockerfile") +} + +#[allow(clippy::case_sensitive_file_extension_comparisons)] // already lowercased +fn filename_looks_like_rootfs_tar(path: &Path) -> bool { + let name = path + .file_name() + .map(|n| n.to_string_lossy()) + .unwrap_or_default(); + let lower = name.to_lowercase(); + lower.ends_with(".tar.gz") || lower.ends_with(".tar") || lower.ends_with(".tgz") } fn value_looks_like_local_source(value: &str) -> bool { @@ -1321,6 +1358,73 @@ async fn build_from_dockerfile( Ok(tag) } +/// Validate that a rootfs tar source is usable with the current gateway. +async fn validate_rootfs_tar_source( + gateway_name: &str, + client: &mut crate::tls::GrpcClient, + tar_path: &Path, +) -> Result<()> { + let metadata = get_gateway_metadata(gateway_name); + if !dockerfile_sources_supported_for_gateway(metadata.as_ref()) { + return Err(miette!( + "local rootfs tar sources are only supported for local gateways; gateway '{}' is remote", + gateway_name + )); + } + + let info = client + .get_gateway_info(GetGatewayInfoRequest {}) + .await + .into_diagnostic() + .wrap_err("failed to query gateway compute driver")? + .into_inner(); + + let driver_name = info.compute_drivers.first().map_or("", |d| d.name.as_str()); + + if driver_name != "vm" { + return Err(miette!( + "rootfs tar sources are only supported by the VM compute driver, \ + but gateway '{}' uses the '{}' driver", + gateway_name, + driver_name + )); + } + + eprintln!( + "Using rootfs tar {} for gateway '{}'", + tar_path.display().to_string().cyan(), + gateway_name, + ); + eprintln!(); + + Ok(()) +} + +/// Build a `driver_config` struct carrying the rootfs tar path for the VM driver. +fn rootfs_tar_driver_config(tar_path: &Path) -> Result { + let fields = serde_json::Map::from_iter([( + "rootfs_tar_path".to_string(), + serde_json::Value::String(tar_path.to_string_lossy().into_owned()), + )]); + openshell_core::proto_struct::json_object_to_struct(fields) + .into_diagnostic() + .wrap_err("failed to encode rootfs_tar_path in driver_config") +} + +/// Merge a rootfs tar config into an existing `driver_config`, if any. +fn merge_driver_config( + base: Option, + overlay: prost_types::Struct, +) -> prost_types::Struct { + match base { + Some(mut base) => { + base.fields.extend(overlay.fields); + base + } + None => overlay, + } +} + /// Load sandbox policy YAML. /// /// Resolution order: `--policy` flag > `OPENSHELL_SANDBOX_POLICY` env var. @@ -6511,8 +6615,8 @@ mod tests { .expect("failed to canonicalize context") ); } - super::ResolvedSource::Image(image) => { - panic!("expected Dockerfile source, got image {image}"); + other => { + panic!("expected Dockerfile source, got {other:?}"); } } } @@ -6537,12 +6641,101 @@ mod tests { match resolve_from(image_ref).expect("expected image source") { super::ResolvedSource::Image(image) => assert_eq!(image, image_ref), - super::ResolvedSource::Dockerfile { .. } => { - panic!("expected image ref, got Dockerfile source"); + other => { + panic!("expected image ref, got {other:?}"); + } + } + } + + #[test] + fn resolve_from_classifies_tar_archive() { + let temp = tempfile::tempdir().expect("failed to create tempdir"); + let archive = temp.path().join("rootfs.tar"); + fs::write(&archive, b"fake tar content").expect("failed to write archive"); + + match resolve_from(archive.to_str().expect("temp path is not UTF-8")) + .expect("expected RootfsTar source") + { + super::ResolvedSource::RootfsTar { path } => { + assert_eq!( + path, + archive + .canonicalize() + .expect("failed to canonicalize archive") + ); + } + other => panic!("expected RootfsTar source, got {other:?}"), + } + } + + #[test] + fn resolve_from_classifies_tar_gz_archive() { + let temp = tempfile::tempdir().expect("failed to create tempdir"); + let archive = temp.path().join("rootfs.tar.gz"); + fs::write(&archive, b"fake tar.gz content").expect("failed to write archive"); + + match resolve_from(archive.to_str().expect("temp path is not UTF-8")) + .expect("expected RootfsTar source") + { + super::ResolvedSource::RootfsTar { path } => { + assert_eq!( + path, + archive + .canonicalize() + .expect("failed to canonicalize archive") + ); + } + other => panic!("expected RootfsTar source, got {other:?}"), + } + } + + #[test] + fn resolve_from_classifies_tgz_archive() { + let temp = tempfile::tempdir().expect("failed to create tempdir"); + let archive = temp.path().join("rootfs.tgz"); + fs::write(&archive, b"fake tgz content").expect("failed to write archive"); + + match resolve_from(archive.to_str().expect("temp path is not UTF-8")) + .expect("expected RootfsTar source") + { + super::ResolvedSource::RootfsTar { path } => { + assert_eq!( + path, + archive + .canonicalize() + .expect("failed to canonicalize archive") + ); } + other => panic!("expected RootfsTar source, got {other:?}"), } } + #[test] + fn resolve_from_rejects_missing_tar_archive() { + let temp = tempfile::tempdir().expect("failed to create tempdir"); + let missing = temp.path().join("missing.tar"); + + let err = resolve_from(missing.to_str().expect("temp path is not UTF-8")) + .expect_err("expected missing archive to be rejected"); + + assert!( + err.to_string().contains("local --from path does not exist"), + "unexpected error: {err}" + ); + } + + #[test] + fn filename_looks_like_rootfs_tar_detects_extensions() { + use super::filename_looks_like_rootfs_tar; + assert!(filename_looks_like_rootfs_tar(Path::new("rootfs.tar"))); + assert!(filename_looks_like_rootfs_tar(Path::new("rootfs.tar.gz"))); + assert!(filename_looks_like_rootfs_tar(Path::new("rootfs.tgz"))); + assert!(filename_looks_like_rootfs_tar(Path::new("IMAGE.TAR"))); + assert!(filename_looks_like_rootfs_tar(Path::new("my-image.TAR.GZ"))); + assert!(!filename_looks_like_rootfs_tar(Path::new("Dockerfile"))); + assert!(!filename_looks_like_rootfs_tar(Path::new("image.zip"))); + } + #[test] fn dockerfile_sources_are_rejected_for_remote_gateways() { let metadata = GatewayMetadata { diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index aa9f4288c1..2acd370dc5 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -101,6 +101,7 @@ struct VmSandboxDriverConfig { deserialize_with = "deserialize_optional_non_empty_string_list" )] gpu_device_ids: Option>, + rootfs_tar_path: Option, } impl VmSandboxDriverConfig { @@ -693,9 +694,11 @@ impl VmDriver { #[allow(clippy::result_large_err)] pub fn validate_sandbox(&self, sandbox: &Sandbox) -> Result<(), Status> { validate_vm_sandbox(sandbox, self.config.gpu_enabled)?; - if self.resolved_sandbox_image(sandbox).is_none() { + let has_rootfs_tar = + VmSandboxDriverConfig::from_sandbox(sandbox).is_ok_and(|c| c.rootfs_tar_path.is_some()); + if self.resolved_sandbox_image(sandbox).is_none() && !has_rootfs_tar { return Err(Status::failed_precondition( - "vm sandboxes require template.image or a configured default sandbox image", + "vm sandboxes require template.image, rootfs_tar_path in driver_config, or a configured default sandbox image", )); } Ok(()) @@ -713,11 +716,20 @@ impl VmDriver { validate_vm_sandbox(sandbox, self.config.gpu_enabled)?; let state_dir = sandbox_state_dir(&self.config.state_dir, &sandbox.id)?; - let image_ref = self.resolved_sandbox_image(sandbox).ok_or_else(|| { - Status::failed_precondition( - "vm sandboxes require template.image or a configured default sandbox image", - ) - })?; + let has_rootfs_tar = + VmSandboxDriverConfig::from_sandbox(sandbox).is_ok_and(|c| c.rootfs_tar_path.is_some()); + let image_ref = self + .resolved_sandbox_image(sandbox) + .or_else(|| { + has_rootfs_tar + .then(|| self.bootstrap_image_ref_default()) + .flatten() + }) + .ok_or_else(|| { + Status::failed_precondition( + "vm sandboxes require template.image, rootfs_tar_path in driver_config, or a configured default sandbox image", + ) + })?; info!( sandbox_id = %sandbox.id, image_ref = %image_ref, @@ -882,6 +894,10 @@ impl VmDriver { .and_then(|spec| spec.resource_requirements.as_ref()) .and_then(|requirements| driver_gpu_requirements(Some(requirements))) .is_some(); + let driver_config = + VmSandboxDriverConfig::from_sandbox(&sandbox).map_err(Status::invalid_argument)?; + let rootfs_tar_path = driver_config.rootfs_tar_path.map(PathBuf::from); + self.publish_platform_event( sandbox.id.clone(), platform_event( @@ -892,7 +908,9 @@ impl VmDriver { ), ); - let image_plan = self.prepare_runtime_images(&sandbox.id, &image_ref).await?; + let image_plan = self + .prepare_runtime_images(&sandbox.id, &image_ref, rootfs_tar_path.as_deref()) + .await?; let image_identity = image_plan.image_identity.clone(); self.ensure_provisioning_active(&sandbox.id).await?; info!( @@ -1633,7 +1651,14 @@ impl VmDriver { clear_stop_marker: bool, reconciliation_span: &tracing::Span, ) -> bool { - let Some(image_ref) = self.resolved_sandbox_image(&sandbox) else { + let has_rootfs_tar = VmSandboxDriverConfig::from_sandbox(&sandbox) + .is_ok_and(|c| c.rootfs_tar_path.is_some()); + + let Some(image_ref) = self.resolved_sandbox_image(&sandbox).or_else(|| { + has_rootfs_tar + .then(|| self.bootstrap_image_ref_default()) + .flatten() + }) else { warn!( sandbox_id = %sandbox.id, sandbox_name = %sandbox.name, @@ -2177,6 +2202,7 @@ impl VmDriver { &self, sandbox_id: &str, image_ref: &str, + rootfs_tar_path: Option<&Path>, ) -> Result { let span_status = openshell_otel::ErrorStatusGuard::current(); let bootstrap_image_ref = self.bootstrap_image_ref(image_ref); @@ -2185,6 +2211,18 @@ impl VmDriver { .await?; let root_disk = image_cache_rootfs_image(&self.config.state_dir, &bootstrap_image_identity); + if let Some(tar_path) = rootfs_tar_path { + let prepared = self + .ensure_prepared_rootfs_tar_disk(sandbox_id, tar_path, &root_disk) + .await?; + return Ok(RuntimeImagePlan { + root_disk, + image_disk: Some(prepared.disk_path), + image_identity: prepared.image_identity, + bootstrap_image_identity, + }); + } + if image_ref.trim() == bootstrap_image_ref.trim() { return span_status.finish(Ok(RuntimeImagePlan { root_disk, @@ -2206,15 +2244,20 @@ impl VmDriver { } fn bootstrap_image_ref(&self, sandbox_image_ref: &str) -> String { + self.bootstrap_image_ref_default() + .unwrap_or_else(|| sandbox_image_ref.to_string()) + } + + fn bootstrap_image_ref_default(&self) -> Option { let configured = self.config.bootstrap_image.trim(); if !configured.is_empty() { - return configured.to_string(); + return Some(configured.to_string()); } let default = self.config.default_image.trim(); if !default.is_empty() { - return default.to_string(); + return Some(default.to_string()); } - sandbox_image_ref.to_string() + None } #[tracing::instrument( @@ -2716,6 +2759,100 @@ impl VmDriver { }) } + async fn ensure_prepared_rootfs_tar_disk( + &self, + sandbox_id: &str, + tar_path: &Path, + bootstrap_root_disk: &Path, + ) -> Result { + let metadata = tokio::fs::metadata(tar_path).await.map_err(|err| { + Status::failed_precondition(format!( + "rootfs tar not accessible at {}: {err}", + tar_path.display() + )) + })?; + let mtime = metadata + .modified() + .unwrap_or(std::time::SystemTime::UNIX_EPOCH) + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let tar_identity = format!("rootfs-tar:{}:{mtime}", tar_path.display()); + let cache_identity = prepared_image_cache_identity(&tar_identity); + let image_path = image_cache_rootfs_image(&self.config.state_dir, &cache_identity); + let tar_display = tar_path.display().to_string(); + + if tokio::fs::metadata(&image_path).await.is_ok() { + self.publish_prepared_cache_hit( + sandbox_id, + &tar_display, + "rootfs_tar", + &cache_identity, + ); + return Ok(PreparedImageDisk { + image_identity: cache_identity, + disk_path: image_path, + }); + } + + self.publish_prepared_cache_miss(sandbox_id, &tar_display, "rootfs_tar", &cache_identity); + let _cache_guard = self.image_cache_lock.lock().await; + if tokio::fs::metadata(&image_path).await.is_ok() { + self.publish_prepared_cache_hit( + sandbox_id, + &tar_display, + "rootfs_tar", + &cache_identity, + ); + return Ok(PreparedImageDisk { + image_identity: cache_identity, + disk_path: image_path, + }); + } + + let staging_dir = image_cache_staging_dir(&self.config.state_dir, &cache_identity); + let rootfs_archive = staging_dir.join(IMAGE_EXPORT_ROOTFS_ARCHIVE); + self.reset_image_staging_dir(&staging_dir).await?; + + self.publish_vm_progress( + sandbox_id, + "CopyingRootfsTar", + format!("Copying rootfs tar \"{tar_display}\""), + HashMap::from([ + ("rootfs_tar_path".to_string(), tar_display.clone()), + ("image_source".to_string(), "rootfs_tar".to_string()), + ("image_identity".to_string(), cache_identity.clone()), + ]), + ); + if let Err(err) = tokio::fs::copy(tar_path, &rootfs_archive).await { + let _ = tokio::fs::remove_dir_all(&staging_dir).await; + return Err(Status::internal(format!( + "failed to copy rootfs tar to staging: {err}" + ))); + } + + let payload = GuestImagePayload { + image_ref: tar_display.clone(), + image_identity: cache_identity.clone(), + source: GuestImagePayloadSource::LocalDocker { rootfs_archive }, + }; + self.build_prepared_image_disk( + sandbox_id, + &tar_display, + "rootfs_tar", + &cache_identity, + bootstrap_root_disk, + &staging_dir, + &payload, + ) + .await?; + + Ok(PreparedImageDisk { + image_identity: cache_identity, + disk_path: image_path, + }) + } + async fn ensure_prepared_registry_image_disk( &self, sandbox_id: &str, diff --git a/docs/sandboxes/manage-sandboxes.mdx b/docs/sandboxes/manage-sandboxes.mdx index 31c7182e5f..0ea6d4c7d6 100644 --- a/docs/sandboxes/manage-sandboxes.mdx +++ b/docs/sandboxes/manage-sandboxes.mdx @@ -144,19 +144,22 @@ openshell sandbox create \ ### Custom Containers -Use `--from` to create a sandbox from the base image, another pre-built sandbox name, a local directory, or a container image: +Use `--from` to create a sandbox from the base image, another pre-built sandbox name, a local directory, a rootfs tar archive, or a container image: ```shell openshell sandbox create --from base openshell sandbox create --from ollama openshell sandbox create --from ./my-sandbox-dir +openshell sandbox create --from ./rootfs.tar openshell sandbox create --from my-registry.example.com/my-image:latest ``` Bare names such as `base` and `ollama` resolve to images under `ghcr.io/nvidia/openshell-community/sandboxes`. Set `OPENSHELL_COMMUNITY_REGISTRY` when you need to use an internal mirror. -Local directories and Dockerfiles require a local gateway because the CLI builds -through the local Docker daemon. Use a registry image reference for remote +Local directories and Dockerfiles require a local gateway because the CLI +builds images through the local Docker daemon. Rootfs tar archives +(`.tar`, `.tar.gz`, `.tgz`) also require a local gateway and are passed +directly to the VM compute driver. Use a registry image reference for remote gateways. ## Reuse Workload Templates diff --git a/e2e/rust/Cargo.toml b/e2e/rust/Cargo.toml index 8d3632e950..8eb3403c61 100644 --- a/e2e/rust/Cargo.toml +++ b/e2e/rust/Cargo.toml @@ -58,6 +58,11 @@ name = "custom_image" path = "tests/custom_image.rs" required-features = ["e2e-docker"] +[[test]] +name = "rootfs_tar" +path = "tests/rootfs_tar.rs" +required-features = ["e2e-vm"] + [[test]] name = "docker_preflight" path = "tests/docker_preflight.rs" diff --git a/e2e/rust/tests/rootfs_tar.rs b/e2e/rust/tests/rootfs_tar.rs new file mode 100644 index 0000000000..e3d303654c --- /dev/null +++ b/e2e/rust/tests/rootfs_tar.rs @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![cfg(feature = "e2e")] + +//! E2E test: create a sandbox from a flat rootfs tar archive. +//! +//! Prerequisites: +//! - A running VM-backed openshell gateway with a default sandbox image configured +//! - Docker daemon running (for image build + container export) +//! - The `openshell` binary (built automatically from the workspace) + +use openshell_e2e::harness::container::ContainerEngine; +use openshell_e2e::harness::output::strip_ansi; +use openshell_e2e::harness::sandbox::SandboxGuard; + +const DOCKERFILE_CONTENT: &str = r#"FROM public.ecr.aws/docker/library/python:3.13-slim + +# iproute2 is required for sandbox network namespace isolation. +RUN apt-get update && apt-get install -y --no-install-recommends iproute2 \ + && rm -rf /var/lib/apt/lists/* + +# Create the sandbox user/group so the supervisor can switch to it. +RUN groupadd -g 1000660000 sandbox && \ + useradd -m -u 1000660000 -g sandbox sandbox + +RUN echo "rootfs-tar-e2e-marker" > /etc/marker.txt + +CMD ["sleep", "infinity"] +"#; + +const MARKER: &str = "rootfs-tar-e2e-marker"; + +/// Build a Docker image, export its filesystem as a flat rootfs tar, then +/// create a sandbox from that tar and verify it contains the expected marker. +#[tokio::test] +async fn sandbox_from_rootfs_tar() { + let engine = ContainerEngine::from_env().expect("container engine available"); + let tmpdir = tempfile::tempdir().expect("create tmpdir"); + + // Step 1: Write a Dockerfile and build an image. + let dockerfile_path = tmpdir.path().join("Dockerfile"); + std::fs::write(&dockerfile_path, DOCKERFILE_CONTENT).expect("write Dockerfile"); + + let tag = format!( + "openshell/e2e-rootfs-tar-test:{}", + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs() + ); + + let build_output = engine + .command() + .args(["build", "-t", &tag, "-f"]) + .arg(&dockerfile_path) + .arg(tmpdir.path()) + .output() + .expect("spawn docker build"); + + assert!( + build_output.status.success(), + "docker build failed:\n{}", + String::from_utf8_lossy(&build_output.stderr) + ); + + // Step 2: Create a temporary container and export its filesystem as a + // flat rootfs tar (equivalent to `docker export`). + let container_name = format!("openshell-e2e-rootfs-export-{}", std::process::id()); + + let create_output = engine + .command() + .args(["create", "--name", &container_name, &tag]) + .output() + .expect("spawn docker create"); + + assert!( + create_output.status.success(), + "docker create failed:\n{}", + String::from_utf8_lossy(&create_output.stderr) + ); + + let rootfs_tar_path = tmpdir.path().join("rootfs.tar"); + let export_output = engine + .command() + .args(["export", "-o"]) + .arg(&rootfs_tar_path) + .arg(&container_name) + .output() + .expect("spawn docker export"); + + assert!( + export_output.status.success(), + "docker export failed:\n{}", + String::from_utf8_lossy(&export_output.stderr) + ); + + // Clean up the temporary container and image. + let _ = engine.command().args(["rm", &container_name]).output(); + let _ = engine.command().args(["rmi", &tag]).output(); + + // Step 3: Create a sandbox from the rootfs tar. + let tar_str = rootfs_tar_path.to_str().expect("tar path is UTF-8"); + let mut guard = SandboxGuard::create(&["--from", tar_str, "--", "cat", "/etc/marker.txt"]) + .await + .expect("sandbox create from rootfs tar"); + + // Step 4: Verify the marker file content appears in the output. + let clean_output = strip_ansi(&guard.create_output); + assert!( + clean_output.contains(MARKER), + "expected marker '{MARKER}' in sandbox output:\n{clean_output}" + ); + + guard.cleanup().await; +} From 59d07df872fa7d0796c5e818acf681846093e150 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 26 Aug 2026 07:39:56 +0000 Subject: [PATCH 2/8] fix(sandbox): validate rootfs tar path at the VM driver boundary The rootfs_tar_path field in driver_config was passed from the API caller directly to tokio::fs::copy without validation. An authenticated user bypassing the CLI could supply arbitrary host paths (e.g. /dev/zero for disk exhaustion, or readable host files for data exfiltration). Introduce a trusted staging directory that the VM driver creates on startup and advertises via GetCapabilities. The CLI now copies the tar into the staging directory before creating the sandbox, and the driver validates that the received path is a regular file inside the staging root and within a configurable size limit (default 10 GiB) before any I/O. New VmDriverConfig options: - rootfs_tar_staging_dir: override the staging directory (default: /rootfs-tar-staging) - rootfs_tar_max_bytes: override the size limit (default: 10 GiB) Addresses GATOR-28b5152e-01. Signed-off-by: Philippe Martin --- crates/openshell-cli/src/run.rs | 44 +++++++-- crates/openshell-driver-docker/src/lib.rs | 1 + .../openshell-driver-kubernetes/src/driver.rs | 1 + crates/openshell-driver-mxc/src/driver.rs | 1 + crates/openshell-driver-podman/src/driver.rs | 1 + crates/openshell-driver-vm/src/driver.rs | 95 ++++++++++++++++++- crates/openshell-driver-vm/src/main.rs | 8 ++ crates/openshell-server/src/compute/mod.rs | 8 ++ crates/openshell-server/src/grpc/mod.rs | 1 + crates/openshell-server/src/test_support.rs | 1 + proto/compute_driver.proto | 4 + proto/openshell.proto | 4 + 12 files changed, 160 insertions(+), 9 deletions(-) diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index 62d73762f6..72ee99dae8 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -546,8 +546,9 @@ pub async fn sandbox_create( (Some(tag), None) } ResolvedSource::RootfsTar { path } => { - validate_rootfs_tar_source(gateway_name, &mut client, &path).await?; - (None, Some(path)) + let staged = + validate_and_stage_rootfs_tar(gateway_name, &mut client, &path).await?; + (None, Some(staged)) } } } @@ -1358,12 +1359,13 @@ async fn build_from_dockerfile( Ok(tag) } -/// Validate that a rootfs tar source is usable with the current gateway. -async fn validate_rootfs_tar_source( +/// Validate that a rootfs tar source is usable with the current gateway, then +/// copy it into the driver's staging directory. Returns the staged path. +async fn validate_and_stage_rootfs_tar( gateway_name: &str, client: &mut crate::tls::GrpcClient, tar_path: &Path, -) -> Result<()> { +) -> Result { let metadata = get_gateway_metadata(gateway_name); if !dockerfile_sources_supported_for_gateway(metadata.as_ref()) { return Err(miette!( @@ -1379,7 +1381,11 @@ async fn validate_rootfs_tar_source( .wrap_err("failed to query gateway compute driver")? .into_inner(); - let driver_name = info.compute_drivers.first().map_or("", |d| d.name.as_str()); + let driver = info + .compute_drivers + .first() + .ok_or_else(|| miette!("gateway '{}' has no compute drivers", gateway_name))?; + let driver_name = driver.name.as_str(); if driver_name != "vm" { return Err(miette!( @@ -1390,14 +1396,36 @@ async fn validate_rootfs_tar_source( )); } + let staging_dir = driver + .capabilities + .as_ref() + .map_or("", |c| c.rootfs_tar_staging_dir.as_str()); + if staging_dir.is_empty() { + return Err(miette!( + "gateway '{}' VM driver did not advertise a rootfs tar staging directory", + gateway_name + )); + } + let staging_dir = PathBuf::from(staging_dir); + + let file_name = tar_path + .file_name() + .ok_or_else(|| miette!("rootfs tar path has no filename"))?; + let staged_name = format!("{}-{}", std::process::id(), file_name.to_string_lossy()); + let staged_path = staging_dir.join(&staged_name); + eprintln!( - "Using rootfs tar {} for gateway '{}'", + "Staging rootfs tar {} for gateway '{}'", tar_path.display().to_string().cyan(), gateway_name, ); + tokio::fs::copy(tar_path, &staged_path) + .await + .into_diagnostic() + .wrap_err_with(|| format!("failed to stage rootfs tar to {}", staged_path.display()))?; eprintln!(); - Ok(()) + Ok(staged_path) } /// Build a `driver_config` struct carrying the rootfs tar path for the VM driver. diff --git a/crates/openshell-driver-docker/src/lib.rs b/crates/openshell-driver-docker/src/lib.rs index d5df4c0b96..fc7ea7174a 100644 --- a/crates/openshell-driver-docker/src/lib.rs +++ b/crates/openshell-driver-docker/src/lib.rs @@ -603,6 +603,7 @@ impl DockerComputeDriver { count_selection_supported: self.config.gpu.cdi_supported, }), }), + rootfs_tar_staging_dir: String::new(), } } diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index 39dab36317..d809416762 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -589,6 +589,7 @@ impl KubernetesComputeDriver { count_selection_supported: true, }), }), + rootfs_tar_staging_dir: String::new(), }) } diff --git a/crates/openshell-driver-mxc/src/driver.rs b/crates/openshell-driver-mxc/src/driver.rs index 28de9e33d7..62f134205b 100644 --- a/crates/openshell-driver-mxc/src/driver.rs +++ b/crates/openshell-driver-mxc/src/driver.rs @@ -292,6 +292,7 @@ impl MxcComputeBackend { supports_sandbox_authentication: false, driver_reports_runtime_readiness: true, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), } } diff --git a/crates/openshell-driver-podman/src/driver.rs b/crates/openshell-driver-podman/src/driver.rs index 8d0957f87a..f9fbd26488 100644 --- a/crates/openshell-driver-podman/src/driver.rs +++ b/crates/openshell-driver-podman/src/driver.rs @@ -529,6 +529,7 @@ impl PodmanComputeDriver { count_selection_supported: true, }), }), + rootfs_tar_staging_dir: String::new(), }) } diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index 2acd370dc5..b3d19e97f2 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -92,6 +92,9 @@ const MAX_REGISTRY_LAYER_DOWNLOAD_CONCURRENCY: usize = 16; const REGISTRY_REQUEST_MAX_ATTEMPTS: usize = 4; const REGISTRY_RETRY_INITIAL_DELAY: Duration = Duration::from_millis(250); const REGISTRY_RETRY_MAX_DELAY: Duration = Duration::from_secs(1); +/// 10 GiB — configurable via `rootfs_tar_max_bytes`. +const DEFAULT_ROOTFS_TAR_MAX_BYTES: u64 = 10 * 1024 * 1024 * 1024; +const ROOTFS_TAR_STAGING_DIR: &str = "rootfs-tar-staging"; #[derive(Debug, Clone, Default, serde::Deserialize)] #[serde(default, deny_unknown_fields)] @@ -326,6 +329,13 @@ pub struct VmDriverConfig { /// TLS-intercepting proxy. #[serde(default, skip_serializing_if = "Option::is_none")] pub proxy_ca_bundle: Option, + /// Directory where rootfs tar files must be staged before they can be + /// referenced in a `CreateSandbox` request. Defaults to `/rootfs-tar-staging`. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub rootfs_tar_staging_dir: Option, + /// Maximum rootfs tar file size in bytes. Defaults to 10 GiB. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub rootfs_tar_max_bytes: Option, } /// Redacting `Debug` so a proxy URL or credential path never reaches a log. @@ -359,6 +369,8 @@ impl std::fmt::Debug for VmDriverConfig { .field("proxy_auth_allow_insecure", &self.proxy_auth_allow_insecure) .field("proxy_connect_by_hostname", &self.proxy_connect_by_hostname) .field("proxy_ca_bundle", &self.proxy_ca_bundle) + .field("rootfs_tar_staging_dir", &self.rootfs_tar_staging_dir) + .field("rootfs_tar_max_bytes", &self.rootfs_tar_max_bytes) .finish() } } @@ -393,6 +405,8 @@ impl Default for VmDriverConfig { proxy_auth_allow_insecure: None, proxy_connect_by_hostname: None, proxy_ca_bundle: None, + rootfs_tar_staging_dir: None, + rootfs_tar_max_bytes: None, } } } @@ -454,6 +468,17 @@ impl VmDriverConfig { ) } + fn rootfs_tar_staging_dir(&self) -> PathBuf { + self.rootfs_tar_staging_dir + .clone() + .unwrap_or_else(|| self.state_dir.join(ROOTFS_TAR_STAGING_DIR)) + } + + fn rootfs_tar_max_bytes(&self) -> u64 { + self.rootfs_tar_max_bytes + .unwrap_or(DEFAULT_ROOTFS_TAR_MAX_BYTES) + } + fn requires_tls_materials(&self) -> bool { self.openshell_endpoint.starts_with("https://") } @@ -625,6 +650,13 @@ impl VmDriver { image_cache_root.display() ) })?; + let staging_dir = config.rootfs_tar_staging_dir(); + create_private_dir_all(&staging_dir).await.map_err(|err| { + format!( + "failed to create rootfs tar staging dir '{}': {err}", + staging_dir.display() + ) + })?; let launcher_bin = if let Some(path) = config.launcher_bin.clone() { path @@ -665,6 +697,59 @@ impl VmDriver { Ok(driver) } + async fn validate_rootfs_tar_path(&self, raw: &Path) -> Result { + let staging_dir = self.config.rootfs_tar_staging_dir(); + let canonical_staging = tokio::fs::canonicalize(&staging_dir).await.map_err(|err| { + Status::internal(format!( + "rootfs tar staging dir not accessible at {}: {err}", + staging_dir.display() + )) + })?; + + let canonical = tokio::fs::canonicalize(raw).await.map_err(|err| { + Status::failed_precondition(format!( + "rootfs tar path not accessible at {}: {err}", + raw.display() + )) + })?; + + if !canonical.starts_with(&canonical_staging) { + return Err(Status::permission_denied(format!( + "rootfs tar path {} is outside the staging directory {}", + canonical.display(), + canonical_staging.display() + ))); + } + + let metadata = tokio::fs::symlink_metadata(&canonical) + .await + .map_err(|err| { + Status::failed_precondition(format!( + "rootfs tar not accessible at {}: {err}", + canonical.display() + )) + })?; + if !metadata.file_type().is_file() { + return Err(Status::invalid_argument(format!( + "rootfs tar path {} is not a regular file", + canonical.display() + ))); + } + + let max_bytes = self.config.rootfs_tar_max_bytes(); + let file_size = metadata.len(); + if file_size > max_bytes { + return Err(Status::invalid_argument(format!( + "rootfs tar {} is {} bytes, exceeding the {} byte limit", + canonical.display(), + file_size, + max_bytes + ))); + } + + Ok(canonical) + } + #[must_use] pub fn capabilities(&self) -> GetCapabilitiesResponse { GetCapabilitiesResponse { @@ -686,6 +771,11 @@ impl VmDriver { count_selection_supported: self.config.gpu_enabled, }), }), + rootfs_tar_staging_dir: self + .config + .rootfs_tar_staging_dir() + .to_string_lossy() + .into_owned(), } } @@ -896,7 +986,10 @@ impl VmDriver { .is_some(); let driver_config = VmSandboxDriverConfig::from_sandbox(&sandbox).map_err(Status::invalid_argument)?; - let rootfs_tar_path = driver_config.rootfs_tar_path.map(PathBuf::from); + let rootfs_tar_path = match driver_config.rootfs_tar_path { + Some(raw) => Some(self.validate_rootfs_tar_path(Path::new(&raw)).await?), + None => None, + }; self.publish_platform_event( sandbox.id.clone(), diff --git a/crates/openshell-driver-vm/src/main.rs b/crates/openshell-driver-vm/src/main.rs index b8788e4fc9..1570ba8419 100644 --- a/crates/openshell-driver-vm/src/main.rs +++ b/crates/openshell-driver-vm/src/main.rs @@ -167,6 +167,12 @@ struct Args { #[arg(long, env = "OPENSHELL_VM_PROXY_CA_BUNDLE")] proxy_ca_bundle: Option, + #[arg(long, env = "OPENSHELL_VM_ROOTFS_TAR_STAGING_DIR")] + rootfs_tar_staging_dir: Option, + + #[arg(long, env = "OPENSHELL_VM_ROOTFS_TAR_MAX_BYTES")] + rootfs_tar_max_bytes: Option, + #[arg(long, hide = true)] vm_backend: Option, @@ -261,6 +267,8 @@ async fn main() -> Result<()> { proxy_auth_allow_insecure: args.proxy_auth_allow_insecure, proxy_connect_by_hostname: args.proxy_connect_by_hostname, proxy_ca_bundle: args.proxy_ca_bundle.clone(), + rootfs_tar_staging_dir: args.rootfs_tar_staging_dir.clone(), + rootfs_tar_max_bytes: args.rootfs_tar_max_bytes, }) .await .map_err(|err| miette::miette!("{err}"))?; diff --git a/crates/openshell-server/src/compute/mod.rs b/crates/openshell-server/src/compute/mod.rs index 42efab3d6f..af3f1a0568 100644 --- a/crates/openshell-server/src/compute/mod.rs +++ b/crates/openshell-server/src/compute/mod.rs @@ -307,6 +307,8 @@ pub struct ComputeDriverInfoSnapshot { pub driver_reports_runtime_readiness: bool, /// Static portable resource request forms from the startup capability snapshot. pub resource_capabilities: Option, + /// Directory where rootfs tar files must be staged. + pub rootfs_tar_staging_dir: String, } /// Interval between store-vs-backend reconciliation sweeps. @@ -656,6 +658,7 @@ impl ComputeRuntime { supports_sandbox_authentication: capabilities.supports_sandbox_authentication, driver_reports_runtime_readiness: capabilities.driver_reports_runtime_readiness, resource_capabilities: capabilities.resource_capabilities, + rootfs_tar_staging_dir: capabilities.rootfs_tar_staging_dir, }; let default_image = capabilities.default_image; let gateway_listener_requirements = match driver @@ -4659,6 +4662,7 @@ impl ComputeDriver for NoopTestDriver { supports_sandbox_authentication: self.sandbox_authentication.is_some(), driver_reports_runtime_readiness: false, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), }, )) } @@ -4804,6 +4808,7 @@ pub async fn new_test_runtime_with_driver( supports_sandbox_authentication, driver_reports_runtime_readiness: false, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), }, telemetry_compute_driver: TelemetryComputeDriver::custom(), driver_process: None, @@ -4983,6 +4988,7 @@ mod tests { supports_sandbox_authentication: false, driver_reports_runtime_readiness: false, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), })) } @@ -5325,6 +5331,7 @@ mod tests { supports_sandbox_authentication: false, driver_reports_runtime_readiness: false, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), })) } @@ -5536,6 +5543,7 @@ mod tests { supports_sandbox_authentication: false, driver_reports_runtime_readiness: false, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), }, telemetry_compute_driver: TelemetryComputeDriver::custom(), driver_process: None, diff --git a/crates/openshell-server/src/grpc/mod.rs b/crates/openshell-server/src/grpc/mod.rs index a88a2e3414..eb36d248f0 100644 --- a/crates/openshell-server/src/grpc/mod.rs +++ b/crates/openshell-server/src/grpc/mod.rs @@ -264,6 +264,7 @@ impl OpenShell for OpenShellService { .resource_capabilities .as_ref() .map(|resources| public_resource_capabilities(*resources)), + rootfs_tar_staging_dir: driver.rootfs_tar_staging_dir.clone(), }), }) .collect(); diff --git a/crates/openshell-server/src/test_support.rs b/crates/openshell-server/src/test_support.rs index 3af65242ef..5b837a1000 100644 --- a/crates/openshell-server/src/test_support.rs +++ b/crates/openshell-server/src/test_support.rs @@ -98,6 +98,7 @@ impl FakeComputeDriver { supports_sandbox_authentication: false, driver_reports_runtime_readiness: false, resource_capabilities: None, + rootfs_tar_staging_dir: String::new(), }, gateway_listener_requirements: Vec::new(), gateway_listener_requirements_supported: true, diff --git a/proto/compute_driver.proto b/proto/compute_driver.proto index fe311201c1..c89b054d6d 100644 --- a/proto/compute_driver.proto +++ b/proto/compute_driver.proto @@ -93,6 +93,10 @@ message GetCapabilitiesResponse { bool driver_reports_runtime_readiness = 8; // Static portable resource request forms supported by this configured driver. ResourceCapabilities resource_capabilities = 9; + // Absolute path to the directory where rootfs tar files must be staged + // before being referenced in a CreateSandbox request. The driver rejects + // paths outside this directory. + string rootfs_tar_staging_dir = 10; } message AuthenticateSandboxRequest { diff --git a/proto/openshell.proto b/proto/openshell.proto index e07055a47b..eb53977bc5 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -839,6 +839,10 @@ message ComputeDriverCapabilities { // Static portable resource request forms reported by the driver. ResourceCapabilities resource_capabilities = 3; + + // Absolute path where rootfs tar files must be staged before creating a + // sandbox. Empty when the driver does not support rootfs tar sources. + string rootfs_tar_staging_dir = 4; } // Static portable resource request forms reported by a compute driver. From 58b56174386ddbb3c0fe0575d43015d15360b5c9 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 26 Aug 2026 09:12:01 +0000 Subject: [PATCH 3/8] fix(sandbox): request-scoped staging, size pre-check, and cleanup for rootfs tar Tighten the rootfs tar staging flow to address the remaining GATOR-01 obligations: - Request-scoped staging: the CLI creates a unique per-request subdirectory (req-) under the staging root instead of placing files directly in the shared directory. The driver enforces that the tar path is at depth 2 (staging_root//), preventing cross-request path selection. - Size pre-check: the driver advertises rootfs_tar_max_bytes via GetCapabilities. The CLI reads this limit and rejects oversized files before copying, avoiding disk exhaustion in the staging directory. - Cleanup: the driver removes the request staging subdirectory after consuming the tar (on cache hit, copy success, or copy failure), ensuring staged data does not persist beyond the request. Signed-off-by: Philippe Martin --- crates/openshell-cli/src/run.rs | 47 +++++++++++++++---- crates/openshell-driver-docker/src/lib.rs | 1 + .../openshell-driver-kubernetes/src/driver.rs | 1 + crates/openshell-driver-podman/src/driver.rs | 1 + crates/openshell-driver-vm/src/driver.rs | 21 +++++++++ crates/openshell-server/src/compute/mod.rs | 8 ++++ crates/openshell-server/src/grpc/mod.rs | 1 + crates/openshell-server/src/test_support.rs | 1 + proto/compute_driver.proto | 3 ++ proto/openshell.proto | 3 ++ 10 files changed, 77 insertions(+), 10 deletions(-) diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index 72ee99dae8..9431b415ad 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -1396,10 +1396,8 @@ async fn validate_and_stage_rootfs_tar( )); } - let staging_dir = driver - .capabilities - .as_ref() - .map_or("", |c| c.rootfs_tar_staging_dir.as_str()); + let caps = driver.capabilities.as_ref(); + let staging_dir = caps.map_or("", |c| c.rootfs_tar_staging_dir.as_str()); if staging_dir.is_empty() { return Err(miette!( "gateway '{}' VM driver did not advertise a rootfs tar staging directory", @@ -1408,21 +1406,50 @@ async fn validate_and_stage_rootfs_tar( } let staging_dir = PathBuf::from(staging_dir); + let max_bytes = caps.map_or(0, |c| c.rootfs_tar_max_bytes); + if max_bytes > 0 { + let source_meta = tokio::fs::metadata(tar_path) + .await + .into_diagnostic() + .wrap_err_with(|| format!("failed to read {}", tar_path.display()))?; + if source_meta.len() > max_bytes { + return Err(miette!( + "rootfs tar {} is {} bytes, exceeding the gateway limit of {} bytes", + tar_path.display(), + source_meta.len(), + max_bytes + )); + } + } + + let request_dir = staging_dir.join(format!("req-{}", std::process::id())); + tokio::fs::create_dir_all(&request_dir) + .await + .into_diagnostic() + .wrap_err_with(|| { + format!( + "failed to create staging directory {}", + request_dir.display() + ) + })?; + let file_name = tar_path .file_name() .ok_or_else(|| miette!("rootfs tar path has no filename"))?; - let staged_name = format!("{}-{}", std::process::id(), file_name.to_string_lossy()); - let staged_path = staging_dir.join(&staged_name); + let staged_path = request_dir.join(file_name); eprintln!( "Staging rootfs tar {} for gateway '{}'", tar_path.display().to_string().cyan(), gateway_name, ); - tokio::fs::copy(tar_path, &staged_path) - .await - .into_diagnostic() - .wrap_err_with(|| format!("failed to stage rootfs tar to {}", staged_path.display()))?; + if let Err(err) = tokio::fs::copy(tar_path, &staged_path).await { + let _ = tokio::fs::remove_dir_all(&request_dir).await; + return Err(miette!( + "failed to stage rootfs tar to {}: {err}", + staged_path.display() + )); + } eprintln!(); Ok(staged_path) diff --git a/crates/openshell-driver-docker/src/lib.rs b/crates/openshell-driver-docker/src/lib.rs index fc7ea7174a..df5aee4750 100644 --- a/crates/openshell-driver-docker/src/lib.rs +++ b/crates/openshell-driver-docker/src/lib.rs @@ -604,6 +604,7 @@ impl DockerComputeDriver { }), }), rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, } } diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index d809416762..3a19917384 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -590,6 +590,7 @@ impl KubernetesComputeDriver { }), }), rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, }) } diff --git a/crates/openshell-driver-podman/src/driver.rs b/crates/openshell-driver-podman/src/driver.rs index f9fbd26488..50eb014691 100644 --- a/crates/openshell-driver-podman/src/driver.rs +++ b/crates/openshell-driver-podman/src/driver.rs @@ -530,6 +530,7 @@ impl PodmanComputeDriver { }), }), rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, }) } diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index b3d19e97f2..6e632675e7 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -721,6 +721,15 @@ impl VmDriver { ))); } + let relative = canonical.strip_prefix(&canonical_staging).unwrap(); + let depth = relative.components().count(); + if depth != 2 { + return Err(Status::permission_denied(format!( + "rootfs tar path {} must be inside a request subdirectory of the staging root", + canonical.display(), + ))); + } + let metadata = tokio::fs::symlink_metadata(&canonical) .await .map_err(|err| { @@ -776,6 +785,7 @@ impl VmDriver { .rootfs_tar_staging_dir() .to_string_lossy() .into_owned(), + rootfs_tar_max_bytes: self.config.rootfs_tar_max_bytes(), } } @@ -2858,6 +2868,13 @@ impl VmDriver { tar_path: &Path, bootstrap_root_disk: &Path, ) -> Result { + let request_staging_dir = tar_path.parent().map(Path::to_path_buf); + let cleanup_request_staging = || async { + if let Some(d) = &request_staging_dir { + let _ = tokio::fs::remove_dir_all(d).await; + } + }; + let metadata = tokio::fs::metadata(tar_path).await.map_err(|err| { Status::failed_precondition(format!( "rootfs tar not accessible at {}: {err}", @@ -2882,6 +2899,7 @@ impl VmDriver { "rootfs_tar", &cache_identity, ); + cleanup_request_staging().await; return Ok(PreparedImageDisk { image_identity: cache_identity, disk_path: image_path, @@ -2897,6 +2915,7 @@ impl VmDriver { "rootfs_tar", &cache_identity, ); + cleanup_request_staging().await; return Ok(PreparedImageDisk { image_identity: cache_identity, disk_path: image_path, @@ -2919,10 +2938,12 @@ impl VmDriver { ); if let Err(err) = tokio::fs::copy(tar_path, &rootfs_archive).await { let _ = tokio::fs::remove_dir_all(&staging_dir).await; + cleanup_request_staging().await; return Err(Status::internal(format!( "failed to copy rootfs tar to staging: {err}" ))); } + cleanup_request_staging().await; let payload = GuestImagePayload { image_ref: tar_display.clone(), diff --git a/crates/openshell-server/src/compute/mod.rs b/crates/openshell-server/src/compute/mod.rs index af3f1a0568..6351dc97a3 100644 --- a/crates/openshell-server/src/compute/mod.rs +++ b/crates/openshell-server/src/compute/mod.rs @@ -309,6 +309,8 @@ pub struct ComputeDriverInfoSnapshot { pub resource_capabilities: Option, /// Directory where rootfs tar files must be staged. pub rootfs_tar_staging_dir: String, + /// Maximum rootfs tar file size in bytes. + pub rootfs_tar_max_bytes: u64, } /// Interval between store-vs-backend reconciliation sweeps. @@ -659,6 +661,7 @@ impl ComputeRuntime { driver_reports_runtime_readiness: capabilities.driver_reports_runtime_readiness, resource_capabilities: capabilities.resource_capabilities, rootfs_tar_staging_dir: capabilities.rootfs_tar_staging_dir, + rootfs_tar_max_bytes: capabilities.rootfs_tar_max_bytes, }; let default_image = capabilities.default_image; let gateway_listener_requirements = match driver @@ -4663,6 +4666,7 @@ impl ComputeDriver for NoopTestDriver { driver_reports_runtime_readiness: false, resource_capabilities: None, rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, }, )) } @@ -4809,6 +4813,7 @@ pub async fn new_test_runtime_with_driver( driver_reports_runtime_readiness: false, resource_capabilities: None, rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, }, telemetry_compute_driver: TelemetryComputeDriver::custom(), driver_process: None, @@ -4989,6 +4994,7 @@ mod tests { driver_reports_runtime_readiness: false, resource_capabilities: None, rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, })) } @@ -5332,6 +5338,7 @@ mod tests { driver_reports_runtime_readiness: false, resource_capabilities: None, rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, })) } @@ -5544,6 +5551,7 @@ mod tests { driver_reports_runtime_readiness: false, resource_capabilities: None, rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, }, telemetry_compute_driver: TelemetryComputeDriver::custom(), driver_process: None, diff --git a/crates/openshell-server/src/grpc/mod.rs b/crates/openshell-server/src/grpc/mod.rs index eb36d248f0..405a99f9d3 100644 --- a/crates/openshell-server/src/grpc/mod.rs +++ b/crates/openshell-server/src/grpc/mod.rs @@ -265,6 +265,7 @@ impl OpenShell for OpenShellService { .as_ref() .map(|resources| public_resource_capabilities(*resources)), rootfs_tar_staging_dir: driver.rootfs_tar_staging_dir.clone(), + rootfs_tar_max_bytes: driver.rootfs_tar_max_bytes, }), }) .collect(); diff --git a/crates/openshell-server/src/test_support.rs b/crates/openshell-server/src/test_support.rs index 5b837a1000..3bd5430ef1 100644 --- a/crates/openshell-server/src/test_support.rs +++ b/crates/openshell-server/src/test_support.rs @@ -99,6 +99,7 @@ impl FakeComputeDriver { driver_reports_runtime_readiness: false, resource_capabilities: None, rootfs_tar_staging_dir: String::new(), + rootfs_tar_max_bytes: 0, }, gateway_listener_requirements: Vec::new(), gateway_listener_requirements_supported: true, diff --git a/proto/compute_driver.proto b/proto/compute_driver.proto index c89b054d6d..f9a19589f9 100644 --- a/proto/compute_driver.proto +++ b/proto/compute_driver.proto @@ -97,6 +97,9 @@ message GetCapabilitiesResponse { // before being referenced in a CreateSandbox request. The driver rejects // paths outside this directory. string rootfs_tar_staging_dir = 10; + // Maximum rootfs tar file size in bytes accepted by the driver. Zero means + // the driver does not support rootfs tar sources. + uint64 rootfs_tar_max_bytes = 11; } message AuthenticateSandboxRequest { diff --git a/proto/openshell.proto b/proto/openshell.proto index eb53977bc5..5be2881a7a 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -843,6 +843,9 @@ message ComputeDriverCapabilities { // Absolute path where rootfs tar files must be staged before creating a // sandbox. Empty when the driver does not support rootfs tar sources. string rootfs_tar_staging_dir = 4; + + // Maximum rootfs tar file size in bytes accepted by the driver. + uint64 rootfs_tar_max_bytes = 5; } // Static portable resource request forms reported by a compute driver. From d0cd9a622611866c28193ecc0120175efcd3eae1 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 26 Aug 2026 10:36:49 +0000 Subject: [PATCH 4/8] fix(vm): restore rootfs-tar sandboxes from persisted image identity On restore or restart, the one-shot staged tar archive has already been cleaned up. Reading the persisted image identity from the sandbox state directory and resolving the cached disk path directly avoids re-accessing the deleted staging path. Addresses GATOR-168b9210-01. Signed-off-by: Philippe Martin --- crates/openshell-driver-vm/src/driver.rs | 41 +++++++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index 6e632675e7..fd87b13989 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -996,9 +996,12 @@ impl VmDriver { .is_some(); let driver_config = VmSandboxDriverConfig::from_sandbox(&sandbox).map_err(Status::invalid_argument)?; + let driver_config_had_rootfs_tar = driver_config.rootfs_tar_path.is_some(); let rootfs_tar_path = match driver_config.rootfs_tar_path { - Some(raw) => Some(self.validate_rootfs_tar_path(Path::new(&raw)).await?), - None => None, + Some(raw) if overlay_preparation == OverlayPreparation::Fresh => { + Some(self.validate_rootfs_tar_path(Path::new(&raw)).await?) + } + Some(_) | None => None, }; self.publish_platform_event( @@ -1011,9 +1014,32 @@ impl VmDriver { ), ); - let image_plan = self - .prepare_runtime_images(&sandbox.id, &image_ref, rootfs_tar_path.as_deref()) - .await?; + let image_plan = if overlay_preparation == OverlayPreparation::PreserveExisting + && driver_config_had_rootfs_tar + { + let persisted_identity = + read_persisted_image_identity(&state_dir).await.map_err(|err| { + Status::internal(format!( + "cannot restore rootfs-tar sandbox: persisted image identity not found: {err}" + )) + })?; + let bootstrap_image_ref = self.bootstrap_image_ref(&image_ref); + let bootstrap_image_identity = self + .ensure_cached_bootstrap_rootfs_image(&sandbox.id, &bootstrap_image_ref) + .await?; + let root_disk = + image_cache_rootfs_image(&self.config.state_dir, &bootstrap_image_identity); + let image_disk = image_cache_rootfs_image(&self.config.state_dir, &persisted_identity); + RuntimeImagePlan { + root_disk, + image_disk: Some(image_disk), + image_identity: persisted_identity, + bootstrap_image_identity, + } + } else { + self.prepare_runtime_images(&sandbox.id, &image_ref, rootfs_tar_path.as_deref()) + .await? + }; let image_identity = image_plan.image_identity.clone(); self.ensure_provisioning_active(&sandbox.id).await?; info!( @@ -5463,6 +5489,11 @@ async fn write_sandbox_image_metadata( Ok(()) } +async fn read_persisted_image_identity(state_dir: &Path) -> Result { + let raw = tokio::fs::read_to_string(state_dir.join(IMAGE_IDENTITY_FILE)).await?; + Ok(raw.trim().to_string()) +} + async fn write_sandbox_request(state_dir: &Path, sandbox: &Sandbox) -> Result<(), std::io::Error> { restrict_owner_only_dir(state_dir).await?; write_private_file( From 79d0587ac2aa36e6ea6e53da4df241ccdeffac20 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Wed, 26 Aug 2026 12:07:22 +0000 Subject: [PATCH 5/8] fix(cli): use random staging dirs and enforce byte limit during rootfs tar copy Replace PID-based request staging directories with tempfile-generated random names to prevent collisions and make paths unpredictable. Replace bare tokio::fs::copy with a streaming copy loop that enforces the advertised max_bytes limit during transfer, closing the TOCTOU gap between the pre-copy size check and the actual copy. Signed-off-by: Philippe Martin Signed-off-by: Philippe Martin --- crates/openshell-cli/src/run.rs | 58 +++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index 9431b415ad..cb23b9fa21 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -1422,16 +1422,12 @@ async fn validate_and_stage_rootfs_tar( } } - let request_dir = staging_dir.join(format!("req-{}", std::process::id())); - tokio::fs::create_dir_all(&request_dir) - .await + let request_dir = tempfile::Builder::new() + .prefix("req-") + .tempdir_in(&staging_dir) .into_diagnostic() - .wrap_err_with(|| { - format!( - "failed to create staging directory {}", - request_dir.display() - ) - })?; + .wrap_err("failed to create request staging directory")? + .keep(); let file_name = tar_path .file_name() @@ -1443,7 +1439,7 @@ async fn validate_and_stage_rootfs_tar( tar_path.display().to_string().cyan(), gateway_name, ); - if let Err(err) = tokio::fs::copy(tar_path, &staged_path).await { + if let Err(err) = copy_with_byte_limit(tar_path, &staged_path, max_bytes).await { let _ = tokio::fs::remove_dir_all(&request_dir).await; return Err(miette!( "failed to stage rootfs tar to {}: {err}", @@ -1455,6 +1451,48 @@ async fn validate_and_stage_rootfs_tar( Ok(staged_path) } +/// Copy `src` to `dst`, aborting if total bytes written exceeds `limit`. +/// A limit of 0 disables enforcement. +async fn copy_with_byte_limit( + src: &Path, + dst: &Path, + limit: u64, +) -> std::result::Result<(), String> { + use tokio::io::{AsyncReadExt, AsyncWriteExt}; + + let mut reader = tokio::fs::File::open(src) + .await + .map_err(|e| format!("open source: {e}"))?; + let mut writer = tokio::fs::File::create(dst) + .await + .map_err(|e| format!("create destination: {e}"))?; + + let mut buf = vec![0u8; 64 * 1024]; + let mut total: u64 = 0; + loop { + let n = reader + .read(&mut buf) + .await + .map_err(|e| format!("read: {e}"))?; + if n == 0 { + break; + } + total += n as u64; + if limit > 0 && total > limit { + return Err(format!( + "{} exceeds the {} byte limit", + src.display(), + limit + )); + } + writer + .write_all(&buf[..n]) + .await + .map_err(|e| format!("write: {e}"))?; + } + Ok(()) +} + /// Build a `driver_config` struct carrying the rootfs tar path for the VM driver. fn rootfs_tar_driver_config(tar_path: &Path) -> Result { let fields = serde_json::Map::from_iter([( From c3881cda9b3dd287bebe6f5ee7f5659b94733d5a Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Mon, 31 Aug 2026 10:57:21 +0200 Subject: [PATCH 6/8] fix(sandbox): issue rootfs tar staging slots from the gateway A caller could name any host path in `driver_config.vm.rootfs_tar_path`, which the privileged VM driver then read. The CLI-side locality check did not apply to direct API requests. The gateway now owns staging. `BeginRootfsTarStaging` allocates a request-scoped directory under the driver-advertised staging root and returns an opaque single-use token; `CreateSandbox` carries the token, and the gateway substitutes the path it allocated before dispatching to the driver. `template.driver_config..rootfs_tar_path` is rejected outright in request validation, so a caller-supplied path never reaches privileged I/O. Tokens are bound to the issuing workspace and subject, consumed once, and expire after 30 minutes. Outstanding slots are capped per caller and overall, so one caller can neither exhaust the staging filesystem nor starve others. An RAII guard reclaims the directory on every failure path after consumption, and an age-gated sweep runs at startup and on each reconcile pass for directories whose driver died before its own cleanup. The token is stripped from the public sandbox before persistence: the stored copy is returned verbatim by GetSandbox, ListSandboxes and WatchSandbox to every member of the workspace. Also fixes two defects this exposed: - The CLI wrote `rootfs_tar_path` at the top level of `driver_config`, but the gateway forwards only `driver_config.`, silently dropping unmatched keys. The archive never reached the VM driver, so the documented `--from ./rootfs.tar` flow did not work at all. Config is now nested under `vm` and deep-merged, so a caller's existing VM settings survive instead of being clobbered by a shallow extend. - Staging previously required `GetGatewayInfo`, which is restricted to `platform_admin`, making the feature unusable for ordinary users on any RBAC-enabled gateway. The new RPC matches CreateSandbox at `sandbox:write` / `workspace_role: user`. `compute_driver.proto` is unchanged; the gateway reads the staging root from the capabilities it already stores. Refs #2175 Signed-off-by: Philippe Martin --- crates/openshell-cli/src/run.rs | 275 +- .../tests/ensure_providers_integration.rs | 7 + .../openshell-cli/tests/mtls_integration.rs | 7 + .../tests/provider_commands_integration.rs | 7 + .../sandbox_create_lifecycle_integration.rs | 7 + .../sandbox_name_fallback_integration.rs | 7 + crates/openshell-sdk/tests/client_mock.rs | 7 + crates/openshell-server/src/compute/mod.rs | 258 +- .../src/compute/rootfs_tar.rs | 693 +++++ crates/openshell-server/src/grpc/mod.rs | 41 +- crates/openshell-server/src/grpc/sandbox.rs | 82 +- .../openshell-server/src/grpc/validation.rs | 64 + crates/openshell-server/tests/common/mod.rs | 7 + .../tests/supervisor_relay_integration.rs | 7 + docs/reference/gateway-config.mdx | 13 + docs/sandboxes/manage-sandboxes.mdx | 32 +- proto/openshell.proto | 51 +- sdk/go/proto/openshellv1/openshell.pb.go | 2231 +++++++++-------- sdk/go/proto/openshellv1/openshell_grpc.pb.go | 54 + 19 files changed, 2684 insertions(+), 1166 deletions(-) create mode 100644 crates/openshell-server/src/compute/rootfs_tar.rs diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index cb23b9fa21..18c8ee7366 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -44,11 +44,11 @@ use openshell_bootstrap::{ }; use openshell_core::net::set_tcp_nodelay_best_effort; use openshell_core::proto::{ - ApproveAllDraftChunksRequest, ApproveDraftChunkRequest, ClearDraftChunksRequest, - CreateSandboxRequest, CreateSandboxTemplateRequest, CreateSshSessionRequest, - DeleteInferenceRouteRequest, DeleteSandboxRequest, DeleteSandboxTemplateRequest, - DeleteServiceRequest, ExecSandboxRequest, ExposeServiceRequest, GetCurrentUserRequest, - GetDraftHistoryRequest, GetDraftPolicyRequest, GetGatewayConfigRequest, GetGatewayInfoRequest, + ApproveAllDraftChunksRequest, ApproveDraftChunkRequest, BeginRootfsTarStagingRequest, + ClearDraftChunksRequest, CreateSandboxRequest, CreateSandboxTemplateRequest, + CreateSshSessionRequest, DeleteInferenceRouteRequest, DeleteSandboxRequest, + DeleteSandboxTemplateRequest, DeleteServiceRequest, ExecSandboxRequest, ExposeServiceRequest, + GetCurrentUserRequest, GetDraftHistoryRequest, GetDraftPolicyRequest, GetGatewayConfigRequest, GetInferenceRouteRequest, GetSandboxConfigRequest, GetSandboxConfigResponse, GetSandboxLogsRequest, GetSandboxPolicyStatusRequest, GetSandboxRequest, GetSandboxTemplateRequest, GetServiceRequest, GpuResourceRequirements, @@ -526,10 +526,10 @@ pub async fn sandbox_create( } // Resolve the --from flag into a container image reference, building from - // a Dockerfile first if necessary, or a rootfs tar path for the VM driver. - // Template creates resolve workload shape on the gateway and skip local - // image handling. - let (image, rootfs_tar_path): (Option, Option) = if template.is_some() { + // a Dockerfile first if necessary, or staging a rootfs tar on the gateway + // and carrying back its staging token. Template creates resolve workload + // shape on the gateway and skip local image handling. + let (image, rootfs_tar_token): (Option, Option) = if template.is_some() { (None, None) } else { match from { @@ -546,9 +546,9 @@ pub async fn sandbox_create( (Some(tag), None) } ResolvedSource::RootfsTar { path } => { - let staged = - validate_and_stage_rootfs_tar(gateway_name, &mut client, &path).await?; - (None, Some(staged)) + let token = + stage_rootfs_tar(gateway_name, &mut client, workspace, &path).await?; + (None, Some(token)) } } } @@ -579,15 +579,14 @@ pub async fn sandbox_create( None }; - if let Some(tar_path) = &rootfs_tar_path { - let rootfs_config = rootfs_tar_driver_config(tar_path)?; - driver_config = Some(merge_driver_config(driver_config, rootfs_config)); + if let Some(token) = &rootfs_tar_token { + driver_config = Some(merge_rootfs_tar_driver_config(driver_config, token)?); } let inline_template = if image.is_some() || resource_limits.is_some() || driver_config.is_some() - || rootfs_tar_path.is_some() + || rootfs_tar_token.is_some() { Some(SandboxTemplate { image: image.unwrap_or_default(), @@ -1359,13 +1358,18 @@ async fn build_from_dockerfile( Ok(tag) } -/// Validate that a rootfs tar source is usable with the current gateway, then -/// copy it into the driver's staging directory. Returns the staged path. -async fn validate_and_stage_rootfs_tar( +/// Ask the gateway for a staging slot, then copy the archive into it. +/// +/// The gateway owns the destination: it allocates a request-scoped directory +/// and returns a single-use token. We never name a path of our own choosing, +/// so a request cannot reach for another caller's archive or an arbitrary host +/// file. Returns the token to pass on `CreateSandbox`. +async fn stage_rootfs_tar( gateway_name: &str, client: &mut crate::tls::GrpcClient, + workspace: &str, tar_path: &Path, -) -> Result { +) -> Result { let metadata = get_gateway_metadata(gateway_name); if !dockerfile_sources_supported_for_gateway(metadata.as_ref()) { return Err(miette!( @@ -1374,73 +1378,40 @@ async fn validate_and_stage_rootfs_tar( )); } - let info = client - .get_gateway_info(GetGatewayInfoRequest {}) + let file_name = tar_path + .file_name() + .ok_or_else(|| miette!("rootfs tar path has no filename"))? + .to_string_lossy() + .into_owned(); + let source_meta = tokio::fs::metadata(tar_path) .await .into_diagnostic() - .wrap_err("failed to query gateway compute driver")? - .into_inner(); - - let driver = info - .compute_drivers - .first() - .ok_or_else(|| miette!("gateway '{}' has no compute drivers", gateway_name))?; - let driver_name = driver.name.as_str(); - - if driver_name != "vm" { - return Err(miette!( - "rootfs tar sources are only supported by the VM compute driver, \ - but gateway '{}' uses the '{}' driver", - gateway_name, - driver_name - )); - } - - let caps = driver.capabilities.as_ref(); - let staging_dir = caps.map_or("", |c| c.rootfs_tar_staging_dir.as_str()); - if staging_dir.is_empty() { - return Err(miette!( - "gateway '{}' VM driver did not advertise a rootfs tar staging directory", - gateway_name - )); - } - let staging_dir = PathBuf::from(staging_dir); - - let max_bytes = caps.map_or(0, |c| c.rootfs_tar_max_bytes); - if max_bytes > 0 { - let source_meta = tokio::fs::metadata(tar_path) - .await - .into_diagnostic() - .wrap_err_with(|| format!("failed to read {}", tar_path.display()))?; - if source_meta.len() > max_bytes { - return Err(miette!( - "rootfs tar {} is {} bytes, exceeding the gateway limit of {} bytes", - tar_path.display(), - source_meta.len(), - max_bytes - )); - } - } + .wrap_err_with(|| format!("failed to read {}", tar_path.display()))?; - let request_dir = tempfile::Builder::new() - .prefix("req-") - .tempdir_in(&staging_dir) + // The gateway rejects a driver that cannot take rootfs tar sources, and an + // archive over its configured limit, before allocating anything. + let slot = client + .begin_rootfs_tar_staging(BeginRootfsTarStagingRequest { + workspace: workspace.to_string(), + file_name, + size_bytes: source_meta.len(), + }) + .await .into_diagnostic() - .wrap_err("failed to create request staging directory")? - .keep(); - - let file_name = tar_path - .file_name() - .ok_or_else(|| miette!("rootfs tar path has no filename"))?; - let staged_path = request_dir.join(file_name); + .wrap_err("failed to allocate a rootfs tar staging slot on the gateway")? + .into_inner(); + let staged_path = PathBuf::from(&slot.upload_path); eprintln!( "Staging rootfs tar {} for gateway '{}'", tar_path.display().to_string().cyan(), gateway_name, ); - if let Err(err) = copy_with_byte_limit(tar_path, &staged_path, max_bytes).await { - let _ = tokio::fs::remove_dir_all(&request_dir).await; + // Enforced while streaming, so an archive that grows after the size check + // above still cannot exceed the limit. + if let Err(err) = copy_with_byte_limit(tar_path, &staged_path, slot.max_bytes).await { + // The staging directory belongs to the gateway, which reclaims it when + // the slot expires. Removing it here would reach into its state. return Err(miette!( "failed to stage rootfs tar to {}: {err}", staged_path.display() @@ -1448,7 +1419,7 @@ async fn validate_and_stage_rootfs_tar( } eprintln!(); - Ok(staged_path) + Ok(slot.staging_token) } /// Copy `src` to `dst`, aborting if total bytes written exceeds `limit`. @@ -1493,29 +1464,51 @@ async fn copy_with_byte_limit( Ok(()) } -/// Build a `driver_config` struct carrying the rootfs tar path for the VM driver. -fn rootfs_tar_driver_config(tar_path: &Path) -> Result { - let fields = serde_json::Map::from_iter([( - "rootfs_tar_path".to_string(), - serde_json::Value::String(tar_path.to_string_lossy().into_owned()), - )]); - openshell_core::proto_struct::json_object_to_struct(fields) - .into_diagnostic() - .wrap_err("failed to encode rootfs_tar_path in driver_config") -} +/// `driver_config` key for the VM compute driver. The gateway forwards only +/// `template.driver_config.` to the selected driver, so VM +/// settings must be nested under this key or they are dropped. +const VM_DRIVER_CONFIG_KEY: &str = "vm"; +/// VM `driver_config` field naming the gateway-issued staging slot. The +/// gateway swaps it for the resolved archive path before the driver sees it. +const ROOTFS_TAR_TOKEN_FIELD: &str = "rootfs_tar_staging_token"; -/// Merge a rootfs tar config into an existing `driver_config`, if any. -fn merge_driver_config( +/// Merge the staging token into `driver_config.vm`, preserving any VM settings +/// the caller already supplied through `--driver-config-json`. +fn merge_rootfs_tar_driver_config( base: Option, - overlay: prost_types::Struct, -) -> prost_types::Struct { - match base { - Some(mut base) => { - base.fields.extend(overlay.fields); - base - } - None => overlay, + staging_token: &str, +) -> Result { + use prost_types::{Struct, Value, value::Kind}; + + let mut config = base.unwrap_or_default(); + let vm = config + .fields + .entry(VM_DRIVER_CONFIG_KEY.to_string()) + .or_insert_with(|| Value { + kind: Some(Kind::StructValue(Struct::default())), + }); + + let Some(Kind::StructValue(vm_config)) = vm.kind.as_mut() else { + return Err(miette!( + "--driver-config-json '{VM_DRIVER_CONFIG_KEY}' must be an object" + )); + }; + + if vm_config.fields.contains_key(ROOTFS_TAR_TOKEN_FIELD) { + return Err(miette!( + "--driver-config-json already sets {VM_DRIVER_CONFIG_KEY}.{ROOTFS_TAR_TOKEN_FIELD}; \ + remove it or drop the rootfs tar from --from" + )); } + + vm_config.fields.insert( + ROOTFS_TAR_TOKEN_FIELD.to_string(), + Value { + kind: Some(Kind::StringValue(staging_token.to_string())), + }, + ); + + Ok(config) } /// Load sandbox policy YAML. @@ -6829,6 +6822,92 @@ mod tests { assert!(!filename_looks_like_rootfs_tar(Path::new("image.zip"))); } + /// The gateway forwards only `template.driver_config.` to the + /// selected driver, so a top-level key is silently dropped and the archive + /// never reaches the VM driver. + #[test] + fn rootfs_tar_driver_config_nests_under_vm_key() { + use prost_types::value::Kind; + + let config = + super::merge_rootfs_tar_driver_config(None, "tok-abc").expect("merge should succeed"); + + assert_eq!( + config.fields.keys().collect::>(), + vec!["vm"], + "rootfs tar config must live under the vm driver key" + ); + let Some(Kind::StructValue(vm)) = config.fields["vm"].kind.as_ref() else { + panic!("vm entry must be an object"); + }; + let Some(Kind::StringValue(token)) = vm.fields["rootfs_tar_staging_token"].kind.as_ref() + else { + panic!("rootfs_tar_staging_token must be a string"); + }; + assert_eq!(token, "tok-abc"); + assert!( + !vm.fields.contains_key("rootfs_tar_path"), + "the CLI never names a host path; the gateway resolves one" + ); + } + + #[test] + fn rootfs_tar_driver_config_preserves_existing_vm_settings() { + use prost_types::value::Kind; + + let base = parse_driver_config_json( + r#"{"vm":{"gpu_device_ids":["0000:2d:00.0"]},"docker":{"userns":"host"}}"#, + ) + .expect("valid driver config json"); + + let config = super::merge_rootfs_tar_driver_config(Some(base), "tok-abc") + .expect("merge should succeed"); + + // The sibling driver block survives untouched. + assert!(config.fields.contains_key("docker")); + + let Some(Kind::StructValue(vm)) = config.fields["vm"].kind.as_ref() else { + panic!("vm entry must be an object"); + }; + assert!( + vm.fields.contains_key("gpu_device_ids"), + "pre-existing vm settings must not be clobbered" + ); + let Some(Kind::StringValue(token)) = vm.fields["rootfs_tar_staging_token"].kind.as_ref() + else { + panic!("rootfs_tar_staging_token must be a string"); + }; + assert_eq!(token, "tok-abc"); + } + + #[test] + fn rootfs_tar_driver_config_rejects_caller_supplied_token() { + let base = parse_driver_config_json(r#"{"vm":{"rootfs_tar_staging_token":"stolen"}}"#) + .expect("valid driver config json"); + + let err = super::merge_rootfs_tar_driver_config(Some(base), "tok-abc") + .expect_err("a caller-supplied staging token must not be silently overwritten"); + + assert!( + err.to_string() + .contains("already sets vm.rootfs_tar_staging_token"), + "unexpected error: {err}" + ); + } + + #[test] + fn rootfs_tar_driver_config_rejects_non_object_vm_block() { + let base = parse_driver_config_json(r#"{"vm":"nonsense"}"#).expect("valid json object"); + + let err = super::merge_rootfs_tar_driver_config(Some(base), "tok-abc") + .expect_err("a non-object vm block must be rejected"); + + assert!( + err.to_string().contains("must be an object"), + "unexpected error: {err}" + ); + } + #[test] fn dockerfile_sources_are_rejected_for_remote_gateways() { let metadata = GatewayMetadata { diff --git a/crates/openshell-cli/tests/ensure_providers_integration.rs b/crates/openshell-cli/tests/ensure_providers_integration.rs index 2a4801b143..ab8626e0a1 100644 --- a/crates/openshell-cli/tests/ensure_providers_integration.rs +++ b/crates/openshell-cli/tests/ensure_providers_integration.rs @@ -81,6 +81,13 @@ impl TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/mtls_integration.rs b/crates/openshell-cli/tests/mtls_integration.rs index 12c838baf1..321c4f4697 100644 --- a/crates/openshell-cli/tests/mtls_integration.rs +++ b/crates/openshell-cli/tests/mtls_integration.rs @@ -34,6 +34,13 @@ struct TestOpenShell; #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/provider_commands_integration.rs b/crates/openshell-cli/tests/provider_commands_integration.rs index e48ca84af0..4211f9cef3 100644 --- a/crates/openshell-cli/tests/provider_commands_integration.rs +++ b/crates/openshell-cli/tests/provider_commands_integration.rs @@ -106,6 +106,13 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs index 7be771c442..e6500c37d5 100644 --- a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs +++ b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs @@ -72,6 +72,13 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs index 5b62c7c15c..bf0e1043e5 100644 --- a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs +++ b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs @@ -49,6 +49,13 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-sdk/tests/client_mock.rs b/crates/openshell-sdk/tests/client_mock.rs index 58633ceb17..89cc68bf0f 100644 --- a/crates/openshell-sdk/tests/client_mock.rs +++ b/crates/openshell-sdk/tests/client_mock.rs @@ -139,6 +139,13 @@ fn workload_template_proto(name: &str, workspace: &str) -> proto::SandboxWorkloa #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-server/src/compute/mod.rs b/crates/openshell-server/src/compute/mod.rs index 6351dc97a3..2b11946a63 100644 --- a/crates/openshell-server/src/compute/mod.rs +++ b/crates/openshell-server/src/compute/mod.rs @@ -5,6 +5,7 @@ pub mod driver_config; pub mod lease; +pub mod rootfs_tar; use crate::grpc::policy::SANDBOX_SETTINGS_OBJECT_TYPE; use crate::otel_tracing::TraceContextInterceptor; @@ -610,6 +611,10 @@ pub struct ComputeRuntime { lifecycle_gates: Arc, gateway_listener_requirements: Vec, replica_id: String, + /// Gateway-issued staging slots for rootfs tar archives. Shared across + /// clones: `ServerState` holds `ComputeRuntime` by value, so a per-clone + /// table would make a token minted on one clone invisible to another. + rootfs_tar_staging: Arc, } impl fmt::Debug for ComputeRuntime { @@ -717,6 +722,12 @@ impl ComputeRuntime { } Err(status) => return Err(compute_error_from_status(status)), }; + let rootfs_tar_staging = Arc::new(rootfs_tar::RootfsTarStagingRegistry::new( + (!driver_info.rootfs_tar_staging_dir.is_empty()) + .then(|| PathBuf::from(&driver_info.rootfs_tar_staging_dir)), + driver_info.rootfs_tar_max_bytes, + )); + rootfs_tar_staging.sweep_orphans(); Ok(Self { driver: TracedDriver::new(driver, driver_name), driver_info, @@ -732,6 +743,7 @@ impl ComputeRuntime { lifecycle_gates: Arc::new(LifecycleGateRegistry::default()), gateway_listener_requirements, replica_id: lease::replica_id(), + rootfs_tar_staging, }) } @@ -792,6 +804,15 @@ impl ComputeRuntime { std::slice::from_ref(&self.driver_info) } + #[must_use] + pub(crate) fn rootfs_tar_staging(&self) -> &rootfs_tar::RootfsTarStagingRegistry { + &self.rootfs_tar_staging + } + + /// The `template.driver_config` key whose block this gateway forwards. + /// + /// This is the *configured* driver name, which is not necessarily the name + /// the driver reports for itself in `driver_info.driver_name`. #[must_use] pub fn configured_driver_name(&self) -> &str { &self.driver_info.name @@ -883,8 +904,14 @@ impl ComputeRuntime { } pub async fn validate_sandbox_create(&self, sandbox: &Sandbox) -> Result<(), Status> { - let driver_sandbox = driver_sandbox_from_public(sandbox, &self.driver_info.name) + let mut driver_sandbox = driver_sandbox_from_public(sandbox, &self.driver_info.name) .map_err(|status| *status)?; + // Peek, never consume: create runs the same path immediately after and + // must still find the token. + if let Some(token) = take_staging_token(&mut driver_sandbox) { + let staged = self.rootfs_tar_staging.peek(&token)?; + set_rootfs_tar_path(&mut driver_sandbox, &staged); + } self.driver .call( openshell_otel::rpc::VALIDATE_SANDBOX_CREATE, @@ -908,12 +935,25 @@ impl ComputeRuntime { await_main_process_attachment: bool, ) -> Result { let sandbox_id = sandbox.object_id().to_string(); + let mut sandbox = sandbox; + + // Strip the staging token from the public sandbox before anything + // persists it: the object store copy is readable by every member of the + // workspace, and the token is a bearer credential for the staged + // archive. The driver gets the resolved path instead, on its own copy. + let staging_token = take_public_staging_token(&mut sandbox, &self.driver_info.name); + let mut staged = staging_token + .map(|token| self.rootfs_tar_staging.consume(&token)) + .transpose()?; + let mut driver_sandbox = driver_sandbox_from_public(&sandbox, &self.driver_info.name) .map_err(|status| *status)?; + if let Some(staged) = staged.as_ref() { + set_rootfs_tar_path(&mut driver_sandbox, staged.path()); + } // Create with MustCreate condition to prevent duplicate creation race self.sandbox_index.update_from_sandbox(&sandbox); - let mut sandbox = sandbox; let labels_map = sandbox.object_labels(); let labels_json = if labels_map.as_ref().is_none_or(HashMap::is_empty) { None @@ -973,6 +1013,12 @@ impl ComputeRuntime { .await { Ok(_) => { + // The driver now owns the staged archive and removes the + // request directory once it has built the disk. Every other + // arm lets the guard drop and clean up. + if let Some(staged) = staged.as_mut() { + staged.disarm(); + } self.sandbox_watch_bus.notify(sandbox.object_id()); if let Some(metadata) = sandbox.metadata.as_mut() { metadata.resource_version = result.resource_version; @@ -2712,6 +2758,9 @@ impl ComputeRuntime { )] async fn reconcile_store_with_backend(&self, grace_period: Duration) -> Result<(), String> { let sweep_started_at_ms = openshell_core::time::now_ms(); + // Reclaims staging directories whose driver failed before its own + // cleanup ran, which the token table cannot see once consumed. + self.rootfs_tar_staging.sweep_orphans(); let backend_sandboxes = self .driver .call( @@ -3901,6 +3950,76 @@ fn driver_sandbox_template_from_public( }) } +/// Remove the staging token from a driver-native sandbox, if present. +/// +/// The driver config here has already been narrowed to the selected driver's +/// block, so the token sits at the top level. +fn take_staging_token(driver_sandbox: &mut DriverSandbox) -> Option { + let config = driver_sandbox + .spec + .as_mut()? + .template + .as_mut()? + .driver_config + .as_mut()?; + match config.fields.remove(rootfs_tar::STAGING_TOKEN_FIELD)?.kind { + Some(prost_types::value::Kind::StringValue(token)) => Some(token), + _ => None, + } +} + +/// Remove the staging token from the public sandbox, under the driver's key. +/// +/// Called before the sandbox is persisted so the token never reaches the object +/// store, where every workspace member could read it back. +fn take_public_staging_token(sandbox: &mut Sandbox, driver_name: &str) -> Option { + let config = sandbox + .spec + .as_mut()? + .template + .as_mut()? + .driver_config + .as_mut()?; + let Some(prost_types::value::Kind::StructValue(driver_config)) = config + .fields + .get_mut(driver_name) + .and_then(|v| v.kind.as_mut()) + else { + return None; + }; + match driver_config + .fields + .remove(rootfs_tar::STAGING_TOKEN_FIELD)? + .kind + { + Some(prost_types::value::Kind::StringValue(token)) => Some(token), + _ => None, + } +} + +/// Substitute the gateway-resolved archive path into the driver-native copy. +/// +/// This is the only writer of `rootfs_tar_path`; a caller-supplied value is +/// rejected in request validation before it ever reaches here. +fn set_rootfs_tar_path(driver_sandbox: &mut DriverSandbox, path: &Path) { + let Some(template) = driver_sandbox + .spec + .as_mut() + .and_then(|spec| spec.template.as_mut()) + else { + return; + }; + let config = template.driver_config.get_or_insert_with(Default::default); + config.fields.insert( + rootfs_tar::ROOTFS_TAR_PATH_FIELD.to_string(), + prost_types::Value { + kind: Some(prost_types::value::Kind::StringValue( + path.to_string_lossy().into_owned(), + )), + }, + ); +} + fn select_driver_config( config: &Option, driver_name: &str, @@ -4827,6 +4946,7 @@ pub async fn new_test_runtime_with_driver( lifecycle_gates: Arc::new(LifecycleGateRegistry::default()), gateway_listener_requirements: Vec::new(), replica_id: "test-replica".to_string(), + rootfs_tar_staging: Arc::new(rootfs_tar::RootfsTarStagingRegistry::disabled()), } } @@ -4945,6 +5065,139 @@ mod tests { assert!(selected.fields.contains_key("pool")); } + /// The CLI builds `--from ` config as `{"vm": {...}}`. Guard the + /// CLI-to-driver transport: the rootfs tar field and any pre-existing VM + /// setting must both survive driver selection. A top-level field would be + /// dropped silently here and never reach the VM driver. + #[test] + fn select_driver_config_forwards_cli_rootfs_tar_template_to_vm_driver() { + let config = prost_types::Struct { + fields: std::iter::once(( + "vm".to_string(), + struct_value([ + ("rootfs_tar_path", string_value("/staging/req-a/rootfs.tar")), + ("gpu_device_ids", string_value("0000:2d:00.0")), + ]), + )) + .collect(), + }; + + let selected = select_driver_config(&Some(config), "vm").unwrap(); + let selected = selected.expect("vm config should be selected"); + + assert!(selected.fields.contains_key("rootfs_tar_path")); + assert!(selected.fields.contains_key("gpu_device_ids")); + } + + #[test] + fn select_driver_config_drops_top_level_rootfs_tar_path() { + let config = prost_types::Struct { + fields: std::iter::once(( + "rootfs_tar_path".to_string(), + string_value("/staging/req-a/rootfs.tar"), + )) + .collect(), + }; + + assert!( + select_driver_config(&Some(config), "vm").unwrap().is_none(), + "a top-level rootfs_tar_path never reaches the vm driver" + ); + } + + /// The staging token is a bearer credential for the staged archive, and the + /// persisted public sandbox is readable by every member of the workspace. + /// It must be stripped before anything writes that copy. + #[test] + fn take_public_staging_token_strips_it_from_the_public_sandbox() { + let mut sandbox = Sandbox { + spec: Some(SandboxSpec { + template: Some(SandboxTemplate { + driver_config: Some(prost_types::Struct { + fields: std::iter::once(( + "vm".to_string(), + struct_value([ + ("rootfs_tar_staging_token", string_value("tok-abc")), + ("gpu_device_ids", string_value("0000:2d:00.0")), + ]), + )) + .collect(), + }), + ..Default::default() + }), + ..Default::default() + }), + ..Default::default() + }; + + let token = take_public_staging_token(&mut sandbox, "vm"); + + assert_eq!(token.as_deref(), Some("tok-abc")); + let config = sandbox + .spec + .as_ref() + .and_then(|s| s.template.as_ref()) + .and_then(|t| t.driver_config.as_ref()) + .expect("driver config"); + let Some(prost_types::value::Kind::StructValue(vm)) = config.fields["vm"].kind.as_ref() + else { + panic!("vm block must survive"); + }; + assert!(!vm.fields.contains_key("rootfs_tar_staging_token")); + assert!( + vm.fields.contains_key("gpu_device_ids"), + "other vm settings must be left intact" + ); + } + + #[test] + fn take_public_staging_token_ignores_other_drivers() { + let mut sandbox = Sandbox { + spec: Some(SandboxSpec { + template: Some(SandboxTemplate { + driver_config: Some(prost_types::Struct { + fields: std::iter::once(( + "docker".to_string(), + struct_value([("rootfs_tar_staging_token", string_value("tok-abc"))]), + )) + .collect(), + }), + ..Default::default() + }), + ..Default::default() + }), + ..Default::default() + }; + + assert!(take_public_staging_token(&mut sandbox, "vm").is_none()); + } + + #[test] + fn set_rootfs_tar_path_writes_into_the_driver_copy() { + let mut driver_sandbox = DriverSandbox { + spec: Some(DriverSandboxSpec { + template: Some(DriverSandboxTemplate::default()), + ..Default::default() + }), + ..Default::default() + }; + + set_rootfs_tar_path(&mut driver_sandbox, Path::new("/staging/req-a/r.tar")); + + let config = driver_sandbox + .spec + .as_ref() + .and_then(|s| s.template.as_ref()) + .and_then(|t| t.driver_config.as_ref()) + .expect("driver config"); + let Some(prost_types::value::Kind::StringValue(path)) = + config.fields["rootfs_tar_path"].kind.as_ref() + else { + panic!("rootfs_tar_path must be a string"); + }; + assert_eq!(path, "/staging/req-a/r.tar"); + } + #[test] fn select_driver_config_rejects_non_object_matching_driver_block() { let config = prost_types::Struct { @@ -5565,6 +5818,7 @@ mod tests { lifecycle_gates: Arc::new(LifecycleGateRegistry::default()), gateway_listener_requirements: Vec::new(), replica_id: "test-replica".to_string(), + rootfs_tar_staging: Arc::new(rootfs_tar::RootfsTarStagingRegistry::disabled()), } } diff --git a/crates/openshell-server/src/compute/rootfs_tar.rs b/crates/openshell-server/src/compute/rootfs_tar.rs new file mode 100644 index 0000000000..f14759d8e5 --- /dev/null +++ b/crates/openshell-server/src/compute/rootfs_tar.rs @@ -0,0 +1,693 @@ +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Gateway-owned staging slots for rootfs tar archives. +//! +//! A sandbox created from a flat rootfs tar needs the archive on the gateway +//! host before the compute driver can turn it into a disk. Callers never name +//! that location. The gateway allocates a request-scoped directory inside the +//! driver-advertised staging root and hands back an opaque single-use token; +//! `CreateSandbox` carries the token, and the gateway substitutes the resolved +//! path into the driver-native request. A caller-supplied `rootfs_tar_path` is +//! rejected outright during request validation, so a raw host path can never +//! reach the privileged driver. + +use std::collections::HashMap; +use std::path::{Component, Path, PathBuf}; +use std::sync::Mutex; +use std::time::{Duration, Instant}; + +use openshell_core::time::now_ms; +use rand::RngCore; +use tonic::Status; +use tracing::{info, warn}; + +/// How long an allocated slot survives without being consumed. +const STAGING_TOKEN_TTL: Duration = Duration::from_secs(30 * 60); +/// Outstanding slots one caller may hold. Bounds the directories a single +/// authenticated caller can create by calling `begin` in a loop. +const MAX_SLOTS_PER_CALLER: usize = 4; +/// Outstanding slots across all callers. Per-caller alone would let enough +/// distinct callers exhaust the staging filesystem; a global cap alone would +/// let one caller starve everyone else. +const MAX_TOTAL_SLOTS: usize = 64; +const STAGING_DIR_PREFIX: &str = "req-"; +const MAX_STAGED_FILE_NAME_LEN: usize = 128; + +/// `driver_config.` key the CLI sets to redeem a staging slot. +pub const STAGING_TOKEN_FIELD: &str = "rootfs_tar_staging_token"; +/// `driver_config.` key the gateway substitutes for the driver. Callers +/// may never set this themselves. +pub const ROOTFS_TAR_PATH_FIELD: &str = "rootfs_tar_path"; + +/// Deliberately identical for unknown and expired tokens: distinguishing them +/// would let a caller probe which tokens exist. +fn unknown_token() -> Status { + Status::failed_precondition( + "rootfs tar staging token is unknown or expired; re-stage the archive", + ) +} + +/// A slot handed back to the client by `BeginRootfsTarStaging`. +#[derive(Debug, Clone)] +pub struct StagingSlot { + pub token: String, + pub upload_path: PathBuf, + pub max_bytes: u64, + pub expires_at_ms: i64, +} + +#[derive(Debug)] +struct StagingEntry { + dir: PathBuf, + file: PathBuf, + workspace: String, + subject: String, + expires_at: Instant, +} + +/// Ownership of a consumed staging directory. +/// +/// Removes the directory on drop so every failure path after the token is +/// consumed cleans up, unless [`StagedRootfsTar::disarm`] has transferred +/// ownership to the driver (which deletes it once the archive is extracted). +#[derive(Debug)] +pub struct StagedRootfsTar { + path: PathBuf, + dir: Option, +} + +impl StagedRootfsTar { + pub fn path(&self) -> &Path { + &self.path + } + + /// Hand the directory to the driver, which removes it after staging. + pub fn disarm(&mut self) { + self.dir = None; + } +} + +impl Drop for StagedRootfsTar { + fn drop(&mut self) { + let Some(dir) = self.dir.take() else { + return; + }; + // Unlinking is a syscall, but a multi-GiB file makes it worth keeping + // off a reactor thread. + match tokio::runtime::Handle::try_current() { + Ok(handle) => { + handle.spawn_blocking(move || remove_staging_dir(&dir)); + } + Err(_) => remove_staging_dir(&dir), + } + } +} + +fn remove_staging_dir(dir: &Path) { + if let Err(err) = std::fs::remove_dir_all(dir) + && err.kind() != std::io::ErrorKind::NotFound + { + warn!( + dir = %dir.display(), + error = %err, + "Failed to remove rootfs tar staging directory" + ); + } +} + +/// Request-scoped staging slots, keyed by opaque single-use token. +#[derive(Debug)] +pub struct RootfsTarStagingRegistry { + /// `None` when the active driver does not support rootfs tar sources. + staging_root: Option, + max_bytes: u64, + entries: Mutex>, + ttl: Duration, +} + +impl RootfsTarStagingRegistry { + pub fn new(staging_root: Option, max_bytes: u64) -> Self { + Self::with_ttl(staging_root, max_bytes, STAGING_TOKEN_TTL) + } + + fn with_ttl(staging_root: Option, max_bytes: u64, ttl: Duration) -> Self { + Self { + staging_root, + max_bytes, + entries: Mutex::new(HashMap::new()), + ttl, + } + } + + /// Registry for a driver that does not accept rootfs tar sources. + #[cfg(test)] + pub fn disabled() -> Self { + Self::new(None, 0) + } + + /// Allocate a request-scoped directory and return its single-use token. + pub fn begin( + &self, + workspace: &str, + subject: &str, + file_name: &str, + size_bytes: u64, + ) -> Result { + let Some(staging_root) = self.staging_root.as_ref() else { + return Err(Status::failed_precondition( + "the active compute driver does not support rootfs tar sources", + )); + }; + + if self.max_bytes > 0 && size_bytes > self.max_bytes { + return Err(Status::invalid_argument(format!( + "rootfs tar is {size_bytes} bytes, exceeding the driver limit of {} bytes", + self.max_bytes + ))); + } + + let file_name = sanitize_staged_file_name(file_name)?; + + let mut entries = self.entries.lock().expect("staging registry poisoned"); + Self::purge_expired(&mut entries); + if entries.len() >= MAX_TOTAL_SLOTS { + return Err(Status::resource_exhausted( + "the gateway has too many outstanding rootfs tar staging slots; retry shortly", + )); + } + let held_by_caller = entries + .values() + .filter(|entry| entry.workspace == workspace && entry.subject == subject) + .count(); + if held_by_caller >= MAX_SLOTS_PER_CALLER { + return Err(Status::resource_exhausted( + "too many outstanding rootfs tar staging slots; retry once an earlier create completes", + )); + } + + // The directory name uses independent randomness so the token never + // appears in a filesystem path, a directory listing, or a log field. + let dir = staging_root.join(format!("{STAGING_DIR_PREFIX}{}", uuid::Uuid::new_v4())); + create_private_dir(&dir).map_err(|err| { + Status::internal(format!( + "failed to create rootfs tar staging directory: {err}" + )) + })?; + + let file = dir.join(&file_name); + let token = new_staging_token(); + let expires_at = Instant::now() + self.ttl; + let expires_at_ms = now_ms() + i64::try_from(self.ttl.as_millis()).unwrap_or(i64::MAX); + + entries.insert( + token.clone(), + StagingEntry { + dir, + file: file.clone(), + workspace: workspace.to_string(), + subject: subject.to_string(), + expires_at, + }, + ); + + Ok(StagingSlot { + token, + upload_path: file, + max_bytes: self.max_bytes, + expires_at_ms, + }) + } + + /// Confirm the token belongs to this caller. Does not consume it. + /// + /// This is what stops one caller redeeming a slot minted for another. + pub fn authorize(&self, token: &str, workspace: &str, subject: &str) -> Result<(), Status> { + let mut entries = self.entries.lock().expect("staging registry poisoned"); + Self::purge_expired(&mut entries); + let entry = entries.get(token).ok_or_else(unknown_token)?; + if entry.workspace != workspace || entry.subject != subject { + return Err(Status::permission_denied( + "rootfs tar staging token was issued to a different caller", + )); + } + Ok(()) + } + + /// Resolve the staged path without consuming the token, for validation. + pub fn peek(&self, token: &str) -> Result { + let mut entries = self.entries.lock().expect("staging registry poisoned"); + Self::purge_expired(&mut entries); + let entry = entries.get(token).ok_or_else(unknown_token)?; + Ok(entry.file.clone()) + } + + /// Consume the token. A second redemption of the same token fails. + pub fn consume(&self, token: &str) -> Result { + let mut entries = self.entries.lock().expect("staging registry poisoned"); + Self::purge_expired(&mut entries); + let entry = entries.remove(token).ok_or_else(unknown_token)?; + drop(entries); + + if !entry.file.is_file() { + // Nothing was uploaded, or it was replaced by a directory or link. + remove_staging_dir(&entry.dir); + return Err(Status::failed_precondition(format!( + "no rootfs tar archive was uploaded to the staging slot at {}", + entry.file.display() + ))); + } + + Ok(StagedRootfsTar { + path: entry.file, + dir: Some(entry.dir), + }) + } + + fn purge_expired(entries: &mut HashMap) { + let now = Instant::now(); + let expired: Vec = entries + .iter() + .filter(|(_, entry)| entry.expires_at <= now) + .map(|(token, _)| token.clone()) + .collect(); + for token in expired { + if let Some(entry) = entries.remove(&token) { + remove_staging_dir(&entry.dir); + } + } + } + + /// Remove request directories nothing owns any more. + /// + /// Runs at startup and on each reconcile sweep. It catches two cases the + /// token table cannot: directories left by a previous gateway process, and + /// directories whose token was consumed but whose driver failed before it + /// reached its own cleanup. + /// + /// Age-gated rather than an unconditional wipe, because a driver can still + /// be copying a multi-gigabyte archive out of a directory whose gateway + /// already restarted. + pub fn sweep_orphans(&self) { + let Some(staging_root) = self.staging_root.as_ref() else { + return; + }; + let Ok(read_dir) = std::fs::read_dir(staging_root) else { + return; + }; + + let mut removed = 0usize; + for entry in read_dir.flatten() { + let name = entry.file_name(); + let Some(name) = name.to_str() else { continue }; + if !name.starts_with(STAGING_DIR_PREFIX) { + continue; + } + let stale = entry + .metadata() + .and_then(|meta| meta.modified()) + .is_ok_and(|modified| modified.elapsed().is_ok_and(|age| age > self.ttl)); + if stale { + remove_staging_dir(&entry.path()); + removed += 1; + } + } + + if removed > 0 { + info!( + removed, + staging_root = %staging_root.display(), + "Removed orphaned rootfs tar staging directories" + ); + } + } +} + +fn new_staging_token() -> String { + let mut raw = [0u8; 32]; + rand::rng().fill_bytes(&mut raw); + hex::encode(raw) +} + +/// Reject anything that would let `dir.join(file_name)` escape the request +/// directory. This is the check that makes the joined path safe to trust. +fn sanitize_staged_file_name(file_name: &str) -> Result { + let invalid = |reason: &str| Status::invalid_argument(format!("rootfs tar file_name {reason}")); + + if file_name.is_empty() { + return Err(invalid("must not be empty")); + } + if file_name.len() > MAX_STAGED_FILE_NAME_LEN { + return Err(invalid(&format!( + "must be at most {MAX_STAGED_FILE_NAME_LEN} bytes" + ))); + } + if file_name.contains('/') || file_name.contains('\\') || file_name.contains('\0') { + return Err(invalid("must not contain path separators")); + } + if file_name.starts_with('.') { + return Err(invalid("must not start with '.'")); + } + + let path = Path::new(file_name); + let mut components = path.components(); + let Some(Component::Normal(only)) = components.next() else { + return Err(invalid("must be a plain file name")); + }; + if components.next().is_some() { + return Err(invalid("must be a plain file name")); + } + if only != file_name { + return Err(invalid("must be a plain file name")); + } + + Ok(file_name.to_string()) +} + +fn create_private_dir(dir: &Path) -> std::io::Result<()> { + std::fs::create_dir(dir)?; + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + std::fs::set_permissions(dir, std::fs::Permissions::from_mode(0o700))?; + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use tonic::Code; + + fn registry(root: &Path) -> RootfsTarStagingRegistry { + RootfsTarStagingRegistry::new(Some(root.to_path_buf()), 1024) + } + + fn temp_root() -> tempfile::TempDir { + tempfile::tempdir().expect("create staging root") + } + + fn upload(slot: &StagingSlot, contents: &[u8]) { + std::fs::write(&slot.upload_path, contents).expect("write staged archive"); + } + + #[test] + fn begin_allocates_private_request_dir_and_hides_the_token() { + let root = temp_root(); + let registry = registry(root.path()); + + let slot = registry + .begin("default", "alice", "rootfs.tar", 128) + .expect("slot allocated"); + + let dir = slot.upload_path.parent().expect("upload dir"); + assert!(dir.starts_with(root.path())); + assert!( + dir.file_name() + .and_then(|n| n.to_str()) + .expect("dir name") + .starts_with(STAGING_DIR_PREFIX) + ); + assert_eq!(slot.upload_path.file_name().unwrap(), "rootfs.tar"); + assert!( + !slot.upload_path.to_string_lossy().contains(&slot.token), + "the token must not be recoverable from a directory listing" + ); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mode = std::fs::metadata(dir) + .expect("dir metadata") + .permissions() + .mode(); + assert_eq!(mode & 0o777, 0o700); + } + } + + #[test] + fn begin_rejects_oversized_archive_before_allocating() { + let root = temp_root(); + let registry = registry(root.path()); + + let err = registry + .begin("default", "alice", "rootfs.tar", 4096) + .expect_err("oversized archive rejected"); + + assert_eq!(err.code(), Code::InvalidArgument); + assert_eq!( + std::fs::read_dir(root.path()).unwrap().count(), + 0, + "nothing may be allocated for a rejected request" + ); + } + + /// `dir.join(file_name)` must not be able to escape the request directory. + #[test] + fn begin_rejects_traversal_file_names() { + let root = temp_root(); + let registry = registry(root.path()); + + let too_long = "x".repeat(MAX_STAGED_FILE_NAME_LEN + 1); + for name in [ + "../../etc/passwd", + "a/b.tar", + "..", + "", + "\\evil.tar", + ".hidden.tar", + too_long.as_str(), + ] { + let err = match registry.begin("default", "alice", name, 16) { + Ok(slot) => panic!("expected rejection for {name:?}, allocated {slot:?}"), + Err(err) => err, + }; + assert_eq!(err.code(), Code::InvalidArgument, "{name:?}: {err}"); + } + + assert_eq!( + std::fs::read_dir(root.path()).unwrap().count(), + 0, + "a rejected file name must not leave a directory behind" + ); + } + + #[test] + fn begin_rejects_when_driver_has_no_staging_dir() { + let registry = RootfsTarStagingRegistry::disabled(); + + let err = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect_err("a driver without tar support rejects staging"); + + assert_eq!(err.code(), Code::FailedPrecondition); + } + + #[test] + fn begin_bounds_outstanding_slots_per_caller() { + let root = temp_root(); + let registry = registry(root.path()); + + for _ in 0..MAX_SLOTS_PER_CALLER { + registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + } + + let err = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect_err("one caller's outstanding slots are bounded"); + assert_eq!(err.code(), Code::ResourceExhausted); + } + + /// The per-caller cap must not become a way for one caller to lock others + /// out of the feature. + #[test] + fn one_caller_at_its_cap_does_not_block_another() { + let root = temp_root(); + let registry = registry(root.path()); + + for _ in 0..MAX_SLOTS_PER_CALLER { + registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + } + + registry + .begin("default", "bob", "rootfs.tar", 16) + .expect("a different caller is unaffected"); + registry + .begin("other-workspace", "alice", "rootfs.tar", 16) + .expect("the same caller in another workspace is unaffected"); + } + + /// The replay regression test: a token redeemed twice must fail. + #[test] + fn consume_is_single_use() { + let root = temp_root(); + let registry = registry(root.path()); + let slot = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + upload(&slot, b"payload"); + + let mut staged = registry.consume(&slot.token).expect("first consume"); + staged.disarm(); + + let err = registry + .consume(&slot.token) + .expect_err("a staging token may only be redeemed once"); + assert_eq!(err.code(), Code::FailedPrecondition); + } + + /// Validation peeks and creation consumes; peeking must not burn the token. + #[test] + fn peek_does_not_consume() { + let root = temp_root(); + let registry = registry(root.path()); + let slot = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + upload(&slot, b"payload"); + + assert_eq!(registry.peek(&slot.token).unwrap(), slot.upload_path); + assert_eq!(registry.peek(&slot.token).unwrap(), slot.upload_path); + + let mut staged = registry.consume(&slot.token).expect("consume after peeks"); + staged.disarm(); + } + + #[test] + fn unknown_token_is_rejected_the_same_way_as_an_expired_one() { + let root = temp_root(); + let registry = registry(root.path()); + + let unknown = registry + .consume(&"0".repeat(64)) + .expect_err("unknown token"); + + let expiring = RootfsTarStagingRegistry::with_ttl( + Some(root.path().to_path_buf()), + 1024, + Duration::ZERO, + ); + let slot = expiring + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + upload(&slot, b"payload"); + let expired = expiring.consume(&slot.token).expect_err("expired token"); + + assert_eq!(unknown.code(), expired.code()); + assert_eq!(unknown.message(), expired.message()); + } + + #[test] + fn expired_slot_directory_is_removed() { + let root = temp_root(); + let registry = RootfsTarStagingRegistry::with_ttl( + Some(root.path().to_path_buf()), + 1024, + Duration::ZERO, + ); + let slot = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + upload(&slot, b"payload"); + let dir = slot.upload_path.parent().unwrap().to_path_buf(); + + let _ = registry.consume(&slot.token); + + assert!(!dir.exists(), "an expired slot must not leave data behind"); + } + + /// The cross-request regression test the review asked for by name. + #[test] + fn authorize_rejects_another_caller() { + let root = temp_root(); + let registry = registry(root.path()); + let slot = registry + .begin("team-a", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + + for (workspace, subject) in [("team-b", "alice"), ("team-a", "bob")] { + let err = registry + .authorize(&slot.token, workspace, subject) + .expect_err("a token minted for another caller must be refused"); + assert_eq!(err.code(), Code::PermissionDenied); + } + + registry + .authorize(&slot.token, "team-a", "alice") + .expect("the rightful owner still holds the slot"); + } + + #[test] + fn consume_rejects_a_slot_that_was_never_uploaded_to() { + let root = temp_root(); + let registry = registry(root.path()); + let slot = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + + let err = registry + .consume(&slot.token) + .expect_err("an empty slot cannot be created from"); + + assert_eq!(err.code(), Code::FailedPrecondition); + } + + #[test] + fn staged_guard_removes_directory_unless_disarmed() { + let root = temp_root(); + let registry = registry(root.path()); + + let slot = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + upload(&slot, b"payload"); + let dir = slot.upload_path.parent().unwrap().to_path_buf(); + drop(registry.consume(&slot.token).expect("consume")); + assert!(!dir.exists(), "dropping the guard must clean up"); + + let slot = registry + .begin("default", "alice", "rootfs.tar", 16) + .expect("slot allocated"); + upload(&slot, b"payload"); + let dir = slot.upload_path.parent().unwrap().to_path_buf(); + let mut staged = registry.consume(&slot.token).expect("consume"); + staged.disarm(); + drop(staged); + assert!( + dir.exists(), + "a disarmed guard leaves the dir to the driver" + ); + } + + #[test] + fn orphan_sweep_removes_only_stale_request_dirs() { + let root = temp_root(); + let stale = root.path().join("req-stale"); + let fresh = root.path().join("req-fresh"); + let unrelated = root.path().join("keep-me"); + for dir in [&stale, &fresh, &unrelated] { + std::fs::create_dir(dir).expect("create dir"); + } + + // A long TTL means nothing on disk has aged out yet. This is what keeps + // a restart from wiping a directory the driver is still copying from. + let young = RootfsTarStagingRegistry::new(Some(root.path().to_path_buf()), 1024); + young.sweep_orphans(); + assert!(stale.exists() && fresh.exists() && unrelated.exists()); + + // A zero TTL ages everything out, but only request directories are ours. + let aged = RootfsTarStagingRegistry::with_ttl( + Some(root.path().to_path_buf()), + 1024, + Duration::ZERO, + ); + aged.sweep_orphans(); + + assert!(!stale.exists()); + assert!(!fresh.exists()); + assert!(unrelated.exists(), "unrelated entries must be left alone"); + } +} diff --git a/crates/openshell-server/src/grpc/mod.rs b/crates/openshell-server/src/grpc/mod.rs index 405a99f9d3..ddbb5940f6 100644 --- a/crates/openshell-server/src/grpc/mod.rs +++ b/crates/openshell-server/src/grpc/mod.rs @@ -14,22 +14,22 @@ pub mod workspace; use openshell_core::proto::{ AddWorkspaceMemberRequest, AddWorkspaceMemberResponse, ApproveAllDraftChunksRequest, ApproveAllDraftChunksResponse, ApproveDraftChunkRequest, ApproveDraftChunkResponse, - AttachSandboxProviderRequest, AttachSandboxProviderResponse, ClearDraftChunksRequest, - ClearDraftChunksResponse, ComputeDriverCapabilities, ComputeDriverInfo, - ConfigureProviderRefreshRequest, ConfigureProviderRefreshResponse, CpuResourceCapabilities, - CreateProviderRequest, CreateSandboxRequest, CreateSandboxTemplateRequest, - CreateSshSessionRequest, CreateSshSessionResponse, CreateWorkspaceRequest, - CreateWorkspaceResponse, DeleteProviderProfileRequest, DeleteProviderProfileResponse, - DeleteProviderRefreshRequest, DeleteProviderRefreshResponse, DeleteProviderRequest, - DeleteProviderResponse, DeleteSandboxRequest, DeleteSandboxResponse, - DeleteSandboxTemplateRequest, DeleteSandboxTemplateResponse, DeleteServiceRequest, - DeleteServiceResponse, DeleteWorkspaceRequest, DeleteWorkspaceResponse, - DetachSandboxProviderRequest, DetachSandboxProviderResponse, EditDraftChunkRequest, - EditDraftChunkResponse, ExchangeProviderSubjectTokenRequest, - ExchangeProviderSubjectTokenResponse, ExecSandboxEvent, ExecSandboxInput, ExecSandboxRequest, - ExposeServiceRequest, FinalizeMainProcessExitRequest, FinalizeMainProcessExitResponse, - GatewayMessage, GetCurrentUserRequest, GetCurrentUserResponse, GetDraftHistoryRequest, - GetDraftHistoryResponse, GetDraftPolicyRequest, GetDraftPolicyResponse, + AttachSandboxProviderRequest, AttachSandboxProviderResponse, BeginRootfsTarStagingRequest, + BeginRootfsTarStagingResponse, ClearDraftChunksRequest, ClearDraftChunksResponse, + ComputeDriverCapabilities, ComputeDriverInfo, ConfigureProviderRefreshRequest, + ConfigureProviderRefreshResponse, CpuResourceCapabilities, CreateProviderRequest, + CreateSandboxRequest, CreateSandboxTemplateRequest, CreateSshSessionRequest, + CreateSshSessionResponse, CreateWorkspaceRequest, CreateWorkspaceResponse, + DeleteProviderProfileRequest, DeleteProviderProfileResponse, DeleteProviderRefreshRequest, + DeleteProviderRefreshResponse, DeleteProviderRequest, DeleteProviderResponse, + DeleteSandboxRequest, DeleteSandboxResponse, DeleteSandboxTemplateRequest, + DeleteSandboxTemplateResponse, DeleteServiceRequest, DeleteServiceResponse, + DeleteWorkspaceRequest, DeleteWorkspaceResponse, DetachSandboxProviderRequest, + DetachSandboxProviderResponse, EditDraftChunkRequest, EditDraftChunkResponse, + ExchangeProviderSubjectTokenRequest, ExchangeProviderSubjectTokenResponse, ExecSandboxEvent, + ExecSandboxInput, ExecSandboxRequest, ExposeServiceRequest, FinalizeMainProcessExitRequest, + FinalizeMainProcessExitResponse, GatewayMessage, GetCurrentUserRequest, GetCurrentUserResponse, + GetDraftHistoryRequest, GetDraftHistoryResponse, GetDraftPolicyRequest, GetDraftPolicyResponse, GetGatewayConfigRequest, GetGatewayConfigResponse, GetGatewayInfoRequest, GetGatewayInfoResponse, GetProviderProfileRequest, GetProviderRefreshStatusRequest, GetProviderRefreshStatusResponse, GetProviderRequest, GetSandboxConfigRequest, @@ -264,8 +264,6 @@ impl OpenShell for OpenShellService { .resource_capabilities .as_ref() .map(|resources| public_resource_capabilities(*resources)), - rootfs_tar_staging_dir: driver.rootfs_tar_staging_dir.clone(), - rootfs_tar_max_bytes: driver.rootfs_tar_max_bytes, }), }) .collect(); @@ -286,6 +284,13 @@ impl OpenShell for OpenShellService { sandbox::handle_create_sandbox(&self.state, request).await } + async fn begin_rootfs_tar_staging( + &self, + request: Request, + ) -> Result, Status> { + sandbox::handle_begin_rootfs_tar_staging(&self.state, request).await + } + type WatchSandboxStream = sandbox::WatchSandboxStream; async fn watch_sandbox( diff --git a/crates/openshell-server/src/grpc/sandbox.rs b/crates/openshell-server/src/grpc/sandbox.rs index 64fd40cee2..e0ff130ebc 100644 --- a/crates/openshell-server/src/grpc/sandbox.rs +++ b/crates/openshell-server/src/grpc/sandbox.rs @@ -32,7 +32,10 @@ use openshell_core::proto::{ TcpForwardFrame, TcpForwardInit, TcpRelayTarget, WatchSandboxRequest, relay_open, tcp_forward_init, }; -use openshell_core::proto::{Sandbox, SandboxPhase, SandboxTemplate, SshSession}; +use openshell_core::proto::{ + BeginRootfsTarStagingRequest, BeginRootfsTarStagingResponse, Sandbox, SandboxPhase, + SandboxTemplate, SshSession, +}; use openshell_core::telemetry::{ LifecycleOperation, LifecycleResource, SandboxTemplateSource, TelemetryOutcome, }; @@ -179,6 +182,73 @@ pub(super) async fn handle_create_sandbox( result } +/// Allocate a gateway-owned staging slot for a local rootfs tar archive. +/// +/// The caller writes the archive to the returned path and then names the token +/// on `CreateSandbox`. It never names a filesystem path of its own choosing. +pub(super) async fn handle_begin_rootfs_tar_staging( + state: &Arc, + request: Request, +) -> Result, Status> { + let principal = super::extract_principal(&request)?; + let request = request.into_inner(); + + let authz = authorize_workspace( + &state.store, + &state.admin_role, + &principal, + &request.workspace, + MinWorkspaceRole::User, + ) + .await?; + let workspace = super::workspace::resolve_workspace(state.store.as_ref(), &authz.workspace) + .await? + .ensure_active()?; + + let subject = principal_subject(&principal)?; + let slot = state.compute.rootfs_tar_staging().begin( + &workspace, + &subject, + &request.file_name, + request.size_bytes, + )?; + + Ok(Response::new(BeginRootfsTarStagingResponse { + staging_token: slot.token, + upload_path: slot.upload_path.to_string_lossy().into_owned(), + max_bytes: slot.max_bytes, + expires_at_ms: slot.expires_at_ms, + })) +} + +/// Stable caller identity used to bind a staging slot to its requester. +fn principal_subject(principal: &crate::auth::principal::Principal) -> Result { + match principal { + crate::auth::principal::Principal::User(user) => Ok(user.identity.subject.clone()), + _ => Err(Status::permission_denied( + "rootfs tar staging requires a user principal", + )), + } +} + +/// Read the staging token a caller named for the active driver, without +/// removing it. The gateway consumes it later, inside `create_sandbox`. +fn staging_token_in_spec(spec: &SandboxSpec, driver_name: &str) -> Option { + let config = spec.template.as_ref()?.driver_config.as_ref()?; + let Kind::StructValue(driver_config) = config.fields.get(driver_name)?.kind.as_ref()? else { + return None; + }; + match driver_config + .fields + .get(crate::compute::rootfs_tar::STAGING_TOKEN_FIELD)? + .kind + .as_ref()? + { + Kind::StringValue(token) => Some(token.clone()), + _ => None, + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct SandboxCreateTelemetryAttrs { requested_gpu: bool, @@ -309,6 +379,16 @@ async fn handle_create_sandbox_inner( // Validate field sizes before any create-side effects. validate_sandbox_spec(&request.name, &spec)?; + // A staging slot may only be redeemed by the caller it was issued to. This + // is the only point in the create path where the principal is in scope. + if let Some(token) = staging_token_in_spec(&spec, state.compute.configured_driver_name()) { + let subject = principal_subject(&principal)?; + state + .compute + .rootfs_tar_staging() + .authorize(&token, &workspace, &subject)?; + } + let _sandbox_sync_guard = if spec.providers.is_empty() { None } else { diff --git a/crates/openshell-server/src/grpc/validation.rs b/crates/openshell-server/src/grpc/validation.rs index 2f22199df1..dac34524c1 100644 --- a/crates/openshell-server/src/grpc/validation.rs +++ b/crates/openshell-server/src/grpc/validation.rs @@ -332,11 +332,36 @@ fn validate_sandbox_template(tmpl: &SandboxTemplate) -> Result<(), Status> { "template.driver_config serialized size exceeds maximum ({size} > {MAX_TEMPLATE_STRUCT_SIZE})" ))); } + reject_gateway_owned_driver_config_keys(s)?; } Ok(()) } +/// `driver_config` fields the gateway resolves and writes itself. +/// +/// A caller who could set these would hand a raw host path straight to a +/// privileged compute driver. Clients name a staging token instead, and the +/// gateway substitutes the path it allocated. +const GATEWAY_OWNED_DRIVER_CONFIG_KEYS: &[&str] = &["rootfs_tar_path"]; + +fn reject_gateway_owned_driver_config_keys(config: &prost_types::Struct) -> Result<(), Status> { + for (driver_name, value) in &config.fields { + let Some(prost_types::value::Kind::StructValue(driver_config)) = value.kind.as_ref() else { + continue; + }; + for key in GATEWAY_OWNED_DRIVER_CONFIG_KEYS { + if driver_config.fields.contains_key(*key) { + return Err(Status::invalid_argument(format!( + "template.driver_config.{driver_name}.{key} is set by the gateway \ + and cannot be supplied by the caller" + ))); + } + } + } + Ok(()) +} + /// Validate a `map` field: entry count, key length, value length. pub(super) fn validate_string_map( map: &std::collections::HashMap, @@ -2267,4 +2292,43 @@ mod tests { let err = validate_exec_request_fields(&req).unwrap_err(); assert!(err.message().contains("newline")); } + + fn driver_config(json: &str) -> prost_types::Struct { + let serde_json::Value::Object(fields) = + serde_json::from_str::(json).expect("valid json") + else { + panic!("driver_config test input must be a JSON object"); + }; + openshell_core::proto_struct::json_object_to_struct(fields).expect("encodable") + } + + /// The security boundary: only the gateway may name a host path for the + /// compute driver. A direct API request that supplies one is refused. + #[test] + fn rejects_caller_supplied_rootfs_tar_path() { + for json in [ + r#"{"vm":{"rootfs_tar_path":"/etc/passwd"}}"#, + r#"{"vm":{"rootfs_tar_path":"/dev/zero"}}"#, + // Driver-agnostic: no driver block may carry a gateway-owned key. + r#"{"docker":{"rootfs_tar_path":"/etc/shadow"}}"#, + ] { + let err = reject_gateway_owned_driver_config_keys(&driver_config(json)) + .expect_err("a caller-supplied rootfs_tar_path must be rejected"); + assert_eq!(err.code(), Code::InvalidArgument, "{json}: {err}"); + assert!(err.message().contains("rootfs_tar_path"), "{json}: {err}"); + } + } + + #[test] + fn accepts_driver_config_without_gateway_owned_keys() { + for json in [ + r#"{"vm":{"rootfs_tar_staging_token":"tok-abc"}}"#, + r#"{"vm":{"gpu_device_ids":["0000:2d:00.0"]}}"#, + r#"{"kubernetes":{"pod":{"nodeName":"gpu-1"}}}"#, + r"{}", + ] { + reject_gateway_owned_driver_config_keys(&driver_config(json)) + .unwrap_or_else(|err| panic!("{json} should be accepted: {err}")); + } + } } diff --git a/crates/openshell-server/tests/common/mod.rs b/crates/openshell-server/tests/common/mod.rs index a60fc8696b..42711a7542 100644 --- a/crates/openshell-server/tests/common/mod.rs +++ b/crates/openshell-server/tests/common/mod.rs @@ -53,6 +53,13 @@ pub struct TestOpenShell; #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/crates/openshell-server/tests/supervisor_relay_integration.rs b/crates/openshell-server/tests/supervisor_relay_integration.rs index 91ac50dcbd..448ae2cc7b 100644 --- a/crates/openshell-server/tests/supervisor_relay_integration.rs +++ b/crates/openshell-server/tests/supervisor_relay_integration.rs @@ -48,6 +48,13 @@ struct RelayGateway { #[tonic::async_trait] impl OpenShell for RelayGateway { + async fn begin_rootfs_tar_staging( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn report_main_process_exit( &self, _request: tonic::Request, diff --git a/docs/reference/gateway-config.mdx b/docs/reference/gateway-config.mdx index 1c846c29a8..81c2411129 100644 --- a/docs/reference/gateway-config.mdx +++ b/docs/reference/gateway-config.mdx @@ -840,8 +840,21 @@ guest_tls_key = "/var/lib/openshell/guest-tls/client-key.pem" # proxy_connect_by_hostname = true # Corporate CA trusted for an https:// proxy and TLS-intercepting proxies. # proxy_ca_bundle = "/etc/openshell/tls/proxy-ca.pem" +# Where the gateway stages rootfs tar archives for `--from ./rootfs.tar`. +# Defaults to /rootfs-tar-staging. The gateway creates one +# request-scoped subdirectory per staging slot and removes it after use. +# rootfs_tar_staging_dir = "/var/lib/openshell/vm/rootfs-tar-staging" +# Largest rootfs tar archive the driver accepts, in bytes. Defaults to 10 GiB. +# rootfs_tar_max_bytes = 10737418240 ``` +Rootfs tar staging requires the gateway and the VM driver to share a filesystem +and run as the same user. That holds for the managed VM driver, which the +gateway starts as a subprocess. If you point `compute_driver_endpoints` at an +externally managed `vm` socket owned by another user, the driver cannot read the +gateway's staging directory and rootfs tar sources fail with a +`FAILED_PRECONDITION` error; use a registry image reference instead. + ### Extension Driver Extension drivers run outside the gateway and expose the diff --git a/docs/sandboxes/manage-sandboxes.mdx b/docs/sandboxes/manage-sandboxes.mdx index 0ea6d4c7d6..fffc6cf04c 100644 --- a/docs/sandboxes/manage-sandboxes.mdx +++ b/docs/sandboxes/manage-sandboxes.mdx @@ -157,10 +157,34 @@ openshell sandbox create --from my-registry.example.com/my-image:latest Bare names such as `base` and `ollama` resolve to images under `ghcr.io/nvidia/openshell-community/sandboxes`. Set `OPENSHELL_COMMUNITY_REGISTRY` when you need to use an internal mirror. Local directories and Dockerfiles require a local gateway because the CLI -builds images through the local Docker daemon. Rootfs tar archives -(`.tar`, `.tar.gz`, `.tgz`) also require a local gateway and are passed -directly to the VM compute driver. Use a registry image reference for remote -gateways. +builds images through the local Docker daemon. Use a registry image reference +for remote gateways. + +#### Rootfs Tar Archives + +A rootfs tar archive (`.tar`, `.tar.gz`, `.tgz`) is a flat filesystem produced +by `docker export`, `podman export`, or `buildah mount` plus `tar`. It lets you +create a sandbox without a registry or a running image daemon: + +```shell +docker create --name export-me my-image:latest +docker export -o rootfs.tar export-me +docker rm export-me + +openshell sandbox create --from ./rootfs.tar +``` + +Rootfs tar sources require a local gateway running the VM compute driver. The +CLI asks the gateway for a staging slot, writes the archive to the location the +gateway allocates, and passes back a single-use token; the gateway resolves that +token to a path for the driver. Because the CLI writes the archive directly to +the gateway host's filesystem, the two must share a filesystem and run as the +same user. Gateways using the Docker, Podman, or Kubernetes drivers reject +rootfs tar sources. + +The gateway caps archive size (10 GiB by default, configurable with the VM +driver's `rootfs_tar_max_bytes`), and reclaims an unused staging slot after 30 +minutes. ## Reuse Workload Templates diff --git a/proto/openshell.proto b/proto/openshell.proto index 5be2881a7a..1308eb6a20 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -52,6 +52,23 @@ service OpenShell { }; } + // Allocate a gateway-owned staging slot for a local rootfs tar archive. + // + // The gateway creates a request-scoped directory inside the compute driver's + // staging root and returns an opaque single-use token plus the absolute path + // the client must write the archive to. The token is then passed as + // `template.driver_config..rootfs_tar_staging_token` on + // CreateSandbox; callers never name a filesystem path themselves. Only a + // client sharing the gateway's filesystem can complete the upload. + rpc BeginRootfsTarStaging(BeginRootfsTarStagingRequest) + returns (BeginRootfsTarStagingResponse) { + option (openshell.options.v1.authorization) = { + auth_mode: "bearer" + scope: "sandbox:write" + workspace_role: "user" + }; + } + // Fetch a sandbox by name. rpc GetSandbox(GetSandboxRequest) returns (SandboxResponse) { option (openshell.options.v1.authorization) = { @@ -839,13 +856,6 @@ message ComputeDriverCapabilities { // Static portable resource request forms reported by the driver. ResourceCapabilities resource_capabilities = 3; - - // Absolute path where rootfs tar files must be staged before creating a - // sandbox. Empty when the driver does not support rootfs tar sources. - string rootfs_tar_staging_dir = 4; - - // Maximum rootfs tar file size in bytes accepted by the driver. - uint64 rootfs_tar_max_bytes = 5; } // Static portable resource request forms reported by a compute driver. @@ -1165,6 +1175,33 @@ message DeleteSandboxTemplateResponse { bool deleted = 1; } +// Request a gateway-owned staging slot for a local rootfs tar archive. +message BeginRootfsTarStagingRequest { + // Workspace that will own the sandbox created from this archive. Empty + // defaults to "default", matching CreateSandboxRequest.workspace. + string workspace = 1; + // Base file name of the local archive. The gateway uses it only to name the + // staged file; path separators and traversal components are rejected. + string file_name = 2; + // Size of the local archive in bytes, checked against the driver limit + // before the gateway allocates a slot. + uint64 size_bytes = 3; +} + +// Gateway-issued staging slot. +message BeginRootfsTarStagingResponse { + // Opaque single-use token. Pass it as + // `template.driver_config..rootfs_tar_staging_token` on + // CreateSandbox. The first CreateSandbox presenting it consumes it. + string staging_token = 1; + // Absolute path on the gateway host the client must write the archive to. + string upload_path = 2; + // Maximum accepted archive size in bytes, enforced again by the driver. + uint64 max_bytes = 3; + // Wall-clock deadline after which the gateway reclaims the slot. + int64 expires_at_ms = 4; +} + // Get sandbox request. message GetSandboxRequest { // Sandbox name (canonical lookup key). diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index 21e9d31ed3..58f1968a04 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -2938,6 +2938,148 @@ func (x *DeleteSandboxTemplateResponse) GetDeleted() bool { return false } +// Request a gateway-owned staging slot for a local rootfs tar archive. +type BeginRootfsTarStagingRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Workspace that will own the sandbox created from this archive. Empty + // defaults to "default", matching CreateSandboxRequest.workspace. + Workspace string `protobuf:"bytes,1,opt,name=workspace,proto3" json:"workspace,omitempty"` + // Base file name of the local archive. The gateway uses it only to name the + // staged file; path separators and traversal components are rejected. + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // Size of the local archive in bytes, checked against the driver limit + // before the gateway allocates a slot. + SizeBytes uint64 `protobuf:"varint,3,opt,name=size_bytes,json=sizeBytes,proto3" json:"size_bytes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BeginRootfsTarStagingRequest) Reset() { + *x = BeginRootfsTarStagingRequest{} + mi := &file_openshell_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BeginRootfsTarStagingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BeginRootfsTarStagingRequest) ProtoMessage() {} + +func (x *BeginRootfsTarStagingRequest) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BeginRootfsTarStagingRequest.ProtoReflect.Descriptor instead. +func (*BeginRootfsTarStagingRequest) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{39} +} + +func (x *BeginRootfsTarStagingRequest) GetWorkspace() string { + if x != nil { + return x.Workspace + } + return "" +} + +func (x *BeginRootfsTarStagingRequest) GetFileName() string { + if x != nil { + return x.FileName + } + return "" +} + +func (x *BeginRootfsTarStagingRequest) GetSizeBytes() uint64 { + if x != nil { + return x.SizeBytes + } + return 0 +} + +// Gateway-issued staging slot. +type BeginRootfsTarStagingResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Opaque single-use token. Pass it as + // `template.driver_config..rootfs_tar_staging_token` on + // CreateSandbox. The first CreateSandbox presenting it consumes it. + StagingToken string `protobuf:"bytes,1,opt,name=staging_token,json=stagingToken,proto3" json:"staging_token,omitempty"` + // Absolute path on the gateway host the client must write the archive to. + UploadPath string `protobuf:"bytes,2,opt,name=upload_path,json=uploadPath,proto3" json:"upload_path,omitempty"` + // Maximum accepted archive size in bytes, enforced again by the driver. + MaxBytes uint64 `protobuf:"varint,3,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` + // Wall-clock deadline after which the gateway reclaims the slot. + ExpiresAtMs int64 `protobuf:"varint,4,opt,name=expires_at_ms,json=expiresAtMs,proto3" json:"expires_at_ms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BeginRootfsTarStagingResponse) Reset() { + *x = BeginRootfsTarStagingResponse{} + mi := &file_openshell_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BeginRootfsTarStagingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BeginRootfsTarStagingResponse) ProtoMessage() {} + +func (x *BeginRootfsTarStagingResponse) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BeginRootfsTarStagingResponse.ProtoReflect.Descriptor instead. +func (*BeginRootfsTarStagingResponse) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{40} +} + +func (x *BeginRootfsTarStagingResponse) GetStagingToken() string { + if x != nil { + return x.StagingToken + } + return "" +} + +func (x *BeginRootfsTarStagingResponse) GetUploadPath() string { + if x != nil { + return x.UploadPath + } + return "" +} + +func (x *BeginRootfsTarStagingResponse) GetMaxBytes() uint64 { + if x != nil { + return x.MaxBytes + } + return 0 +} + +func (x *BeginRootfsTarStagingResponse) GetExpiresAtMs() int64 { + if x != nil { + return x.ExpiresAtMs + } + return 0 +} + // Get sandbox request. type GetSandboxRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2951,7 +3093,7 @@ type GetSandboxRequest struct { func (x *GetSandboxRequest) Reset() { *x = GetSandboxRequest{} - mi := &file_openshell_proto_msgTypes[39] + mi := &file_openshell_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2963,7 +3105,7 @@ func (x *GetSandboxRequest) String() string { func (*GetSandboxRequest) ProtoMessage() {} func (x *GetSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[39] + mi := &file_openshell_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2976,7 +3118,7 @@ func (x *GetSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxRequest.ProtoReflect.Descriptor instead. func (*GetSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{39} + return file_openshell_proto_rawDescGZIP(), []int{41} } func (x *GetSandboxRequest) GetName() string { @@ -3010,7 +3152,7 @@ type ListSandboxesRequest struct { func (x *ListSandboxesRequest) Reset() { *x = ListSandboxesRequest{} - mi := &file_openshell_proto_msgTypes[40] + mi := &file_openshell_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3022,7 +3164,7 @@ func (x *ListSandboxesRequest) String() string { func (*ListSandboxesRequest) ProtoMessage() {} func (x *ListSandboxesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[40] + mi := &file_openshell_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3035,7 +3177,7 @@ func (x *ListSandboxesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxesRequest.ProtoReflect.Descriptor instead. func (*ListSandboxesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{40} + return file_openshell_proto_rawDescGZIP(), []int{42} } func (x *ListSandboxesRequest) GetLimit() uint32 { @@ -3086,7 +3228,7 @@ type ListSandboxProvidersRequest struct { func (x *ListSandboxProvidersRequest) Reset() { *x = ListSandboxProvidersRequest{} - mi := &file_openshell_proto_msgTypes[41] + mi := &file_openshell_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3098,7 +3240,7 @@ func (x *ListSandboxProvidersRequest) String() string { func (*ListSandboxProvidersRequest) ProtoMessage() {} func (x *ListSandboxProvidersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[41] + mi := &file_openshell_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3111,7 +3253,7 @@ func (x *ListSandboxProvidersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxProvidersRequest.ProtoReflect.Descriptor instead. func (*ListSandboxProvidersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{41} + return file_openshell_proto_rawDescGZIP(), []int{43} } func (x *ListSandboxProvidersRequest) GetSandboxName() string { @@ -3148,7 +3290,7 @@ type AttachSandboxProviderRequest struct { func (x *AttachSandboxProviderRequest) Reset() { *x = AttachSandboxProviderRequest{} - mi := &file_openshell_proto_msgTypes[42] + mi := &file_openshell_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3160,7 +3302,7 @@ func (x *AttachSandboxProviderRequest) String() string { func (*AttachSandboxProviderRequest) ProtoMessage() {} func (x *AttachSandboxProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[42] + mi := &file_openshell_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3173,7 +3315,7 @@ func (x *AttachSandboxProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AttachSandboxProviderRequest.ProtoReflect.Descriptor instead. func (*AttachSandboxProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{42} + return file_openshell_proto_rawDescGZIP(), []int{44} } func (x *AttachSandboxProviderRequest) GetSandboxName() string { @@ -3224,7 +3366,7 @@ type DetachSandboxProviderRequest struct { func (x *DetachSandboxProviderRequest) Reset() { *x = DetachSandboxProviderRequest{} - mi := &file_openshell_proto_msgTypes[43] + mi := &file_openshell_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3236,7 +3378,7 @@ func (x *DetachSandboxProviderRequest) String() string { func (*DetachSandboxProviderRequest) ProtoMessage() {} func (x *DetachSandboxProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[43] + mi := &file_openshell_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3249,7 +3391,7 @@ func (x *DetachSandboxProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DetachSandboxProviderRequest.ProtoReflect.Descriptor instead. func (*DetachSandboxProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{43} + return file_openshell_proto_rawDescGZIP(), []int{45} } func (x *DetachSandboxProviderRequest) GetSandboxName() string { @@ -3293,7 +3435,7 @@ type DeleteSandboxRequest struct { func (x *DeleteSandboxRequest) Reset() { *x = DeleteSandboxRequest{} - mi := &file_openshell_proto_msgTypes[44] + mi := &file_openshell_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3305,7 +3447,7 @@ func (x *DeleteSandboxRequest) String() string { func (*DeleteSandboxRequest) ProtoMessage() {} func (x *DeleteSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[44] + mi := &file_openshell_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3318,7 +3460,7 @@ func (x *DeleteSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteSandboxRequest.ProtoReflect.Descriptor instead. func (*DeleteSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{44} + return file_openshell_proto_rawDescGZIP(), []int{46} } func (x *DeleteSandboxRequest) GetName() string { @@ -3348,7 +3490,7 @@ type StopSandboxRequest struct { func (x *StopSandboxRequest) Reset() { *x = StopSandboxRequest{} - mi := &file_openshell_proto_msgTypes[45] + mi := &file_openshell_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3360,7 +3502,7 @@ func (x *StopSandboxRequest) String() string { func (*StopSandboxRequest) ProtoMessage() {} func (x *StopSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[45] + mi := &file_openshell_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3373,7 +3515,7 @@ func (x *StopSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StopSandboxRequest.ProtoReflect.Descriptor instead. func (*StopSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{45} + return file_openshell_proto_rawDescGZIP(), []int{47} } func (x *StopSandboxRequest) GetName() string { @@ -3403,7 +3545,7 @@ type StartSandboxRequest struct { func (x *StartSandboxRequest) Reset() { *x = StartSandboxRequest{} - mi := &file_openshell_proto_msgTypes[46] + mi := &file_openshell_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3415,7 +3557,7 @@ func (x *StartSandboxRequest) String() string { func (*StartSandboxRequest) ProtoMessage() {} func (x *StartSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[46] + mi := &file_openshell_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3428,7 +3570,7 @@ func (x *StartSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartSandboxRequest.ProtoReflect.Descriptor instead. func (*StartSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{46} + return file_openshell_proto_rawDescGZIP(), []int{48} } func (x *StartSandboxRequest) GetName() string { @@ -3455,7 +3597,7 @@ type SandboxResponse struct { func (x *SandboxResponse) Reset() { *x = SandboxResponse{} - mi := &file_openshell_proto_msgTypes[47] + mi := &file_openshell_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3467,7 +3609,7 @@ func (x *SandboxResponse) String() string { func (*SandboxResponse) ProtoMessage() {} func (x *SandboxResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[47] + mi := &file_openshell_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3480,7 +3622,7 @@ func (x *SandboxResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxResponse.ProtoReflect.Descriptor instead. func (*SandboxResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{47} + return file_openshell_proto_rawDescGZIP(), []int{49} } func (x *SandboxResponse) GetSandbox() *Sandbox { @@ -3500,7 +3642,7 @@ type ListSandboxesResponse struct { func (x *ListSandboxesResponse) Reset() { *x = ListSandboxesResponse{} - mi := &file_openshell_proto_msgTypes[48] + mi := &file_openshell_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3512,7 +3654,7 @@ func (x *ListSandboxesResponse) String() string { func (*ListSandboxesResponse) ProtoMessage() {} func (x *ListSandboxesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[48] + mi := &file_openshell_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3525,7 +3667,7 @@ func (x *ListSandboxesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxesResponse.ProtoReflect.Descriptor instead. func (*ListSandboxesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{48} + return file_openshell_proto_rawDescGZIP(), []int{50} } func (x *ListSandboxesResponse) GetSandboxes() []*Sandbox { @@ -3545,7 +3687,7 @@ type ListSandboxProvidersResponse struct { func (x *ListSandboxProvidersResponse) Reset() { *x = ListSandboxProvidersResponse{} - mi := &file_openshell_proto_msgTypes[49] + mi := &file_openshell_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3557,7 +3699,7 @@ func (x *ListSandboxProvidersResponse) String() string { func (*ListSandboxProvidersResponse) ProtoMessage() {} func (x *ListSandboxProvidersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[49] + mi := &file_openshell_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3570,7 +3712,7 @@ func (x *ListSandboxProvidersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxProvidersResponse.ProtoReflect.Descriptor instead. func (*ListSandboxProvidersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{49} + return file_openshell_proto_rawDescGZIP(), []int{51} } func (x *ListSandboxProvidersResponse) GetProviders() []*datamodelv1.Provider { @@ -3592,7 +3734,7 @@ type AttachSandboxProviderResponse struct { func (x *AttachSandboxProviderResponse) Reset() { *x = AttachSandboxProviderResponse{} - mi := &file_openshell_proto_msgTypes[50] + mi := &file_openshell_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3604,7 +3746,7 @@ func (x *AttachSandboxProviderResponse) String() string { func (*AttachSandboxProviderResponse) ProtoMessage() {} func (x *AttachSandboxProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[50] + mi := &file_openshell_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3617,7 +3759,7 @@ func (x *AttachSandboxProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AttachSandboxProviderResponse.ProtoReflect.Descriptor instead. func (*AttachSandboxProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{50} + return file_openshell_proto_rawDescGZIP(), []int{52} } func (x *AttachSandboxProviderResponse) GetSandbox() *Sandbox { @@ -3646,7 +3788,7 @@ type DetachSandboxProviderResponse struct { func (x *DetachSandboxProviderResponse) Reset() { *x = DetachSandboxProviderResponse{} - mi := &file_openshell_proto_msgTypes[51] + mi := &file_openshell_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3658,7 +3800,7 @@ func (x *DetachSandboxProviderResponse) String() string { func (*DetachSandboxProviderResponse) ProtoMessage() {} func (x *DetachSandboxProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[51] + mi := &file_openshell_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3671,7 +3813,7 @@ func (x *DetachSandboxProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DetachSandboxProviderResponse.ProtoReflect.Descriptor instead. func (*DetachSandboxProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{51} + return file_openshell_proto_rawDescGZIP(), []int{53} } func (x *DetachSandboxProviderResponse) GetSandbox() *Sandbox { @@ -3698,7 +3840,7 @@ type DeleteSandboxResponse struct { func (x *DeleteSandboxResponse) Reset() { *x = DeleteSandboxResponse{} - mi := &file_openshell_proto_msgTypes[52] + mi := &file_openshell_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3710,7 +3852,7 @@ func (x *DeleteSandboxResponse) String() string { func (*DeleteSandboxResponse) ProtoMessage() {} func (x *DeleteSandboxResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[52] + mi := &file_openshell_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3723,7 +3865,7 @@ func (x *DeleteSandboxResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteSandboxResponse.ProtoReflect.Descriptor instead. func (*DeleteSandboxResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{52} + return file_openshell_proto_rawDescGZIP(), []int{54} } func (x *DeleteSandboxResponse) GetDeleted() bool { @@ -3744,7 +3886,7 @@ type CreateSshSessionRequest struct { func (x *CreateSshSessionRequest) Reset() { *x = CreateSshSessionRequest{} - mi := &file_openshell_proto_msgTypes[53] + mi := &file_openshell_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3756,7 +3898,7 @@ func (x *CreateSshSessionRequest) String() string { func (*CreateSshSessionRequest) ProtoMessage() {} func (x *CreateSshSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[53] + mi := &file_openshell_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3769,7 +3911,7 @@ func (x *CreateSshSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSshSessionRequest.ProtoReflect.Descriptor instead. func (*CreateSshSessionRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{53} + return file_openshell_proto_rawDescGZIP(), []int{55} } func (x *CreateSshSessionRequest) GetSandboxId() string { @@ -3812,7 +3954,7 @@ type CreateSshSessionResponse struct { func (x *CreateSshSessionResponse) Reset() { *x = CreateSshSessionResponse{} - mi := &file_openshell_proto_msgTypes[54] + mi := &file_openshell_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3824,7 +3966,7 @@ func (x *CreateSshSessionResponse) String() string { func (*CreateSshSessionResponse) ProtoMessage() {} func (x *CreateSshSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[54] + mi := &file_openshell_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3837,7 +3979,7 @@ func (x *CreateSshSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSshSessionResponse.ProtoReflect.Descriptor instead. func (*CreateSshSessionResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{54} + return file_openshell_proto_rawDescGZIP(), []int{56} } func (x *CreateSshSessionResponse) GetSandboxId() string { @@ -3908,7 +4050,7 @@ type ExposeServiceRequest struct { func (x *ExposeServiceRequest) Reset() { *x = ExposeServiceRequest{} - mi := &file_openshell_proto_msgTypes[55] + mi := &file_openshell_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3920,7 +4062,7 @@ func (x *ExposeServiceRequest) String() string { func (*ExposeServiceRequest) ProtoMessage() {} func (x *ExposeServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[55] + mi := &file_openshell_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3933,7 +4075,7 @@ func (x *ExposeServiceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExposeServiceRequest.ProtoReflect.Descriptor instead. func (*ExposeServiceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{55} + return file_openshell_proto_rawDescGZIP(), []int{57} } func (x *ExposeServiceRequest) GetSandbox() string { @@ -3986,7 +4128,7 @@ type GetServiceRequest struct { func (x *GetServiceRequest) Reset() { *x = GetServiceRequest{} - mi := &file_openshell_proto_msgTypes[56] + mi := &file_openshell_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3998,7 +4140,7 @@ func (x *GetServiceRequest) String() string { func (*GetServiceRequest) ProtoMessage() {} func (x *GetServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[56] + mi := &file_openshell_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4011,7 +4153,7 @@ func (x *GetServiceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetServiceRequest.ProtoReflect.Descriptor instead. func (*GetServiceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{56} + return file_openshell_proto_rawDescGZIP(), []int{58} } func (x *GetServiceRequest) GetSandbox() string { @@ -4054,7 +4196,7 @@ type ListServicesRequest struct { func (x *ListServicesRequest) Reset() { *x = ListServicesRequest{} - mi := &file_openshell_proto_msgTypes[57] + mi := &file_openshell_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4066,7 +4208,7 @@ func (x *ListServicesRequest) String() string { func (*ListServicesRequest) ProtoMessage() {} func (x *ListServicesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[57] + mi := &file_openshell_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4079,7 +4221,7 @@ func (x *ListServicesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServicesRequest.ProtoReflect.Descriptor instead. func (*ListServicesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{57} + return file_openshell_proto_rawDescGZIP(), []int{59} } func (x *ListServicesRequest) GetSandbox() string { @@ -4127,7 +4269,7 @@ type ListServicesResponse struct { func (x *ListServicesResponse) Reset() { *x = ListServicesResponse{} - mi := &file_openshell_proto_msgTypes[58] + mi := &file_openshell_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4139,7 +4281,7 @@ func (x *ListServicesResponse) String() string { func (*ListServicesResponse) ProtoMessage() {} func (x *ListServicesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[58] + mi := &file_openshell_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4152,7 +4294,7 @@ func (x *ListServicesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServicesResponse.ProtoReflect.Descriptor instead. func (*ListServicesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{58} + return file_openshell_proto_rawDescGZIP(), []int{60} } func (x *ListServicesResponse) GetServices() []*ServiceEndpointResponse { @@ -4177,7 +4319,7 @@ type DeleteServiceRequest struct { func (x *DeleteServiceRequest) Reset() { *x = DeleteServiceRequest{} - mi := &file_openshell_proto_msgTypes[59] + mi := &file_openshell_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4189,7 +4331,7 @@ func (x *DeleteServiceRequest) String() string { func (*DeleteServiceRequest) ProtoMessage() {} func (x *DeleteServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[59] + mi := &file_openshell_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4202,7 +4344,7 @@ func (x *DeleteServiceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteServiceRequest.ProtoReflect.Descriptor instead. func (*DeleteServiceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{59} + return file_openshell_proto_rawDescGZIP(), []int{61} } func (x *DeleteServiceRequest) GetSandbox() string { @@ -4237,7 +4379,7 @@ type DeleteServiceResponse struct { func (x *DeleteServiceResponse) Reset() { *x = DeleteServiceResponse{} - mi := &file_openshell_proto_msgTypes[60] + mi := &file_openshell_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4249,7 +4391,7 @@ func (x *DeleteServiceResponse) String() string { func (*DeleteServiceResponse) ProtoMessage() {} func (x *DeleteServiceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[60] + mi := &file_openshell_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4262,7 +4404,7 @@ func (x *DeleteServiceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteServiceResponse.ProtoReflect.Descriptor instead. func (*DeleteServiceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{60} + return file_openshell_proto_rawDescGZIP(), []int{62} } func (x *DeleteServiceResponse) GetDeleted() bool { @@ -4293,7 +4435,7 @@ type ServiceEndpoint struct { func (x *ServiceEndpoint) Reset() { *x = ServiceEndpoint{} - mi := &file_openshell_proto_msgTypes[61] + mi := &file_openshell_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4305,7 +4447,7 @@ func (x *ServiceEndpoint) String() string { func (*ServiceEndpoint) ProtoMessage() {} func (x *ServiceEndpoint) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[61] + mi := &file_openshell_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4318,7 +4460,7 @@ func (x *ServiceEndpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceEndpoint.ProtoReflect.Descriptor instead. func (*ServiceEndpoint) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{61} + return file_openshell_proto_rawDescGZIP(), []int{63} } func (x *ServiceEndpoint) GetMetadata() *datamodelv1.ObjectMeta { @@ -4374,7 +4516,7 @@ type ServiceEndpointResponse struct { func (x *ServiceEndpointResponse) Reset() { *x = ServiceEndpointResponse{} - mi := &file_openshell_proto_msgTypes[62] + mi := &file_openshell_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4386,7 +4528,7 @@ func (x *ServiceEndpointResponse) String() string { func (*ServiceEndpointResponse) ProtoMessage() {} func (x *ServiceEndpointResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[62] + mi := &file_openshell_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4399,7 +4541,7 @@ func (x *ServiceEndpointResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceEndpointResponse.ProtoReflect.Descriptor instead. func (*ServiceEndpointResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{62} + return file_openshell_proto_rawDescGZIP(), []int{64} } func (x *ServiceEndpointResponse) GetEndpoint() *ServiceEndpoint { @@ -4427,7 +4569,7 @@ type RevokeSshSessionRequest struct { func (x *RevokeSshSessionRequest) Reset() { *x = RevokeSshSessionRequest{} - mi := &file_openshell_proto_msgTypes[63] + mi := &file_openshell_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4439,7 +4581,7 @@ func (x *RevokeSshSessionRequest) String() string { func (*RevokeSshSessionRequest) ProtoMessage() {} func (x *RevokeSshSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[63] + mi := &file_openshell_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4452,7 +4594,7 @@ func (x *RevokeSshSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeSshSessionRequest.ProtoReflect.Descriptor instead. func (*RevokeSshSessionRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{63} + return file_openshell_proto_rawDescGZIP(), []int{65} } func (x *RevokeSshSessionRequest) GetToken() string { @@ -4473,7 +4615,7 @@ type RevokeSshSessionResponse struct { func (x *RevokeSshSessionResponse) Reset() { *x = RevokeSshSessionResponse{} - mi := &file_openshell_proto_msgTypes[64] + mi := &file_openshell_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4485,7 +4627,7 @@ func (x *RevokeSshSessionResponse) String() string { func (*RevokeSshSessionResponse) ProtoMessage() {} func (x *RevokeSshSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[64] + mi := &file_openshell_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4498,7 +4640,7 @@ func (x *RevokeSshSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeSshSessionResponse.ProtoReflect.Descriptor instead. func (*RevokeSshSessionResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{64} + return file_openshell_proto_rawDescGZIP(), []int{66} } func (x *RevokeSshSessionResponse) GetRevoked() bool { @@ -4541,7 +4683,7 @@ type ExecSandboxRequest struct { func (x *ExecSandboxRequest) Reset() { *x = ExecSandboxRequest{} - mi := &file_openshell_proto_msgTypes[65] + mi := &file_openshell_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4553,7 +4695,7 @@ func (x *ExecSandboxRequest) String() string { func (*ExecSandboxRequest) ProtoMessage() {} func (x *ExecSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[65] + mi := &file_openshell_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4566,7 +4708,7 @@ func (x *ExecSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxRequest.ProtoReflect.Descriptor instead. func (*ExecSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{65} + return file_openshell_proto_rawDescGZIP(), []int{67} } func (x *ExecSandboxRequest) GetSandboxId() string { @@ -4649,7 +4791,7 @@ type ExecSandboxStdout struct { func (x *ExecSandboxStdout) Reset() { *x = ExecSandboxStdout{} - mi := &file_openshell_proto_msgTypes[66] + mi := &file_openshell_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4661,7 +4803,7 @@ func (x *ExecSandboxStdout) String() string { func (*ExecSandboxStdout) ProtoMessage() {} func (x *ExecSandboxStdout) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[66] + mi := &file_openshell_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4674,7 +4816,7 @@ func (x *ExecSandboxStdout) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxStdout.ProtoReflect.Descriptor instead. func (*ExecSandboxStdout) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{66} + return file_openshell_proto_rawDescGZIP(), []int{68} } func (x *ExecSandboxStdout) GetData() []byte { @@ -4694,7 +4836,7 @@ type ExecSandboxStderr struct { func (x *ExecSandboxStderr) Reset() { *x = ExecSandboxStderr{} - mi := &file_openshell_proto_msgTypes[67] + mi := &file_openshell_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4706,7 +4848,7 @@ func (x *ExecSandboxStderr) String() string { func (*ExecSandboxStderr) ProtoMessage() {} func (x *ExecSandboxStderr) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[67] + mi := &file_openshell_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4719,7 +4861,7 @@ func (x *ExecSandboxStderr) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxStderr.ProtoReflect.Descriptor instead. func (*ExecSandboxStderr) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{67} + return file_openshell_proto_rawDescGZIP(), []int{69} } func (x *ExecSandboxStderr) GetData() []byte { @@ -4739,7 +4881,7 @@ type ExecSandboxExit struct { func (x *ExecSandboxExit) Reset() { *x = ExecSandboxExit{} - mi := &file_openshell_proto_msgTypes[68] + mi := &file_openshell_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4751,7 +4893,7 @@ func (x *ExecSandboxExit) String() string { func (*ExecSandboxExit) ProtoMessage() {} func (x *ExecSandboxExit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[68] + mi := &file_openshell_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4764,7 +4906,7 @@ func (x *ExecSandboxExit) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxExit.ProtoReflect.Descriptor instead. func (*ExecSandboxExit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{68} + return file_openshell_proto_rawDescGZIP(), []int{70} } func (x *ExecSandboxExit) GetExitCode() int32 { @@ -4789,7 +4931,7 @@ type ExecSandboxEvent struct { func (x *ExecSandboxEvent) Reset() { *x = ExecSandboxEvent{} - mi := &file_openshell_proto_msgTypes[69] + mi := &file_openshell_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4801,7 +4943,7 @@ func (x *ExecSandboxEvent) String() string { func (*ExecSandboxEvent) ProtoMessage() {} func (x *ExecSandboxEvent) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[69] + mi := &file_openshell_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4814,7 +4956,7 @@ func (x *ExecSandboxEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxEvent.ProtoReflect.Descriptor instead. func (*ExecSandboxEvent) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{69} + return file_openshell_proto_rawDescGZIP(), []int{71} } func (x *ExecSandboxEvent) GetPayload() isExecSandboxEvent_Payload { @@ -4896,7 +5038,7 @@ type TcpForwardInit struct { func (x *TcpForwardInit) Reset() { *x = TcpForwardInit{} - mi := &file_openshell_proto_msgTypes[70] + mi := &file_openshell_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4908,7 +5050,7 @@ func (x *TcpForwardInit) String() string { func (*TcpForwardInit) ProtoMessage() {} func (x *TcpForwardInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[70] + mi := &file_openshell_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4921,7 +5063,7 @@ func (x *TcpForwardInit) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpForwardInit.ProtoReflect.Descriptor instead. func (*TcpForwardInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{70} + return file_openshell_proto_rawDescGZIP(), []int{72} } func (x *TcpForwardInit) GetSandboxId() string { @@ -5000,7 +5142,7 @@ type TcpForwardFrame struct { func (x *TcpForwardFrame) Reset() { *x = TcpForwardFrame{} - mi := &file_openshell_proto_msgTypes[71] + mi := &file_openshell_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5012,7 +5154,7 @@ func (x *TcpForwardFrame) String() string { func (*TcpForwardFrame) ProtoMessage() {} func (x *TcpForwardFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[71] + mi := &file_openshell_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5025,7 +5167,7 @@ func (x *TcpForwardFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpForwardFrame.ProtoReflect.Descriptor instead. func (*TcpForwardFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{71} + return file_openshell_proto_rawDescGZIP(), []int{73} } func (x *TcpForwardFrame) GetPayload() isTcpForwardFrame_Payload { @@ -5084,7 +5226,7 @@ type ExecSandboxInput struct { func (x *ExecSandboxInput) Reset() { *x = ExecSandboxInput{} - mi := &file_openshell_proto_msgTypes[72] + mi := &file_openshell_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5096,7 +5238,7 @@ func (x *ExecSandboxInput) String() string { func (*ExecSandboxInput) ProtoMessage() {} func (x *ExecSandboxInput) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[72] + mi := &file_openshell_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5109,7 +5251,7 @@ func (x *ExecSandboxInput) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxInput.ProtoReflect.Descriptor instead. func (*ExecSandboxInput) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{72} + return file_openshell_proto_rawDescGZIP(), []int{74} } func (x *ExecSandboxInput) GetPayload() isExecSandboxInput_Payload { @@ -5182,7 +5324,7 @@ type ExecSandboxWindowResize struct { func (x *ExecSandboxWindowResize) Reset() { *x = ExecSandboxWindowResize{} - mi := &file_openshell_proto_msgTypes[73] + mi := &file_openshell_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5194,7 +5336,7 @@ func (x *ExecSandboxWindowResize) String() string { func (*ExecSandboxWindowResize) ProtoMessage() {} func (x *ExecSandboxWindowResize) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[73] + mi := &file_openshell_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5207,7 +5349,7 @@ func (x *ExecSandboxWindowResize) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxWindowResize.ProtoReflect.Descriptor instead. func (*ExecSandboxWindowResize) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{73} + return file_openshell_proto_rawDescGZIP(), []int{75} } func (x *ExecSandboxWindowResize) GetCols() uint32 { @@ -5244,7 +5386,7 @@ type SshSession struct { func (x *SshSession) Reset() { *x = SshSession{} - mi := &file_openshell_proto_msgTypes[74] + mi := &file_openshell_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5256,7 +5398,7 @@ func (x *SshSession) String() string { func (*SshSession) ProtoMessage() {} func (x *SshSession) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[74] + mi := &file_openshell_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5269,7 +5411,7 @@ func (x *SshSession) ProtoReflect() protoreflect.Message { // Deprecated: Use SshSession.ProtoReflect.Descriptor instead. func (*SshSession) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{74} + return file_openshell_proto_rawDescGZIP(), []int{76} } func (x *SshSession) GetMetadata() *datamodelv1.ObjectMeta { @@ -5338,7 +5480,7 @@ type WatchSandboxRequest struct { func (x *WatchSandboxRequest) Reset() { *x = WatchSandboxRequest{} - mi := &file_openshell_proto_msgTypes[75] + mi := &file_openshell_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5350,7 +5492,7 @@ func (x *WatchSandboxRequest) String() string { func (*WatchSandboxRequest) ProtoMessage() {} func (x *WatchSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[75] + mi := &file_openshell_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5363,7 +5505,7 @@ func (x *WatchSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSandboxRequest.ProtoReflect.Descriptor instead. func (*WatchSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{75} + return file_openshell_proto_rawDescGZIP(), []int{77} } func (x *WatchSandboxRequest) GetId() string { @@ -5453,7 +5595,7 @@ type SandboxStreamEvent struct { func (x *SandboxStreamEvent) Reset() { *x = SandboxStreamEvent{} - mi := &file_openshell_proto_msgTypes[76] + mi := &file_openshell_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5465,7 +5607,7 @@ func (x *SandboxStreamEvent) String() string { func (*SandboxStreamEvent) ProtoMessage() {} func (x *SandboxStreamEvent) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[76] + mi := &file_openshell_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5478,7 +5620,7 @@ func (x *SandboxStreamEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxStreamEvent.ProtoReflect.Descriptor instead. func (*SandboxStreamEvent) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{76} + return file_openshell_proto_rawDescGZIP(), []int{78} } func (x *SandboxStreamEvent) GetPayload() isSandboxStreamEvent_Payload { @@ -5591,7 +5733,7 @@ type SandboxLogLine struct { func (x *SandboxLogLine) Reset() { *x = SandboxLogLine{} - mi := &file_openshell_proto_msgTypes[77] + mi := &file_openshell_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5603,7 +5745,7 @@ func (x *SandboxLogLine) String() string { func (*SandboxLogLine) ProtoMessage() {} func (x *SandboxLogLine) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[77] + mi := &file_openshell_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5616,7 +5758,7 @@ func (x *SandboxLogLine) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxLogLine.ProtoReflect.Descriptor instead. func (*SandboxLogLine) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{77} + return file_openshell_proto_rawDescGZIP(), []int{79} } func (x *SandboxLogLine) GetSandboxId() string { @@ -5677,7 +5819,7 @@ type SandboxStreamWarning struct { func (x *SandboxStreamWarning) Reset() { *x = SandboxStreamWarning{} - mi := &file_openshell_proto_msgTypes[78] + mi := &file_openshell_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5689,7 +5831,7 @@ func (x *SandboxStreamWarning) String() string { func (*SandboxStreamWarning) ProtoMessage() {} func (x *SandboxStreamWarning) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[78] + mi := &file_openshell_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5702,7 +5844,7 @@ func (x *SandboxStreamWarning) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxStreamWarning.ProtoReflect.Descriptor instead. func (*SandboxStreamWarning) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{78} + return file_openshell_proto_rawDescGZIP(), []int{80} } func (x *SandboxStreamWarning) GetMessage() string { @@ -5724,7 +5866,7 @@ type CreateProviderRequest struct { func (x *CreateProviderRequest) Reset() { *x = CreateProviderRequest{} - mi := &file_openshell_proto_msgTypes[79] + mi := &file_openshell_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5736,7 +5878,7 @@ func (x *CreateProviderRequest) String() string { func (*CreateProviderRequest) ProtoMessage() {} func (x *CreateProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[79] + mi := &file_openshell_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5749,7 +5891,7 @@ func (x *CreateProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateProviderRequest.ProtoReflect.Descriptor instead. func (*CreateProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{79} + return file_openshell_proto_rawDescGZIP(), []int{81} } func (x *CreateProviderRequest) GetProvider() *datamodelv1.Provider { @@ -5778,7 +5920,7 @@ type GetProviderRequest struct { func (x *GetProviderRequest) Reset() { *x = GetProviderRequest{} - mi := &file_openshell_proto_msgTypes[80] + mi := &file_openshell_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5790,7 +5932,7 @@ func (x *GetProviderRequest) String() string { func (*GetProviderRequest) ProtoMessage() {} func (x *GetProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[80] + mi := &file_openshell_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5803,7 +5945,7 @@ func (x *GetProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRequest.ProtoReflect.Descriptor instead. func (*GetProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{80} + return file_openshell_proto_rawDescGZIP(), []int{82} } func (x *GetProviderRequest) GetName() string { @@ -5835,7 +5977,7 @@ type ListProvidersRequest struct { func (x *ListProvidersRequest) Reset() { *x = ListProvidersRequest{} - mi := &file_openshell_proto_msgTypes[81] + mi := &file_openshell_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5847,7 +5989,7 @@ func (x *ListProvidersRequest) String() string { func (*ListProvidersRequest) ProtoMessage() {} func (x *ListProvidersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[81] + mi := &file_openshell_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5860,7 +6002,7 @@ func (x *ListProvidersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProvidersRequest.ProtoReflect.Descriptor instead. func (*ListProvidersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{81} + return file_openshell_proto_rawDescGZIP(), []int{83} } func (x *ListProvidersRequest) GetLimit() uint32 { @@ -5906,7 +6048,7 @@ type UpdateProviderRequest struct { func (x *UpdateProviderRequest) Reset() { *x = UpdateProviderRequest{} - mi := &file_openshell_proto_msgTypes[82] + mi := &file_openshell_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5918,7 +6060,7 @@ func (x *UpdateProviderRequest) String() string { func (*UpdateProviderRequest) ProtoMessage() {} func (x *UpdateProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[82] + mi := &file_openshell_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5931,7 +6073,7 @@ func (x *UpdateProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderRequest.ProtoReflect.Descriptor instead. func (*UpdateProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{82} + return file_openshell_proto_rawDescGZIP(), []int{84} } func (x *UpdateProviderRequest) GetProvider() *datamodelv1.Provider { @@ -5967,7 +6109,7 @@ type DeleteProviderRequest struct { func (x *DeleteProviderRequest) Reset() { *x = DeleteProviderRequest{} - mi := &file_openshell_proto_msgTypes[83] + mi := &file_openshell_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5979,7 +6121,7 @@ func (x *DeleteProviderRequest) String() string { func (*DeleteProviderRequest) ProtoMessage() {} func (x *DeleteProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[83] + mi := &file_openshell_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5992,7 +6134,7 @@ func (x *DeleteProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{83} + return file_openshell_proto_rawDescGZIP(), []int{85} } func (x *DeleteProviderRequest) GetName() string { @@ -6019,7 +6161,7 @@ type ProviderResponse struct { func (x *ProviderResponse) Reset() { *x = ProviderResponse{} - mi := &file_openshell_proto_msgTypes[84] + mi := &file_openshell_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6031,7 +6173,7 @@ func (x *ProviderResponse) String() string { func (*ProviderResponse) ProtoMessage() {} func (x *ProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[84] + mi := &file_openshell_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6044,7 +6186,7 @@ func (x *ProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderResponse.ProtoReflect.Descriptor instead. func (*ProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{84} + return file_openshell_proto_rawDescGZIP(), []int{86} } func (x *ProviderResponse) GetProvider() *datamodelv1.Provider { @@ -6064,7 +6206,7 @@ type ListProvidersResponse struct { func (x *ListProvidersResponse) Reset() { *x = ListProvidersResponse{} - mi := &file_openshell_proto_msgTypes[85] + mi := &file_openshell_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6076,7 +6218,7 @@ func (x *ListProvidersResponse) String() string { func (*ListProvidersResponse) ProtoMessage() {} func (x *ListProvidersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[85] + mi := &file_openshell_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6089,7 +6231,7 @@ func (x *ListProvidersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProvidersResponse.ProtoReflect.Descriptor instead. func (*ListProvidersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{85} + return file_openshell_proto_rawDescGZIP(), []int{87} } func (x *ListProvidersResponse) GetProviders() []*datamodelv1.Provider { @@ -6113,7 +6255,7 @@ type ListProviderProfilesRequest struct { func (x *ListProviderProfilesRequest) Reset() { *x = ListProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[86] + mi := &file_openshell_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6125,7 +6267,7 @@ func (x *ListProviderProfilesRequest) String() string { func (*ListProviderProfilesRequest) ProtoMessage() {} func (x *ListProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[86] + mi := &file_openshell_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6138,7 +6280,7 @@ func (x *ListProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*ListProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{86} + return file_openshell_proto_rawDescGZIP(), []int{88} } func (x *ListProviderProfilesRequest) GetLimit() uint32 { @@ -6176,7 +6318,7 @@ type GetProviderProfileRequest struct { func (x *GetProviderProfileRequest) Reset() { *x = GetProviderProfileRequest{} - mi := &file_openshell_proto_msgTypes[87] + mi := &file_openshell_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6188,7 +6330,7 @@ func (x *GetProviderProfileRequest) String() string { func (*GetProviderProfileRequest) ProtoMessage() {} func (x *GetProviderProfileRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[87] + mi := &file_openshell_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6201,7 +6343,7 @@ func (x *GetProviderProfileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderProfileRequest.ProtoReflect.Descriptor instead. func (*GetProviderProfileRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{87} + return file_openshell_proto_rawDescGZIP(), []int{89} } func (x *GetProviderProfileRequest) GetId() string { @@ -6229,7 +6371,7 @@ type ProviderProfileImportItem struct { func (x *ProviderProfileImportItem) Reset() { *x = ProviderProfileImportItem{} - mi := &file_openshell_proto_msgTypes[88] + mi := &file_openshell_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6241,7 +6383,7 @@ func (x *ProviderProfileImportItem) String() string { func (*ProviderProfileImportItem) ProtoMessage() {} func (x *ProviderProfileImportItem) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[88] + mi := &file_openshell_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6254,7 +6396,7 @@ func (x *ProviderProfileImportItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileImportItem.ProtoReflect.Descriptor instead. func (*ProviderProfileImportItem) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{88} + return file_openshell_proto_rawDescGZIP(), []int{90} } func (x *ProviderProfileImportItem) GetProfile() *ProviderProfile { @@ -6285,7 +6427,7 @@ type ProviderProfileDiagnostic struct { func (x *ProviderProfileDiagnostic) Reset() { *x = ProviderProfileDiagnostic{} - mi := &file_openshell_proto_msgTypes[89] + mi := &file_openshell_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6297,7 +6439,7 @@ func (x *ProviderProfileDiagnostic) String() string { func (*ProviderProfileDiagnostic) ProtoMessage() {} func (x *ProviderProfileDiagnostic) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[89] + mi := &file_openshell_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6310,7 +6452,7 @@ func (x *ProviderProfileDiagnostic) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileDiagnostic.ProtoReflect.Descriptor instead. func (*ProviderProfileDiagnostic) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{89} + return file_openshell_proto_rawDescGZIP(), []int{91} } func (x *ProviderProfileDiagnostic) GetSource() string { @@ -6367,7 +6509,7 @@ type ProviderCredentialTokenGrantAudienceOverride struct { func (x *ProviderCredentialTokenGrantAudienceOverride) Reset() { *x = ProviderCredentialTokenGrantAudienceOverride{} - mi := &file_openshell_proto_msgTypes[90] + mi := &file_openshell_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6379,7 +6521,7 @@ func (x *ProviderCredentialTokenGrantAudienceOverride) String() string { func (*ProviderCredentialTokenGrantAudienceOverride) ProtoMessage() {} func (x *ProviderCredentialTokenGrantAudienceOverride) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[90] + mi := &file_openshell_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6392,7 +6534,7 @@ func (x *ProviderCredentialTokenGrantAudienceOverride) ProtoReflect() protorefle // Deprecated: Use ProviderCredentialTokenGrantAudienceOverride.ProtoReflect.Descriptor instead. func (*ProviderCredentialTokenGrantAudienceOverride) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{90} + return file_openshell_proto_rawDescGZIP(), []int{92} } func (x *ProviderCredentialTokenGrantAudienceOverride) GetHost() string { @@ -6446,7 +6588,7 @@ type ProviderCredentialTokenGrantSubjectToken struct { func (x *ProviderCredentialTokenGrantSubjectToken) Reset() { *x = ProviderCredentialTokenGrantSubjectToken{} - mi := &file_openshell_proto_msgTypes[91] + mi := &file_openshell_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6458,7 +6600,7 @@ func (x *ProviderCredentialTokenGrantSubjectToken) String() string { func (*ProviderCredentialTokenGrantSubjectToken) ProtoMessage() {} func (x *ProviderCredentialTokenGrantSubjectToken) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[91] + mi := &file_openshell_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6471,7 +6613,7 @@ func (x *ProviderCredentialTokenGrantSubjectToken) ProtoReflect() protoreflect.M // Deprecated: Use ProviderCredentialTokenGrantSubjectToken.ProtoReflect.Descriptor instead. func (*ProviderCredentialTokenGrantSubjectToken) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{91} + return file_openshell_proto_rawDescGZIP(), []int{93} } func (x *ProviderCredentialTokenGrantSubjectToken) GetSource() string { @@ -6528,7 +6670,7 @@ type ProviderCredentialTokenGrant struct { func (x *ProviderCredentialTokenGrant) Reset() { *x = ProviderCredentialTokenGrant{} - mi := &file_openshell_proto_msgTypes[92] + mi := &file_openshell_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6540,7 +6682,7 @@ func (x *ProviderCredentialTokenGrant) String() string { func (*ProviderCredentialTokenGrant) ProtoMessage() {} func (x *ProviderCredentialTokenGrant) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[92] + mi := &file_openshell_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6553,7 +6695,7 @@ func (x *ProviderCredentialTokenGrant) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialTokenGrant.ProtoReflect.Descriptor instead. func (*ProviderCredentialTokenGrant) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{92} + return file_openshell_proto_rawDescGZIP(), []int{94} } func (x *ProviderCredentialTokenGrant) GetTokenEndpoint() string { @@ -6645,7 +6787,7 @@ type ProviderProfileCredential struct { func (x *ProviderProfileCredential) Reset() { *x = ProviderProfileCredential{} - mi := &file_openshell_proto_msgTypes[93] + mi := &file_openshell_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6657,7 +6799,7 @@ func (x *ProviderProfileCredential) String() string { func (*ProviderProfileCredential) ProtoMessage() {} func (x *ProviderProfileCredential) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[93] + mi := &file_openshell_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6670,7 +6812,7 @@ func (x *ProviderProfileCredential) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileCredential.ProtoReflect.Descriptor instead. func (*ProviderProfileCredential) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{93} + return file_openshell_proto_rawDescGZIP(), []int{95} } func (x *ProviderProfileCredential) GetName() string { @@ -6755,7 +6897,7 @@ type ProviderCredentialRefreshMaterial struct { func (x *ProviderCredentialRefreshMaterial) Reset() { *x = ProviderCredentialRefreshMaterial{} - mi := &file_openshell_proto_msgTypes[94] + mi := &file_openshell_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6767,7 +6909,7 @@ func (x *ProviderCredentialRefreshMaterial) String() string { func (*ProviderCredentialRefreshMaterial) ProtoMessage() {} func (x *ProviderCredentialRefreshMaterial) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[94] + mi := &file_openshell_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6780,7 +6922,7 @@ func (x *ProviderCredentialRefreshMaterial) ProtoReflect() protoreflect.Message // Deprecated: Use ProviderCredentialRefreshMaterial.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefreshMaterial) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{94} + return file_openshell_proto_rawDescGZIP(), []int{96} } func (x *ProviderCredentialRefreshMaterial) GetName() string { @@ -6825,7 +6967,7 @@ type ProviderCredentialRefreshOutput struct { func (x *ProviderCredentialRefreshOutput) Reset() { *x = ProviderCredentialRefreshOutput{} - mi := &file_openshell_proto_msgTypes[95] + mi := &file_openshell_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6837,7 +6979,7 @@ func (x *ProviderCredentialRefreshOutput) String() string { func (*ProviderCredentialRefreshOutput) ProtoMessage() {} func (x *ProviderCredentialRefreshOutput) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[95] + mi := &file_openshell_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6850,7 +6992,7 @@ func (x *ProviderCredentialRefreshOutput) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialRefreshOutput.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefreshOutput) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{95} + return file_openshell_proto_rawDescGZIP(), []int{97} } func (x *ProviderCredentialRefreshOutput) GetOutput() string { @@ -6882,7 +7024,7 @@ type ProviderCredentialRefresh struct { func (x *ProviderCredentialRefresh) Reset() { *x = ProviderCredentialRefresh{} - mi := &file_openshell_proto_msgTypes[96] + mi := &file_openshell_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6894,7 +7036,7 @@ func (x *ProviderCredentialRefresh) String() string { func (*ProviderCredentialRefresh) ProtoMessage() {} func (x *ProviderCredentialRefresh) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[96] + mi := &file_openshell_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6907,7 +7049,7 @@ func (x *ProviderCredentialRefresh) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialRefresh.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefresh) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{96} + return file_openshell_proto_rawDescGZIP(), []int{98} } func (x *ProviderCredentialRefresh) GetStrategy() ProviderCredentialRefreshStrategy { @@ -6990,7 +7132,7 @@ type ProviderCredentialRefreshStatus struct { func (x *ProviderCredentialRefreshStatus) Reset() { *x = ProviderCredentialRefreshStatus{} - mi := &file_openshell_proto_msgTypes[97] + mi := &file_openshell_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7002,7 +7144,7 @@ func (x *ProviderCredentialRefreshStatus) String() string { func (*ProviderCredentialRefreshStatus) ProtoMessage() {} func (x *ProviderCredentialRefreshStatus) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[97] + mi := &file_openshell_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7015,7 +7157,7 @@ func (x *ProviderCredentialRefreshStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialRefreshStatus.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefreshStatus) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{97} + return file_openshell_proto_rawDescGZIP(), []int{99} } func (x *ProviderCredentialRefreshStatus) GetProviderName() string { @@ -7120,7 +7262,7 @@ type ProviderProfileDiscovery struct { func (x *ProviderProfileDiscovery) Reset() { *x = ProviderProfileDiscovery{} - mi := &file_openshell_proto_msgTypes[98] + mi := &file_openshell_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7132,7 +7274,7 @@ func (x *ProviderProfileDiscovery) String() string { func (*ProviderProfileDiscovery) ProtoMessage() {} func (x *ProviderProfileDiscovery) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[98] + mi := &file_openshell_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7145,7 +7287,7 @@ func (x *ProviderProfileDiscovery) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileDiscovery.ProtoReflect.Descriptor instead. func (*ProviderProfileDiscovery) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{98} + return file_openshell_proto_rawDescGZIP(), []int{100} } func (x *ProviderProfileDiscovery) GetCredentials() []string { @@ -7209,7 +7351,7 @@ type StoredProviderCredentialRefreshState struct { func (x *StoredProviderCredentialRefreshState) Reset() { *x = StoredProviderCredentialRefreshState{} - mi := &file_openshell_proto_msgTypes[99] + mi := &file_openshell_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7221,7 +7363,7 @@ func (x *StoredProviderCredentialRefreshState) String() string { func (*StoredProviderCredentialRefreshState) ProtoMessage() {} func (x *StoredProviderCredentialRefreshState) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[99] + mi := &file_openshell_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7234,7 +7376,7 @@ func (x *StoredProviderCredentialRefreshState) ProtoReflect() protoreflect.Messa // Deprecated: Use StoredProviderCredentialRefreshState.ProtoReflect.Descriptor instead. func (*StoredProviderCredentialRefreshState) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{99} + return file_openshell_proto_rawDescGZIP(), []int{101} } func (x *StoredProviderCredentialRefreshState) GetMetadata() *datamodelv1.ObjectMeta { @@ -7417,7 +7559,7 @@ type StoredRefreshMaterialDeletion struct { func (x *StoredRefreshMaterialDeletion) Reset() { *x = StoredRefreshMaterialDeletion{} - mi := &file_openshell_proto_msgTypes[100] + mi := &file_openshell_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7429,7 +7571,7 @@ func (x *StoredRefreshMaterialDeletion) String() string { func (*StoredRefreshMaterialDeletion) ProtoMessage() {} func (x *StoredRefreshMaterialDeletion) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[100] + mi := &file_openshell_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7442,7 +7584,7 @@ func (x *StoredRefreshMaterialDeletion) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredRefreshMaterialDeletion.ProtoReflect.Descriptor instead. func (*StoredRefreshMaterialDeletion) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{100} + return file_openshell_proto_rawDescGZIP(), []int{102} } func (x *StoredRefreshMaterialDeletion) GetMaterialKey() string { @@ -7471,7 +7613,7 @@ type GetProviderRefreshStatusRequest struct { func (x *GetProviderRefreshStatusRequest) Reset() { *x = GetProviderRefreshStatusRequest{} - mi := &file_openshell_proto_msgTypes[101] + mi := &file_openshell_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7483,7 +7625,7 @@ func (x *GetProviderRefreshStatusRequest) String() string { func (*GetProviderRefreshStatusRequest) ProtoMessage() {} func (x *GetProviderRefreshStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[101] + mi := &file_openshell_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7496,7 +7638,7 @@ func (x *GetProviderRefreshStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRefreshStatusRequest.ProtoReflect.Descriptor instead. func (*GetProviderRefreshStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{101} + return file_openshell_proto_rawDescGZIP(), []int{103} } func (x *GetProviderRefreshStatusRequest) GetProvider() string { @@ -7529,7 +7671,7 @@ type GetProviderRefreshStatusResponse struct { func (x *GetProviderRefreshStatusResponse) Reset() { *x = GetProviderRefreshStatusResponse{} - mi := &file_openshell_proto_msgTypes[102] + mi := &file_openshell_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7541,7 +7683,7 @@ func (x *GetProviderRefreshStatusResponse) String() string { func (*GetProviderRefreshStatusResponse) ProtoMessage() {} func (x *GetProviderRefreshStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[102] + mi := &file_openshell_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7554,7 +7696,7 @@ func (x *GetProviderRefreshStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRefreshStatusResponse.ProtoReflect.Descriptor instead. func (*GetProviderRefreshStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{102} + return file_openshell_proto_rawDescGZIP(), []int{104} } func (x *GetProviderRefreshStatusResponse) GetCredentials() []*ProviderCredentialRefreshStatus { @@ -7583,7 +7725,7 @@ type ConfigureProviderRefreshRequest struct { func (x *ConfigureProviderRefreshRequest) Reset() { *x = ConfigureProviderRefreshRequest{} - mi := &file_openshell_proto_msgTypes[103] + mi := &file_openshell_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7595,7 +7737,7 @@ func (x *ConfigureProviderRefreshRequest) String() string { func (*ConfigureProviderRefreshRequest) ProtoMessage() {} func (x *ConfigureProviderRefreshRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[103] + mi := &file_openshell_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7608,7 +7750,7 @@ func (x *ConfigureProviderRefreshRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureProviderRefreshRequest.ProtoReflect.Descriptor instead. func (*ConfigureProviderRefreshRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{103} + return file_openshell_proto_rawDescGZIP(), []int{105} } func (x *ConfigureProviderRefreshRequest) GetProvider() string { @@ -7669,7 +7811,7 @@ type ConfigureProviderRefreshResponse struct { func (x *ConfigureProviderRefreshResponse) Reset() { *x = ConfigureProviderRefreshResponse{} - mi := &file_openshell_proto_msgTypes[104] + mi := &file_openshell_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7681,7 +7823,7 @@ func (x *ConfigureProviderRefreshResponse) String() string { func (*ConfigureProviderRefreshResponse) ProtoMessage() {} func (x *ConfigureProviderRefreshResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[104] + mi := &file_openshell_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7694,7 +7836,7 @@ func (x *ConfigureProviderRefreshResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureProviderRefreshResponse.ProtoReflect.Descriptor instead. func (*ConfigureProviderRefreshResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{104} + return file_openshell_proto_rawDescGZIP(), []int{106} } func (x *ConfigureProviderRefreshResponse) GetStatus() *ProviderCredentialRefreshStatus { @@ -7716,7 +7858,7 @@ type RotateProviderCredentialRequest struct { func (x *RotateProviderCredentialRequest) Reset() { *x = RotateProviderCredentialRequest{} - mi := &file_openshell_proto_msgTypes[105] + mi := &file_openshell_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7728,7 +7870,7 @@ func (x *RotateProviderCredentialRequest) String() string { func (*RotateProviderCredentialRequest) ProtoMessage() {} func (x *RotateProviderCredentialRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[105] + mi := &file_openshell_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7741,7 +7883,7 @@ func (x *RotateProviderCredentialRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RotateProviderCredentialRequest.ProtoReflect.Descriptor instead. func (*RotateProviderCredentialRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{105} + return file_openshell_proto_rawDescGZIP(), []int{107} } func (x *RotateProviderCredentialRequest) GetProvider() string { @@ -7774,7 +7916,7 @@ type RotateProviderCredentialResponse struct { func (x *RotateProviderCredentialResponse) Reset() { *x = RotateProviderCredentialResponse{} - mi := &file_openshell_proto_msgTypes[106] + mi := &file_openshell_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7786,7 +7928,7 @@ func (x *RotateProviderCredentialResponse) String() string { func (*RotateProviderCredentialResponse) ProtoMessage() {} func (x *RotateProviderCredentialResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[106] + mi := &file_openshell_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7799,7 +7941,7 @@ func (x *RotateProviderCredentialResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RotateProviderCredentialResponse.ProtoReflect.Descriptor instead. func (*RotateProviderCredentialResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{106} + return file_openshell_proto_rawDescGZIP(), []int{108} } func (x *RotateProviderCredentialResponse) GetStatus() *ProviderCredentialRefreshStatus { @@ -7821,7 +7963,7 @@ type DeleteProviderRefreshRequest struct { func (x *DeleteProviderRefreshRequest) Reset() { *x = DeleteProviderRefreshRequest{} - mi := &file_openshell_proto_msgTypes[107] + mi := &file_openshell_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7833,7 +7975,7 @@ func (x *DeleteProviderRefreshRequest) String() string { func (*DeleteProviderRefreshRequest) ProtoMessage() {} func (x *DeleteProviderRefreshRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[107] + mi := &file_openshell_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7846,7 +7988,7 @@ func (x *DeleteProviderRefreshRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRefreshRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderRefreshRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{107} + return file_openshell_proto_rawDescGZIP(), []int{109} } func (x *DeleteProviderRefreshRequest) GetProvider() string { @@ -7879,7 +8021,7 @@ type DeleteProviderRefreshResponse struct { func (x *DeleteProviderRefreshResponse) Reset() { *x = DeleteProviderRefreshResponse{} - mi := &file_openshell_proto_msgTypes[108] + mi := &file_openshell_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7891,7 +8033,7 @@ func (x *DeleteProviderRefreshResponse) String() string { func (*DeleteProviderRefreshResponse) ProtoMessage() {} func (x *DeleteProviderRefreshResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[108] + mi := &file_openshell_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7904,7 +8046,7 @@ func (x *DeleteProviderRefreshResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRefreshResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderRefreshResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{108} + return file_openshell_proto_rawDescGZIP(), []int{110} } func (x *DeleteProviderRefreshResponse) GetDeleted() bool { @@ -7944,7 +8086,7 @@ type ProviderProfile struct { func (x *ProviderProfile) Reset() { *x = ProviderProfile{} - mi := &file_openshell_proto_msgTypes[109] + mi := &file_openshell_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7956,7 +8098,7 @@ func (x *ProviderProfile) String() string { func (*ProviderProfile) ProtoMessage() {} func (x *ProviderProfile) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[109] + mi := &file_openshell_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7969,7 +8111,7 @@ func (x *ProviderProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfile.ProtoReflect.Descriptor instead. func (*ProviderProfile) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{109} + return file_openshell_proto_rawDescGZIP(), []int{111} } func (x *ProviderProfile) GetId() string { @@ -8074,7 +8216,7 @@ type StoredProviderProfile struct { func (x *StoredProviderProfile) Reset() { *x = StoredProviderProfile{} - mi := &file_openshell_proto_msgTypes[110] + mi := &file_openshell_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8086,7 +8228,7 @@ func (x *StoredProviderProfile) String() string { func (*StoredProviderProfile) ProtoMessage() {} func (x *StoredProviderProfile) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[110] + mi := &file_openshell_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8099,7 +8241,7 @@ func (x *StoredProviderProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredProviderProfile.ProtoReflect.Descriptor instead. func (*StoredProviderProfile) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{110} + return file_openshell_proto_rawDescGZIP(), []int{112} } func (x *StoredProviderProfile) GetMetadata() *datamodelv1.ObjectMeta { @@ -8126,7 +8268,7 @@ type ProviderProfileResponse struct { func (x *ProviderProfileResponse) Reset() { *x = ProviderProfileResponse{} - mi := &file_openshell_proto_msgTypes[111] + mi := &file_openshell_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8138,7 +8280,7 @@ func (x *ProviderProfileResponse) String() string { func (*ProviderProfileResponse) ProtoMessage() {} func (x *ProviderProfileResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[111] + mi := &file_openshell_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8151,7 +8293,7 @@ func (x *ProviderProfileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileResponse.ProtoReflect.Descriptor instead. func (*ProviderProfileResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{111} + return file_openshell_proto_rawDescGZIP(), []int{113} } func (x *ProviderProfileResponse) GetProfile() *ProviderProfile { @@ -8171,7 +8313,7 @@ type ListProviderProfilesResponse struct { func (x *ListProviderProfilesResponse) Reset() { *x = ListProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[112] + mi := &file_openshell_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8183,7 +8325,7 @@ func (x *ListProviderProfilesResponse) String() string { func (*ListProviderProfilesResponse) ProtoMessage() {} func (x *ListProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[112] + mi := &file_openshell_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8196,7 +8338,7 @@ func (x *ListProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*ListProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{112} + return file_openshell_proto_rawDescGZIP(), []int{114} } func (x *ListProviderProfilesResponse) GetProfiles() []*ProviderProfile { @@ -8219,7 +8361,7 @@ type ImportProviderProfilesRequest struct { func (x *ImportProviderProfilesRequest) Reset() { *x = ImportProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[113] + mi := &file_openshell_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8231,7 +8373,7 @@ func (x *ImportProviderProfilesRequest) String() string { func (*ImportProviderProfilesRequest) ProtoMessage() {} func (x *ImportProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[113] + mi := &file_openshell_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8244,7 +8386,7 @@ func (x *ImportProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*ImportProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{113} + return file_openshell_proto_rawDescGZIP(), []int{115} } func (x *ImportProviderProfilesRequest) GetProfiles() []*ProviderProfileImportItem { @@ -8273,7 +8415,7 @@ type ImportProviderProfilesResponse struct { func (x *ImportProviderProfilesResponse) Reset() { *x = ImportProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[114] + mi := &file_openshell_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8285,7 +8427,7 @@ func (x *ImportProviderProfilesResponse) String() string { func (*ImportProviderProfilesResponse) ProtoMessage() {} func (x *ImportProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[114] + mi := &file_openshell_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8298,7 +8440,7 @@ func (x *ImportProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*ImportProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{114} + return file_openshell_proto_rawDescGZIP(), []int{116} } func (x *ImportProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -8342,7 +8484,7 @@ type UpdateProviderProfilesRequest struct { func (x *UpdateProviderProfilesRequest) Reset() { *x = UpdateProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[115] + mi := &file_openshell_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8354,7 +8496,7 @@ func (x *UpdateProviderProfilesRequest) String() string { func (*UpdateProviderProfilesRequest) ProtoMessage() {} func (x *UpdateProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[115] + mi := &file_openshell_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8367,7 +8509,7 @@ func (x *UpdateProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*UpdateProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{115} + return file_openshell_proto_rawDescGZIP(), []int{117} } func (x *UpdateProviderProfilesRequest) GetProfile() *ProviderProfileImportItem { @@ -8410,7 +8552,7 @@ type UpdateProviderProfilesResponse struct { func (x *UpdateProviderProfilesResponse) Reset() { *x = UpdateProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[116] + mi := &file_openshell_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8422,7 +8564,7 @@ func (x *UpdateProviderProfilesResponse) String() string { func (*UpdateProviderProfilesResponse) ProtoMessage() {} func (x *UpdateProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[116] + mi := &file_openshell_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8435,7 +8577,7 @@ func (x *UpdateProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*UpdateProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{116} + return file_openshell_proto_rawDescGZIP(), []int{118} } func (x *UpdateProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -8472,7 +8614,7 @@ type LintProviderProfilesRequest struct { func (x *LintProviderProfilesRequest) Reset() { *x = LintProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[117] + mi := &file_openshell_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8484,7 +8626,7 @@ func (x *LintProviderProfilesRequest) String() string { func (*LintProviderProfilesRequest) ProtoMessage() {} func (x *LintProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[117] + mi := &file_openshell_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8497,7 +8639,7 @@ func (x *LintProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LintProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*LintProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{117} + return file_openshell_proto_rawDescGZIP(), []int{119} } func (x *LintProviderProfilesRequest) GetProfiles() []*ProviderProfileImportItem { @@ -8525,7 +8667,7 @@ type LintProviderProfilesResponse struct { func (x *LintProviderProfilesResponse) Reset() { *x = LintProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[118] + mi := &file_openshell_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8537,7 +8679,7 @@ func (x *LintProviderProfilesResponse) String() string { func (*LintProviderProfilesResponse) ProtoMessage() {} func (x *LintProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[118] + mi := &file_openshell_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8550,7 +8692,7 @@ func (x *LintProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LintProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*LintProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{118} + return file_openshell_proto_rawDescGZIP(), []int{120} } func (x *LintProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -8577,7 +8719,7 @@ type DeleteProviderResponse struct { func (x *DeleteProviderResponse) Reset() { *x = DeleteProviderResponse{} - mi := &file_openshell_proto_msgTypes[119] + mi := &file_openshell_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8589,7 +8731,7 @@ func (x *DeleteProviderResponse) String() string { func (*DeleteProviderResponse) ProtoMessage() {} func (x *DeleteProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[119] + mi := &file_openshell_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8602,7 +8744,7 @@ func (x *DeleteProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{119} + return file_openshell_proto_rawDescGZIP(), []int{121} } func (x *DeleteProviderResponse) GetDeleted() bool { @@ -8625,7 +8767,7 @@ type DeleteProviderProfileRequest struct { func (x *DeleteProviderProfileRequest) Reset() { *x = DeleteProviderProfileRequest{} - mi := &file_openshell_proto_msgTypes[120] + mi := &file_openshell_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8637,7 +8779,7 @@ func (x *DeleteProviderProfileRequest) String() string { func (*DeleteProviderProfileRequest) ProtoMessage() {} func (x *DeleteProviderProfileRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[120] + mi := &file_openshell_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8650,7 +8792,7 @@ func (x *DeleteProviderProfileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderProfileRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderProfileRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{120} + return file_openshell_proto_rawDescGZIP(), []int{122} } func (x *DeleteProviderProfileRequest) GetId() string { @@ -8677,7 +8819,7 @@ type DeleteProviderProfileResponse struct { func (x *DeleteProviderProfileResponse) Reset() { *x = DeleteProviderProfileResponse{} - mi := &file_openshell_proto_msgTypes[121] + mi := &file_openshell_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8689,7 +8831,7 @@ func (x *DeleteProviderProfileResponse) String() string { func (*DeleteProviderProfileResponse) ProtoMessage() {} func (x *DeleteProviderProfileResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[121] + mi := &file_openshell_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8702,7 +8844,7 @@ func (x *DeleteProviderProfileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderProfileResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderProfileResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{121} + return file_openshell_proto_rawDescGZIP(), []int{123} } func (x *DeleteProviderProfileResponse) GetDeleted() bool { @@ -8727,7 +8869,7 @@ type GetSandboxProviderEnvironmentRequest struct { func (x *GetSandboxProviderEnvironmentRequest) Reset() { *x = GetSandboxProviderEnvironmentRequest{} - mi := &file_openshell_proto_msgTypes[122] + mi := &file_openshell_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8739,7 +8881,7 @@ func (x *GetSandboxProviderEnvironmentRequest) String() string { func (*GetSandboxProviderEnvironmentRequest) ProtoMessage() {} func (x *GetSandboxProviderEnvironmentRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[122] + mi := &file_openshell_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8752,7 +8894,7 @@ func (x *GetSandboxProviderEnvironmentRequest) ProtoReflect() protoreflect.Messa // Deprecated: Use GetSandboxProviderEnvironmentRequest.ProtoReflect.Descriptor instead. func (*GetSandboxProviderEnvironmentRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{122} + return file_openshell_proto_rawDescGZIP(), []int{124} } func (x *GetSandboxProviderEnvironmentRequest) GetSandboxId() string { @@ -8781,7 +8923,7 @@ type StaticCredentialEndpointBinding struct { func (x *StaticCredentialEndpointBinding) Reset() { *x = StaticCredentialEndpointBinding{} - mi := &file_openshell_proto_msgTypes[123] + mi := &file_openshell_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8793,7 +8935,7 @@ func (x *StaticCredentialEndpointBinding) String() string { func (*StaticCredentialEndpointBinding) ProtoMessage() {} func (x *StaticCredentialEndpointBinding) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[123] + mi := &file_openshell_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8806,7 +8948,7 @@ func (x *StaticCredentialEndpointBinding) ProtoReflect() protoreflect.Message { // Deprecated: Use StaticCredentialEndpointBinding.ProtoReflect.Descriptor instead. func (*StaticCredentialEndpointBinding) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{123} + return file_openshell_proto_rawDescGZIP(), []int{125} } func (x *StaticCredentialEndpointBinding) GetHost() string { @@ -8850,7 +8992,7 @@ type StaticCredentialBinding struct { func (x *StaticCredentialBinding) Reset() { *x = StaticCredentialBinding{} - mi := &file_openshell_proto_msgTypes[124] + mi := &file_openshell_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8862,7 +9004,7 @@ func (x *StaticCredentialBinding) String() string { func (*StaticCredentialBinding) ProtoMessage() {} func (x *StaticCredentialBinding) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[124] + mi := &file_openshell_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8875,7 +9017,7 @@ func (x *StaticCredentialBinding) ProtoReflect() protoreflect.Message { // Deprecated: Use StaticCredentialBinding.ProtoReflect.Descriptor instead. func (*StaticCredentialBinding) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{124} + return file_openshell_proto_rawDescGZIP(), []int{126} } func (x *StaticCredentialBinding) GetEndpoints() []*StaticCredentialEndpointBinding { @@ -8926,7 +9068,7 @@ type GetSandboxProviderEnvironmentResponse struct { func (x *GetSandboxProviderEnvironmentResponse) Reset() { *x = GetSandboxProviderEnvironmentResponse{} - mi := &file_openshell_proto_msgTypes[125] + mi := &file_openshell_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8938,7 +9080,7 @@ func (x *GetSandboxProviderEnvironmentResponse) String() string { func (*GetSandboxProviderEnvironmentResponse) ProtoMessage() {} func (x *GetSandboxProviderEnvironmentResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[125] + mi := &file_openshell_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8951,7 +9093,7 @@ func (x *GetSandboxProviderEnvironmentResponse) ProtoReflect() protoreflect.Mess // Deprecated: Use GetSandboxProviderEnvironmentResponse.ProtoReflect.Descriptor instead. func (*GetSandboxProviderEnvironmentResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{125} + return file_openshell_proto_rawDescGZIP(), []int{127} } func (x *GetSandboxProviderEnvironmentResponse) GetEnvironment() map[string]string { @@ -9013,7 +9155,7 @@ type ExchangeProviderSubjectTokenRequest struct { func (x *ExchangeProviderSubjectTokenRequest) Reset() { *x = ExchangeProviderSubjectTokenRequest{} - mi := &file_openshell_proto_msgTypes[126] + mi := &file_openshell_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9025,7 +9167,7 @@ func (x *ExchangeProviderSubjectTokenRequest) String() string { func (*ExchangeProviderSubjectTokenRequest) ProtoMessage() {} func (x *ExchangeProviderSubjectTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[126] + mi := &file_openshell_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9038,7 +9180,7 @@ func (x *ExchangeProviderSubjectTokenRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use ExchangeProviderSubjectTokenRequest.ProtoReflect.Descriptor instead. func (*ExchangeProviderSubjectTokenRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{126} + return file_openshell_proto_rawDescGZIP(), []int{128} } func (x *ExchangeProviderSubjectTokenRequest) GetSandboxId() string { @@ -9080,7 +9222,7 @@ type ExchangeProviderSubjectTokenResponse struct { func (x *ExchangeProviderSubjectTokenResponse) Reset() { *x = ExchangeProviderSubjectTokenResponse{} - mi := &file_openshell_proto_msgTypes[127] + mi := &file_openshell_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9092,7 +9234,7 @@ func (x *ExchangeProviderSubjectTokenResponse) String() string { func (*ExchangeProviderSubjectTokenResponse) ProtoMessage() {} func (x *ExchangeProviderSubjectTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[127] + mi := &file_openshell_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9105,7 +9247,7 @@ func (x *ExchangeProviderSubjectTokenResponse) ProtoReflect() protoreflect.Messa // Deprecated: Use ExchangeProviderSubjectTokenResponse.ProtoReflect.Descriptor instead. func (*ExchangeProviderSubjectTokenResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{127} + return file_openshell_proto_rawDescGZIP(), []int{129} } func (x *ExchangeProviderSubjectTokenResponse) GetAccessToken() string { @@ -9176,7 +9318,7 @@ type UpdateConfigRequest struct { func (x *UpdateConfigRequest) Reset() { *x = UpdateConfigRequest{} - mi := &file_openshell_proto_msgTypes[128] + mi := &file_openshell_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9188,7 +9330,7 @@ func (x *UpdateConfigRequest) String() string { func (*UpdateConfigRequest) ProtoMessage() {} func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[128] + mi := &file_openshell_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9201,7 +9343,7 @@ func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateConfigRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{128} + return file_openshell_proto_rawDescGZIP(), []int{130} } func (x *UpdateConfigRequest) GetName() string { @@ -9291,7 +9433,7 @@ type PolicyMergeOperation struct { func (x *PolicyMergeOperation) Reset() { *x = PolicyMergeOperation{} - mi := &file_openshell_proto_msgTypes[129] + mi := &file_openshell_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9303,7 +9445,7 @@ func (x *PolicyMergeOperation) String() string { func (*PolicyMergeOperation) ProtoMessage() {} func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[129] + mi := &file_openshell_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9316,7 +9458,7 @@ func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyMergeOperation.ProtoReflect.Descriptor instead. func (*PolicyMergeOperation) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{129} + return file_openshell_proto_rawDescGZIP(), []int{131} } func (x *PolicyMergeOperation) GetOperation() isPolicyMergeOperation_Operation { @@ -9430,7 +9572,7 @@ type AddNetworkRule struct { func (x *AddNetworkRule) Reset() { *x = AddNetworkRule{} - mi := &file_openshell_proto_msgTypes[130] + mi := &file_openshell_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9442,7 +9584,7 @@ func (x *AddNetworkRule) String() string { func (*AddNetworkRule) ProtoMessage() {} func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[130] + mi := &file_openshell_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9455,7 +9597,7 @@ func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use AddNetworkRule.ProtoReflect.Descriptor instead. func (*AddNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{130} + return file_openshell_proto_rawDescGZIP(), []int{132} } func (x *AddNetworkRule) GetRuleName() string { @@ -9483,7 +9625,7 @@ type RemoveNetworkEndpoint struct { func (x *RemoveNetworkEndpoint) Reset() { *x = RemoveNetworkEndpoint{} - mi := &file_openshell_proto_msgTypes[131] + mi := &file_openshell_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9495,7 +9637,7 @@ func (x *RemoveNetworkEndpoint) String() string { func (*RemoveNetworkEndpoint) ProtoMessage() {} func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[131] + mi := &file_openshell_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9508,7 +9650,7 @@ func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkEndpoint.ProtoReflect.Descriptor instead. func (*RemoveNetworkEndpoint) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{131} + return file_openshell_proto_rawDescGZIP(), []int{133} } func (x *RemoveNetworkEndpoint) GetRuleName() string { @@ -9541,7 +9683,7 @@ type RemoveNetworkRule struct { func (x *RemoveNetworkRule) Reset() { *x = RemoveNetworkRule{} - mi := &file_openshell_proto_msgTypes[132] + mi := &file_openshell_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9553,7 +9695,7 @@ func (x *RemoveNetworkRule) String() string { func (*RemoveNetworkRule) ProtoMessage() {} func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[132] + mi := &file_openshell_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9566,7 +9708,7 @@ func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkRule.ProtoReflect.Descriptor instead. func (*RemoveNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{132} + return file_openshell_proto_rawDescGZIP(), []int{134} } func (x *RemoveNetworkRule) GetRuleName() string { @@ -9587,7 +9729,7 @@ type AddDenyRules struct { func (x *AddDenyRules) Reset() { *x = AddDenyRules{} - mi := &file_openshell_proto_msgTypes[133] + mi := &file_openshell_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9599,7 +9741,7 @@ func (x *AddDenyRules) String() string { func (*AddDenyRules) ProtoMessage() {} func (x *AddDenyRules) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[133] + mi := &file_openshell_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9612,7 +9754,7 @@ func (x *AddDenyRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddDenyRules.ProtoReflect.Descriptor instead. func (*AddDenyRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{133} + return file_openshell_proto_rawDescGZIP(), []int{135} } func (x *AddDenyRules) GetHost() string { @@ -9647,7 +9789,7 @@ type AddAllowRules struct { func (x *AddAllowRules) Reset() { *x = AddAllowRules{} - mi := &file_openshell_proto_msgTypes[134] + mi := &file_openshell_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9659,7 +9801,7 @@ func (x *AddAllowRules) String() string { func (*AddAllowRules) ProtoMessage() {} func (x *AddAllowRules) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[134] + mi := &file_openshell_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9672,7 +9814,7 @@ func (x *AddAllowRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAllowRules.ProtoReflect.Descriptor instead. func (*AddAllowRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{134} + return file_openshell_proto_rawDescGZIP(), []int{136} } func (x *AddAllowRules) GetHost() string { @@ -9706,7 +9848,7 @@ type RemoveNetworkBinary struct { func (x *RemoveNetworkBinary) Reset() { *x = RemoveNetworkBinary{} - mi := &file_openshell_proto_msgTypes[135] + mi := &file_openshell_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9718,7 +9860,7 @@ func (x *RemoveNetworkBinary) String() string { func (*RemoveNetworkBinary) ProtoMessage() {} func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[135] + mi := &file_openshell_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9731,7 +9873,7 @@ func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkBinary.ProtoReflect.Descriptor instead. func (*RemoveNetworkBinary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{135} + return file_openshell_proto_rawDescGZIP(), []int{137} } func (x *RemoveNetworkBinary) GetRuleName() string { @@ -9767,7 +9909,7 @@ type UpdateConfigResponse struct { func (x *UpdateConfigResponse) Reset() { *x = UpdateConfigResponse{} - mi := &file_openshell_proto_msgTypes[136] + mi := &file_openshell_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9779,7 +9921,7 @@ func (x *UpdateConfigResponse) String() string { func (*UpdateConfigResponse) ProtoMessage() {} func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[136] + mi := &file_openshell_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9792,7 +9934,7 @@ func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateConfigResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{136} + return file_openshell_proto_rawDescGZIP(), []int{138} } func (x *UpdateConfigResponse) GetVersion() uint32 { @@ -9847,7 +9989,7 @@ type GetSandboxPolicyStatusRequest struct { func (x *GetSandboxPolicyStatusRequest) Reset() { *x = GetSandboxPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[137] + mi := &file_openshell_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9859,7 +10001,7 @@ func (x *GetSandboxPolicyStatusRequest) String() string { func (*GetSandboxPolicyStatusRequest) ProtoMessage() {} func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[137] + mi := &file_openshell_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9872,7 +10014,7 @@ func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{137} + return file_openshell_proto_rawDescGZIP(), []int{139} } func (x *GetSandboxPolicyStatusRequest) GetName() string { @@ -9916,7 +10058,7 @@ type GetSandboxPolicyStatusResponse struct { func (x *GetSandboxPolicyStatusResponse) Reset() { *x = GetSandboxPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9928,7 +10070,7 @@ func (x *GetSandboxPolicyStatusResponse) String() string { func (*GetSandboxPolicyStatusResponse) ProtoMessage() {} func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9941,7 +10083,7 @@ func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{138} + return file_openshell_proto_rawDescGZIP(), []int{140} } func (x *GetSandboxPolicyStatusResponse) GetRevision() *SandboxPolicyRevision { @@ -9975,7 +10117,7 @@ type ListSandboxPoliciesRequest struct { func (x *ListSandboxPoliciesRequest) Reset() { *x = ListSandboxPoliciesRequest{} - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9987,7 +10129,7 @@ func (x *ListSandboxPoliciesRequest) String() string { func (*ListSandboxPoliciesRequest) ProtoMessage() {} func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10000,7 +10142,7 @@ func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesRequest.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{139} + return file_openshell_proto_rawDescGZIP(), []int{141} } func (x *ListSandboxPoliciesRequest) GetName() string { @@ -10050,7 +10192,7 @@ type ListSandboxPoliciesResponse struct { func (x *ListSandboxPoliciesResponse) Reset() { *x = ListSandboxPoliciesResponse{} - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10062,7 +10204,7 @@ func (x *ListSandboxPoliciesResponse) String() string { func (*ListSandboxPoliciesResponse) ProtoMessage() {} func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10075,7 +10217,7 @@ func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesResponse.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{140} + return file_openshell_proto_rawDescGZIP(), []int{142} } func (x *ListSandboxPoliciesResponse) GetRevisions() []*SandboxPolicyRevision { @@ -10102,7 +10244,7 @@ type ReportPolicyStatusRequest struct { func (x *ReportPolicyStatusRequest) Reset() { *x = ReportPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10114,7 +10256,7 @@ func (x *ReportPolicyStatusRequest) String() string { func (*ReportPolicyStatusRequest) ProtoMessage() {} func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10127,7 +10269,7 @@ func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{141} + return file_openshell_proto_rawDescGZIP(), []int{143} } func (x *ReportPolicyStatusRequest) GetSandboxId() string { @@ -10167,7 +10309,7 @@ type ReportPolicyStatusResponse struct { func (x *ReportPolicyStatusResponse) Reset() { *x = ReportPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10179,7 +10321,7 @@ func (x *ReportPolicyStatusResponse) String() string { func (*ReportPolicyStatusResponse) ProtoMessage() {} func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10192,7 +10334,7 @@ func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{142} + return file_openshell_proto_rawDescGZIP(), []int{144} } // A versioned policy revision with metadata. @@ -10225,7 +10367,7 @@ type SandboxPolicyRevision struct { func (x *SandboxPolicyRevision) Reset() { *x = SandboxPolicyRevision{} - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10237,7 +10379,7 @@ func (x *SandboxPolicyRevision) String() string { func (*SandboxPolicyRevision) ProtoMessage() {} func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10250,7 +10392,7 @@ func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxPolicyRevision.ProtoReflect.Descriptor instead. func (*SandboxPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{143} + return file_openshell_proto_rawDescGZIP(), []int{145} } func (x *SandboxPolicyRevision) GetVersion() uint32 { @@ -10330,7 +10472,7 @@ type GetSandboxLogsRequest struct { func (x *GetSandboxLogsRequest) Reset() { *x = GetSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10342,7 +10484,7 @@ func (x *GetSandboxLogsRequest) String() string { func (*GetSandboxLogsRequest) ProtoMessage() {} func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10355,7 +10497,7 @@ func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*GetSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{144} + return file_openshell_proto_rawDescGZIP(), []int{146} } func (x *GetSandboxLogsRequest) GetSandboxId() string { @@ -10413,7 +10555,7 @@ type PushSandboxLogsRequest struct { func (x *PushSandboxLogsRequest) Reset() { *x = PushSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10425,7 +10567,7 @@ func (x *PushSandboxLogsRequest) String() string { func (*PushSandboxLogsRequest) ProtoMessage() {} func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10438,7 +10580,7 @@ func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*PushSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{145} + return file_openshell_proto_rawDescGZIP(), []int{147} } func (x *PushSandboxLogsRequest) GetSandboxId() string { @@ -10464,7 +10606,7 @@ type PushSandboxLogsResponse struct { func (x *PushSandboxLogsResponse) Reset() { *x = PushSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10476,7 +10618,7 @@ func (x *PushSandboxLogsResponse) String() string { func (*PushSandboxLogsResponse) ProtoMessage() {} func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10489,7 +10631,7 @@ func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*PushSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{146} + return file_openshell_proto_rawDescGZIP(), []int{148} } // Get sandbox logs response. @@ -10505,7 +10647,7 @@ type GetSandboxLogsResponse struct { func (x *GetSandboxLogsResponse) Reset() { *x = GetSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10517,7 +10659,7 @@ func (x *GetSandboxLogsResponse) String() string { func (*GetSandboxLogsResponse) ProtoMessage() {} func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10530,7 +10672,7 @@ func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*GetSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{147} + return file_openshell_proto_rawDescGZIP(), []int{149} } func (x *GetSandboxLogsResponse) GetLogs() []*SandboxLogLine { @@ -10563,7 +10705,7 @@ type SupervisorMessage struct { func (x *SupervisorMessage) Reset() { *x = SupervisorMessage{} - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10575,7 +10717,7 @@ func (x *SupervisorMessage) String() string { func (*SupervisorMessage) ProtoMessage() {} func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10588,7 +10730,7 @@ func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorMessage.ProtoReflect.Descriptor instead. func (*SupervisorMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{148} + return file_openshell_proto_rawDescGZIP(), []int{150} } func (x *SupervisorMessage) GetPayload() isSupervisorMessage_Payload { @@ -10679,7 +10821,7 @@ type GatewayMessage struct { func (x *GatewayMessage) Reset() { *x = GatewayMessage{} - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10691,7 +10833,7 @@ func (x *GatewayMessage) String() string { func (*GatewayMessage) ProtoMessage() {} func (x *GatewayMessage) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[151] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10704,7 +10846,7 @@ func (x *GatewayMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayMessage.ProtoReflect.Descriptor instead. func (*GatewayMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{149} + return file_openshell_proto_rawDescGZIP(), []int{151} } func (x *GatewayMessage) GetPayload() isGatewayMessage_Payload { @@ -10806,7 +10948,7 @@ type SupervisorHello struct { func (x *SupervisorHello) Reset() { *x = SupervisorHello{} - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10818,7 +10960,7 @@ func (x *SupervisorHello) String() string { func (*SupervisorHello) ProtoMessage() {} func (x *SupervisorHello) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[152] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10831,7 +10973,7 @@ func (x *SupervisorHello) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHello.ProtoReflect.Descriptor instead. func (*SupervisorHello) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{150} + return file_openshell_proto_rawDescGZIP(), []int{152} } func (x *SupervisorHello) GetSandboxId() string { @@ -10861,7 +11003,7 @@ type SessionAccepted struct { func (x *SessionAccepted) Reset() { *x = SessionAccepted{} - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10873,7 +11015,7 @@ func (x *SessionAccepted) String() string { func (*SessionAccepted) ProtoMessage() {} func (x *SessionAccepted) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10886,7 +11028,7 @@ func (x *SessionAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionAccepted.ProtoReflect.Descriptor instead. func (*SessionAccepted) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{151} + return file_openshell_proto_rawDescGZIP(), []int{153} } func (x *SessionAccepted) GetSessionId() string { @@ -10914,7 +11056,7 @@ type SessionRejected struct { func (x *SessionRejected) Reset() { *x = SessionRejected{} - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10926,7 +11068,7 @@ func (x *SessionRejected) String() string { func (*SessionRejected) ProtoMessage() {} func (x *SessionRejected) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[154] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10939,7 +11081,7 @@ func (x *SessionRejected) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionRejected.ProtoReflect.Descriptor instead. func (*SessionRejected) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{152} + return file_openshell_proto_rawDescGZIP(), []int{154} } func (x *SessionRejected) GetReason() string { @@ -10958,7 +11100,7 @@ type SupervisorHeartbeat struct { func (x *SupervisorHeartbeat) Reset() { *x = SupervisorHeartbeat{} - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10970,7 +11112,7 @@ func (x *SupervisorHeartbeat) String() string { func (*SupervisorHeartbeat) ProtoMessage() {} func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10983,7 +11125,7 @@ func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHeartbeat.ProtoReflect.Descriptor instead. func (*SupervisorHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{153} + return file_openshell_proto_rawDescGZIP(), []int{155} } // Gateway heartbeat. @@ -10995,7 +11137,7 @@ type GatewayHeartbeat struct { func (x *GatewayHeartbeat) Reset() { *x = GatewayHeartbeat{} - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11007,7 +11149,7 @@ func (x *GatewayHeartbeat) String() string { func (*GatewayHeartbeat) ProtoMessage() {} func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[156] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11020,7 +11162,7 @@ func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayHeartbeat.ProtoReflect.Descriptor instead. func (*GatewayHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{154} + return file_openshell_proto_rawDescGZIP(), []int{156} } // Terminal result reported before the supervisor shuts down. A successful RPC @@ -11037,7 +11179,7 @@ type ReportMainProcessExitRequest struct { func (x *ReportMainProcessExitRequest) Reset() { *x = ReportMainProcessExitRequest{} - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11049,7 +11191,7 @@ func (x *ReportMainProcessExitRequest) String() string { func (*ReportMainProcessExitRequest) ProtoMessage() {} func (x *ReportMainProcessExitRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[157] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11062,7 +11204,7 @@ func (x *ReportMainProcessExitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportMainProcessExitRequest.ProtoReflect.Descriptor instead. func (*ReportMainProcessExitRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{155} + return file_openshell_proto_rawDescGZIP(), []int{157} } func (x *ReportMainProcessExitRequest) GetSandboxId() string { @@ -11094,7 +11236,7 @@ type ReportMainProcessExitResponse struct { func (x *ReportMainProcessExitResponse) Reset() { *x = ReportMainProcessExitResponse{} - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11106,7 +11248,7 @@ func (x *ReportMainProcessExitResponse) String() string { func (*ReportMainProcessExitResponse) ProtoMessage() {} func (x *ReportMainProcessExitResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11119,7 +11261,7 @@ func (x *ReportMainProcessExitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportMainProcessExitResponse.ProtoReflect.Descriptor instead. func (*ReportMainProcessExitResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{156} + return file_openshell_proto_rawDescGZIP(), []int{158} } // Terminal-delivery completion reported after all expected foreground SSH @@ -11134,7 +11276,7 @@ type FinalizeMainProcessExitRequest struct { func (x *FinalizeMainProcessExitRequest) Reset() { *x = FinalizeMainProcessExitRequest{} - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11146,7 +11288,7 @@ func (x *FinalizeMainProcessExitRequest) String() string { func (*FinalizeMainProcessExitRequest) ProtoMessage() {} func (x *FinalizeMainProcessExitRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[159] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11159,7 +11301,7 @@ func (x *FinalizeMainProcessExitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizeMainProcessExitRequest.ProtoReflect.Descriptor instead. func (*FinalizeMainProcessExitRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{157} + return file_openshell_proto_rawDescGZIP(), []int{159} } func (x *FinalizeMainProcessExitRequest) GetSandboxId() string { @@ -11184,7 +11326,7 @@ type FinalizeMainProcessExitResponse struct { func (x *FinalizeMainProcessExitResponse) Reset() { *x = FinalizeMainProcessExitResponse{} - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11196,7 +11338,7 @@ func (x *FinalizeMainProcessExitResponse) String() string { func (*FinalizeMainProcessExitResponse) ProtoMessage() {} func (x *FinalizeMainProcessExitResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[160] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11209,7 +11351,7 @@ func (x *FinalizeMainProcessExitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizeMainProcessExitResponse.ProtoReflect.Descriptor instead. func (*FinalizeMainProcessExitResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{158} + return file_openshell_proto_rawDescGZIP(), []int{160} } // Gateway requests the supervisor to open a relay channel. @@ -11238,7 +11380,7 @@ type RelayOpen struct { func (x *RelayOpen) Reset() { *x = RelayOpen{} - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11250,7 +11392,7 @@ func (x *RelayOpen) String() string { func (*RelayOpen) ProtoMessage() {} func (x *RelayOpen) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[161] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11263,7 +11405,7 @@ func (x *RelayOpen) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpen.ProtoReflect.Descriptor instead. func (*RelayOpen) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{159} + return file_openshell_proto_rawDescGZIP(), []int{161} } func (x *RelayOpen) GetChannelId() string { @@ -11330,7 +11472,7 @@ type SshRelayTarget struct { func (x *SshRelayTarget) Reset() { *x = SshRelayTarget{} - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11342,7 +11484,7 @@ func (x *SshRelayTarget) String() string { func (*SshRelayTarget) ProtoMessage() {} func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[162] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11355,7 +11497,7 @@ func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use SshRelayTarget.ProtoReflect.Descriptor instead. func (*SshRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{160} + return file_openshell_proto_rawDescGZIP(), []int{162} } // TCP target dialed by the supervisor from inside the sandbox. @@ -11371,7 +11513,7 @@ type TcpRelayTarget struct { func (x *TcpRelayTarget) Reset() { *x = TcpRelayTarget{} - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11383,7 +11525,7 @@ func (x *TcpRelayTarget) String() string { func (*TcpRelayTarget) ProtoMessage() {} func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[163] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11396,7 +11538,7 @@ func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpRelayTarget.ProtoReflect.Descriptor instead. func (*TcpRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{161} + return file_openshell_proto_rawDescGZIP(), []int{163} } func (x *TcpRelayTarget) GetHost() string { @@ -11424,7 +11566,7 @@ type RelayInit struct { func (x *RelayInit) Reset() { *x = RelayInit{} - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11436,7 +11578,7 @@ func (x *RelayInit) String() string { func (*RelayInit) ProtoMessage() {} func (x *RelayInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[164] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11449,7 +11591,7 @@ func (x *RelayInit) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayInit.ProtoReflect.Descriptor instead. func (*RelayInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{162} + return file_openshell_proto_rawDescGZIP(), []int{164} } func (x *RelayInit) GetChannelId() string { @@ -11476,7 +11618,7 @@ type RelayFrame struct { func (x *RelayFrame) Reset() { *x = RelayFrame{} - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11488,7 +11630,7 @@ func (x *RelayFrame) String() string { func (*RelayFrame) ProtoMessage() {} func (x *RelayFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[165] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11501,7 +11643,7 @@ func (x *RelayFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayFrame.ProtoReflect.Descriptor instead. func (*RelayFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{163} + return file_openshell_proto_rawDescGZIP(), []int{165} } func (x *RelayFrame) GetPayload() isRelayFrame_Payload { @@ -11560,7 +11702,7 @@ type RelayOpenResult struct { func (x *RelayOpenResult) Reset() { *x = RelayOpenResult{} - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11572,7 +11714,7 @@ func (x *RelayOpenResult) String() string { func (*RelayOpenResult) ProtoMessage() {} func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[166] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11585,7 +11727,7 @@ func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpenResult.ProtoReflect.Descriptor instead. func (*RelayOpenResult) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{164} + return file_openshell_proto_rawDescGZIP(), []int{166} } func (x *RelayOpenResult) GetChannelId() string { @@ -11622,7 +11764,7 @@ type RelayClose struct { func (x *RelayClose) Reset() { *x = RelayClose{} - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11634,7 +11776,7 @@ func (x *RelayClose) String() string { func (*RelayClose) ProtoMessage() {} func (x *RelayClose) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[167] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11647,7 +11789,7 @@ func (x *RelayClose) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayClose.ProtoReflect.Descriptor instead. func (*RelayClose) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{165} + return file_openshell_proto_rawDescGZIP(), []int{167} } func (x *RelayClose) GetChannelId() string { @@ -11681,7 +11823,7 @@ type L7RequestSample struct { func (x *L7RequestSample) Reset() { *x = L7RequestSample{} - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11693,7 +11835,7 @@ func (x *L7RequestSample) String() string { func (*L7RequestSample) ProtoMessage() {} func (x *L7RequestSample) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[168] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11706,7 +11848,7 @@ func (x *L7RequestSample) ProtoReflect() protoreflect.Message { // Deprecated: Use L7RequestSample.ProtoReflect.Descriptor instead. func (*L7RequestSample) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{166} + return file_openshell_proto_rawDescGZIP(), []int{168} } func (x *L7RequestSample) GetMethod() string { @@ -11780,7 +11922,7 @@ type DenialSummary struct { func (x *DenialSummary) Reset() { *x = DenialSummary{} - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11792,7 +11934,7 @@ func (x *DenialSummary) String() string { func (*DenialSummary) ProtoMessage() {} func (x *DenialSummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[169] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11805,7 +11947,7 @@ func (x *DenialSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialSummary.ProtoReflect.Descriptor instead. func (*DenialSummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{167} + return file_openshell_proto_rawDescGZIP(), []int{169} } func (x *DenialSummary) GetSandboxId() string { @@ -11940,7 +12082,7 @@ type DenialGroupCount struct { func (x *DenialGroupCount) Reset() { *x = DenialGroupCount{} - mi := &file_openshell_proto_msgTypes[168] + mi := &file_openshell_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11952,7 +12094,7 @@ func (x *DenialGroupCount) String() string { func (*DenialGroupCount) ProtoMessage() {} func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[168] + mi := &file_openshell_proto_msgTypes[170] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11965,7 +12107,7 @@ func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialGroupCount.ProtoReflect.Descriptor instead. func (*DenialGroupCount) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{168} + return file_openshell_proto_rawDescGZIP(), []int{170} } func (x *DenialGroupCount) GetDenyGroup() string { @@ -11998,7 +12140,7 @@ type NetworkActivitySummary struct { func (x *NetworkActivitySummary) Reset() { *x = NetworkActivitySummary{} - mi := &file_openshell_proto_msgTypes[169] + mi := &file_openshell_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12010,7 +12152,7 @@ func (x *NetworkActivitySummary) String() string { func (*NetworkActivitySummary) ProtoMessage() {} func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[169] + mi := &file_openshell_proto_msgTypes[171] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12023,7 +12165,7 @@ func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkActivitySummary.ProtoReflect.Descriptor instead. func (*NetworkActivitySummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{169} + return file_openshell_proto_rawDescGZIP(), []int{171} } func (x *NetworkActivitySummary) GetNetworkActivityCount() uint32 { @@ -12111,7 +12253,7 @@ type PolicyChunk struct { func (x *PolicyChunk) Reset() { *x = PolicyChunk{} - mi := &file_openshell_proto_msgTypes[170] + mi := &file_openshell_proto_msgTypes[172] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12123,7 +12265,7 @@ func (x *PolicyChunk) String() string { func (*PolicyChunk) ProtoMessage() {} func (x *PolicyChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[170] + mi := &file_openshell_proto_msgTypes[172] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12136,7 +12278,7 @@ func (x *PolicyChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyChunk.ProtoReflect.Descriptor instead. func (*PolicyChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{170} + return file_openshell_proto_rawDescGZIP(), []int{172} } func (x *PolicyChunk) GetId() string { @@ -12324,7 +12466,7 @@ type DraftPolicyUpdate struct { func (x *DraftPolicyUpdate) Reset() { *x = DraftPolicyUpdate{} - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[173] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12336,7 +12478,7 @@ func (x *DraftPolicyUpdate) String() string { func (*DraftPolicyUpdate) ProtoMessage() {} func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[173] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12349,7 +12491,7 @@ func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftPolicyUpdate.ProtoReflect.Descriptor instead. func (*DraftPolicyUpdate) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{171} + return file_openshell_proto_rawDescGZIP(), []int{173} } func (x *DraftPolicyUpdate) GetDraftVersion() uint64 { @@ -12407,7 +12549,7 @@ type SubmitPolicyAnalysisRequest struct { func (x *SubmitPolicyAnalysisRequest) Reset() { *x = SubmitPolicyAnalysisRequest{} - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[174] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12419,7 +12561,7 @@ func (x *SubmitPolicyAnalysisRequest) String() string { func (*SubmitPolicyAnalysisRequest) ProtoMessage() {} func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[174] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12432,7 +12574,7 @@ func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisRequest.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{172} + return file_openshell_proto_rawDescGZIP(), []int{174} } func (x *SubmitPolicyAnalysisRequest) GetSummaries() []*DenialSummary { @@ -12495,7 +12637,7 @@ type SubmitPolicyAnalysisResponse struct { func (x *SubmitPolicyAnalysisResponse) Reset() { *x = SubmitPolicyAnalysisResponse{} - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[175] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12507,7 +12649,7 @@ func (x *SubmitPolicyAnalysisResponse) String() string { func (*SubmitPolicyAnalysisResponse) ProtoMessage() {} func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[175] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12520,7 +12662,7 @@ func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisResponse.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{173} + return file_openshell_proto_rawDescGZIP(), []int{175} } func (x *SubmitPolicyAnalysisResponse) GetAcceptedChunks() uint32 { @@ -12566,7 +12708,7 @@ type GetDraftPolicyRequest struct { func (x *GetDraftPolicyRequest) Reset() { *x = GetDraftPolicyRequest{} - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[176] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12578,7 +12720,7 @@ func (x *GetDraftPolicyRequest) String() string { func (*GetDraftPolicyRequest) ProtoMessage() {} func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[176] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12591,7 +12733,7 @@ func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyRequest.ProtoReflect.Descriptor instead. func (*GetDraftPolicyRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{174} + return file_openshell_proto_rawDescGZIP(), []int{176} } func (x *GetDraftPolicyRequest) GetName() string { @@ -12631,7 +12773,7 @@ type GetDraftPolicyResponse struct { func (x *GetDraftPolicyResponse) Reset() { *x = GetDraftPolicyResponse{} - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[177] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12643,7 +12785,7 @@ func (x *GetDraftPolicyResponse) String() string { func (*GetDraftPolicyResponse) ProtoMessage() {} func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[177] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12656,7 +12798,7 @@ func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyResponse.ProtoReflect.Descriptor instead. func (*GetDraftPolicyResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{175} + return file_openshell_proto_rawDescGZIP(), []int{177} } func (x *GetDraftPolicyResponse) GetChunks() []*PolicyChunk { @@ -12705,7 +12847,7 @@ type ApproveDraftChunkRequest struct { func (x *ApproveDraftChunkRequest) Reset() { *x = ApproveDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[178] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12717,7 +12859,7 @@ func (x *ApproveDraftChunkRequest) String() string { func (*ApproveDraftChunkRequest) ProtoMessage() {} func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[178] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12730,7 +12872,7 @@ func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkRequest.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{176} + return file_openshell_proto_rawDescGZIP(), []int{178} } func (x *ApproveDraftChunkRequest) GetName() string { @@ -12773,7 +12915,7 @@ type ApproveDraftChunkResponse struct { func (x *ApproveDraftChunkResponse) Reset() { *x = ApproveDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12785,7 +12927,7 @@ func (x *ApproveDraftChunkResponse) String() string { func (*ApproveDraftChunkResponse) ProtoMessage() {} func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[179] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12798,7 +12940,7 @@ func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkResponse.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{177} + return file_openshell_proto_rawDescGZIP(), []int{179} } func (x *ApproveDraftChunkResponse) GetPolicyVersion() uint32 { @@ -12832,7 +12974,7 @@ type RejectDraftChunkRequest struct { func (x *RejectDraftChunkRequest) Reset() { *x = RejectDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12844,7 +12986,7 @@ func (x *RejectDraftChunkRequest) String() string { func (*RejectDraftChunkRequest) ProtoMessage() {} func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[180] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12857,7 +12999,7 @@ func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkRequest.ProtoReflect.Descriptor instead. func (*RejectDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{178} + return file_openshell_proto_rawDescGZIP(), []int{180} } func (x *RejectDraftChunkRequest) GetName() string { @@ -12896,7 +13038,7 @@ type RejectDraftChunkResponse struct { func (x *RejectDraftChunkResponse) Reset() { *x = RejectDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12908,7 +13050,7 @@ func (x *RejectDraftChunkResponse) String() string { func (*RejectDraftChunkResponse) ProtoMessage() {} func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[181] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12921,7 +13063,7 @@ func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkResponse.ProtoReflect.Descriptor instead. func (*RejectDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{179} + return file_openshell_proto_rawDescGZIP(), []int{181} } // Approve all pending chunks. @@ -12935,7 +13077,7 @@ type DraftChunkApproval struct { func (x *DraftChunkApproval) Reset() { *x = DraftChunkApproval{} - mi := &file_openshell_proto_msgTypes[180] + mi := &file_openshell_proto_msgTypes[182] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12947,7 +13089,7 @@ func (x *DraftChunkApproval) String() string { func (*DraftChunkApproval) ProtoMessage() {} func (x *DraftChunkApproval) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[180] + mi := &file_openshell_proto_msgTypes[182] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12960,7 +13102,7 @@ func (x *DraftChunkApproval) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftChunkApproval.ProtoReflect.Descriptor instead. func (*DraftChunkApproval) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{180} + return file_openshell_proto_rawDescGZIP(), []int{182} } func (x *DraftChunkApproval) GetChunkId() string { @@ -12994,7 +13136,7 @@ type ApproveAllDraftChunksRequest struct { func (x *ApproveAllDraftChunksRequest) Reset() { *x = ApproveAllDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[181] + mi := &file_openshell_proto_msgTypes[183] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13006,7 +13148,7 @@ func (x *ApproveAllDraftChunksRequest) String() string { func (*ApproveAllDraftChunksRequest) ProtoMessage() {} func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[181] + mi := &file_openshell_proto_msgTypes[183] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13019,7 +13161,7 @@ func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{181} + return file_openshell_proto_rawDescGZIP(), []int{183} } func (x *ApproveAllDraftChunksRequest) GetName() string { @@ -13067,7 +13209,7 @@ type ApproveAllDraftChunksResponse struct { func (x *ApproveAllDraftChunksResponse) Reset() { *x = ApproveAllDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[182] + mi := &file_openshell_proto_msgTypes[184] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13079,7 +13221,7 @@ func (x *ApproveAllDraftChunksResponse) String() string { func (*ApproveAllDraftChunksResponse) ProtoMessage() {} func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[182] + mi := &file_openshell_proto_msgTypes[184] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13092,7 +13234,7 @@ func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{182} + return file_openshell_proto_rawDescGZIP(), []int{184} } func (x *ApproveAllDraftChunksResponse) GetPolicyVersion() uint32 { @@ -13140,7 +13282,7 @@ type EditDraftChunkRequest struct { func (x *EditDraftChunkRequest) Reset() { *x = EditDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[183] + mi := &file_openshell_proto_msgTypes[185] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13152,7 +13294,7 @@ func (x *EditDraftChunkRequest) String() string { func (*EditDraftChunkRequest) ProtoMessage() {} func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[183] + mi := &file_openshell_proto_msgTypes[185] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13165,7 +13307,7 @@ func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkRequest.ProtoReflect.Descriptor instead. func (*EditDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{183} + return file_openshell_proto_rawDescGZIP(), []int{185} } func (x *EditDraftChunkRequest) GetName() string { @@ -13204,7 +13346,7 @@ type EditDraftChunkResponse struct { func (x *EditDraftChunkResponse) Reset() { *x = EditDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[184] + mi := &file_openshell_proto_msgTypes[186] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13216,7 +13358,7 @@ func (x *EditDraftChunkResponse) String() string { func (*EditDraftChunkResponse) ProtoMessage() {} func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[184] + mi := &file_openshell_proto_msgTypes[186] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13229,7 +13371,7 @@ func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkResponse.ProtoReflect.Descriptor instead. func (*EditDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{184} + return file_openshell_proto_rawDescGZIP(), []int{186} } // Reverse an approval (remove merged rule from active policy). @@ -13247,7 +13389,7 @@ type UndoDraftChunkRequest struct { func (x *UndoDraftChunkRequest) Reset() { *x = UndoDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[185] + mi := &file_openshell_proto_msgTypes[187] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13259,7 +13401,7 @@ func (x *UndoDraftChunkRequest) String() string { func (*UndoDraftChunkRequest) ProtoMessage() {} func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[185] + mi := &file_openshell_proto_msgTypes[187] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13272,7 +13414,7 @@ func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkRequest.ProtoReflect.Descriptor instead. func (*UndoDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{185} + return file_openshell_proto_rawDescGZIP(), []int{187} } func (x *UndoDraftChunkRequest) GetName() string { @@ -13308,7 +13450,7 @@ type UndoDraftChunkResponse struct { func (x *UndoDraftChunkResponse) Reset() { *x = UndoDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[186] + mi := &file_openshell_proto_msgTypes[188] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13320,7 +13462,7 @@ func (x *UndoDraftChunkResponse) String() string { func (*UndoDraftChunkResponse) ProtoMessage() {} func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[186] + mi := &file_openshell_proto_msgTypes[188] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13333,7 +13475,7 @@ func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkResponse.ProtoReflect.Descriptor instead. func (*UndoDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{186} + return file_openshell_proto_rawDescGZIP(), []int{188} } func (x *UndoDraftChunkResponse) GetPolicyVersion() uint32 { @@ -13363,7 +13505,7 @@ type ClearDraftChunksRequest struct { func (x *ClearDraftChunksRequest) Reset() { *x = ClearDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[187] + mi := &file_openshell_proto_msgTypes[189] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13375,7 +13517,7 @@ func (x *ClearDraftChunksRequest) String() string { func (*ClearDraftChunksRequest) ProtoMessage() {} func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[187] + mi := &file_openshell_proto_msgTypes[189] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13388,7 +13530,7 @@ func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ClearDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{187} + return file_openshell_proto_rawDescGZIP(), []int{189} } func (x *ClearDraftChunksRequest) GetName() string { @@ -13415,7 +13557,7 @@ type ClearDraftChunksResponse struct { func (x *ClearDraftChunksResponse) Reset() { *x = ClearDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[188] + mi := &file_openshell_proto_msgTypes[190] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13427,7 +13569,7 @@ func (x *ClearDraftChunksResponse) String() string { func (*ClearDraftChunksResponse) ProtoMessage() {} func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[188] + mi := &file_openshell_proto_msgTypes[190] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13440,7 +13582,7 @@ func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ClearDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{188} + return file_openshell_proto_rawDescGZIP(), []int{190} } func (x *ClearDraftChunksResponse) GetChunksCleared() uint32 { @@ -13463,7 +13605,7 @@ type GetDraftHistoryRequest struct { func (x *GetDraftHistoryRequest) Reset() { *x = GetDraftHistoryRequest{} - mi := &file_openshell_proto_msgTypes[189] + mi := &file_openshell_proto_msgTypes[191] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13475,7 +13617,7 @@ func (x *GetDraftHistoryRequest) String() string { func (*GetDraftHistoryRequest) ProtoMessage() {} func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[189] + mi := &file_openshell_proto_msgTypes[191] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13488,7 +13630,7 @@ func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryRequest.ProtoReflect.Descriptor instead. func (*GetDraftHistoryRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{189} + return file_openshell_proto_rawDescGZIP(), []int{191} } func (x *GetDraftHistoryRequest) GetName() string { @@ -13522,7 +13664,7 @@ type DraftHistoryEntry struct { func (x *DraftHistoryEntry) Reset() { *x = DraftHistoryEntry{} - mi := &file_openshell_proto_msgTypes[190] + mi := &file_openshell_proto_msgTypes[192] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13534,7 +13676,7 @@ func (x *DraftHistoryEntry) String() string { func (*DraftHistoryEntry) ProtoMessage() {} func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[190] + mi := &file_openshell_proto_msgTypes[192] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13547,7 +13689,7 @@ func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftHistoryEntry.ProtoReflect.Descriptor instead. func (*DraftHistoryEntry) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{190} + return file_openshell_proto_rawDescGZIP(), []int{192} } func (x *DraftHistoryEntry) GetTimestampMs() int64 { @@ -13588,7 +13730,7 @@ type GetDraftHistoryResponse struct { func (x *GetDraftHistoryResponse) Reset() { *x = GetDraftHistoryResponse{} - mi := &file_openshell_proto_msgTypes[191] + mi := &file_openshell_proto_msgTypes[193] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13600,7 +13742,7 @@ func (x *GetDraftHistoryResponse) String() string { func (*GetDraftHistoryResponse) ProtoMessage() {} func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[191] + mi := &file_openshell_proto_msgTypes[193] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13613,7 +13755,7 @@ func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryResponse.ProtoReflect.Descriptor instead. func (*GetDraftHistoryResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{191} + return file_openshell_proto_rawDescGZIP(), []int{193} } func (x *GetDraftHistoryResponse) GetEntries() []*DraftHistoryEntry { @@ -13642,7 +13784,7 @@ type PolicyRevisionPayload struct { func (x *PolicyRevisionPayload) Reset() { *x = PolicyRevisionPayload{} - mi := &file_openshell_proto_msgTypes[192] + mi := &file_openshell_proto_msgTypes[194] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13654,7 +13796,7 @@ func (x *PolicyRevisionPayload) String() string { func (*PolicyRevisionPayload) ProtoMessage() {} func (x *PolicyRevisionPayload) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[192] + mi := &file_openshell_proto_msgTypes[194] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13667,7 +13809,7 @@ func (x *PolicyRevisionPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyRevisionPayload.ProtoReflect.Descriptor instead. func (*PolicyRevisionPayload) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{192} + return file_openshell_proto_rawDescGZIP(), []int{194} } func (x *PolicyRevisionPayload) GetPolicy() *sandboxv1.SandboxPolicy { @@ -13746,7 +13888,7 @@ type DraftChunkPayload struct { func (x *DraftChunkPayload) Reset() { *x = DraftChunkPayload{} - mi := &file_openshell_proto_msgTypes[193] + mi := &file_openshell_proto_msgTypes[195] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13758,7 +13900,7 @@ func (x *DraftChunkPayload) String() string { func (*DraftChunkPayload) ProtoMessage() {} func (x *DraftChunkPayload) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[193] + mi := &file_openshell_proto_msgTypes[195] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13771,7 +13913,7 @@ func (x *DraftChunkPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftChunkPayload.ProtoReflect.Descriptor instead. func (*DraftChunkPayload) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{193} + return file_openshell_proto_rawDescGZIP(), []int{195} } func (x *DraftChunkPayload) GetRuleName() string { @@ -13919,7 +14061,7 @@ type StoredPolicyRevision struct { func (x *StoredPolicyRevision) Reset() { *x = StoredPolicyRevision{} - mi := &file_openshell_proto_msgTypes[194] + mi := &file_openshell_proto_msgTypes[196] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13931,7 +14073,7 @@ func (x *StoredPolicyRevision) String() string { func (*StoredPolicyRevision) ProtoMessage() {} func (x *StoredPolicyRevision) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[194] + mi := &file_openshell_proto_msgTypes[196] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13944,7 +14086,7 @@ func (x *StoredPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredPolicyRevision.ProtoReflect.Descriptor instead. func (*StoredPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{194} + return file_openshell_proto_rawDescGZIP(), []int{196} } func (x *StoredPolicyRevision) GetId() string { @@ -14053,7 +14195,7 @@ type StoredDraftChunk struct { func (x *StoredDraftChunk) Reset() { *x = StoredDraftChunk{} - mi := &file_openshell_proto_msgTypes[195] + mi := &file_openshell_proto_msgTypes[197] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14065,7 +14207,7 @@ func (x *StoredDraftChunk) String() string { func (*StoredDraftChunk) ProtoMessage() {} func (x *StoredDraftChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[195] + mi := &file_openshell_proto_msgTypes[197] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14078,7 +14220,7 @@ func (x *StoredDraftChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredDraftChunk.ProtoReflect.Descriptor instead. func (*StoredDraftChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{195} + return file_openshell_proto_rawDescGZIP(), []int{197} } func (x *StoredDraftChunk) GetId() string { @@ -14269,7 +14411,7 @@ type CreateWorkspaceRequest struct { func (x *CreateWorkspaceRequest) Reset() { *x = CreateWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[196] + mi := &file_openshell_proto_msgTypes[198] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14281,7 +14423,7 @@ func (x *CreateWorkspaceRequest) String() string { func (*CreateWorkspaceRequest) ProtoMessage() {} func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[196] + mi := &file_openshell_proto_msgTypes[198] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14294,7 +14436,7 @@ func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceRequest.ProtoReflect.Descriptor instead. func (*CreateWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{196} + return file_openshell_proto_rawDescGZIP(), []int{198} } func (x *CreateWorkspaceRequest) GetName() string { @@ -14321,7 +14463,7 @@ type CreateWorkspaceResponse struct { func (x *CreateWorkspaceResponse) Reset() { *x = CreateWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[197] + mi := &file_openshell_proto_msgTypes[199] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14333,7 +14475,7 @@ func (x *CreateWorkspaceResponse) String() string { func (*CreateWorkspaceResponse) ProtoMessage() {} func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[197] + mi := &file_openshell_proto_msgTypes[199] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14346,7 +14488,7 @@ func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceResponse.ProtoReflect.Descriptor instead. func (*CreateWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{197} + return file_openshell_proto_rawDescGZIP(), []int{199} } func (x *CreateWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -14367,7 +14509,7 @@ type GetWorkspaceRequest struct { func (x *GetWorkspaceRequest) Reset() { *x = GetWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[198] + mi := &file_openshell_proto_msgTypes[200] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14379,7 +14521,7 @@ func (x *GetWorkspaceRequest) String() string { func (*GetWorkspaceRequest) ProtoMessage() {} func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[198] + mi := &file_openshell_proto_msgTypes[200] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14392,7 +14534,7 @@ func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceRequest.ProtoReflect.Descriptor instead. func (*GetWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{198} + return file_openshell_proto_rawDescGZIP(), []int{200} } func (x *GetWorkspaceRequest) GetName() string { @@ -14412,7 +14554,7 @@ type GetWorkspaceResponse struct { func (x *GetWorkspaceResponse) Reset() { *x = GetWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[199] + mi := &file_openshell_proto_msgTypes[201] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14424,7 +14566,7 @@ func (x *GetWorkspaceResponse) String() string { func (*GetWorkspaceResponse) ProtoMessage() {} func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[199] + mi := &file_openshell_proto_msgTypes[201] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14437,7 +14579,7 @@ func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceResponse.ProtoReflect.Descriptor instead. func (*GetWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{199} + return file_openshell_proto_rawDescGZIP(), []int{201} } func (x *GetWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -14460,7 +14602,7 @@ type ListWorkspacesRequest struct { func (x *ListWorkspacesRequest) Reset() { *x = ListWorkspacesRequest{} - mi := &file_openshell_proto_msgTypes[200] + mi := &file_openshell_proto_msgTypes[202] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14472,7 +14614,7 @@ func (x *ListWorkspacesRequest) String() string { func (*ListWorkspacesRequest) ProtoMessage() {} func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[200] + mi := &file_openshell_proto_msgTypes[202] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14485,7 +14627,7 @@ func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesRequest.ProtoReflect.Descriptor instead. func (*ListWorkspacesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{200} + return file_openshell_proto_rawDescGZIP(), []int{202} } func (x *ListWorkspacesRequest) GetLimit() uint32 { @@ -14519,7 +14661,7 @@ type ListWorkspacesResponse struct { func (x *ListWorkspacesResponse) Reset() { *x = ListWorkspacesResponse{} - mi := &file_openshell_proto_msgTypes[201] + mi := &file_openshell_proto_msgTypes[203] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14531,7 +14673,7 @@ func (x *ListWorkspacesResponse) String() string { func (*ListWorkspacesResponse) ProtoMessage() {} func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[201] + mi := &file_openshell_proto_msgTypes[203] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14544,7 +14686,7 @@ func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesResponse.ProtoReflect.Descriptor instead. func (*ListWorkspacesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{201} + return file_openshell_proto_rawDescGZIP(), []int{203} } func (x *ListWorkspacesResponse) GetWorkspaces() []*datamodelv1.Workspace { @@ -14565,7 +14707,7 @@ type DeleteWorkspaceRequest struct { func (x *DeleteWorkspaceRequest) Reset() { *x = DeleteWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[202] + mi := &file_openshell_proto_msgTypes[204] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14577,7 +14719,7 @@ func (x *DeleteWorkspaceRequest) String() string { func (*DeleteWorkspaceRequest) ProtoMessage() {} func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[202] + mi := &file_openshell_proto_msgTypes[204] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14590,7 +14732,7 @@ func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{202} + return file_openshell_proto_rawDescGZIP(), []int{204} } func (x *DeleteWorkspaceRequest) GetName() string { @@ -14610,7 +14752,7 @@ type DeleteWorkspaceResponse struct { func (x *DeleteWorkspaceResponse) Reset() { *x = DeleteWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[203] + mi := &file_openshell_proto_msgTypes[205] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14622,7 +14764,7 @@ func (x *DeleteWorkspaceResponse) String() string { func (*DeleteWorkspaceResponse) ProtoMessage() {} func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[203] + mi := &file_openshell_proto_msgTypes[205] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14635,7 +14777,7 @@ func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceResponse.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{203} + return file_openshell_proto_rawDescGZIP(), []int{205} } func (x *DeleteWorkspaceResponse) GetDeleted() bool { @@ -14659,7 +14801,7 @@ type WorkspaceMember struct { func (x *WorkspaceMember) Reset() { *x = WorkspaceMember{} - mi := &file_openshell_proto_msgTypes[204] + mi := &file_openshell_proto_msgTypes[206] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14671,7 +14813,7 @@ func (x *WorkspaceMember) String() string { func (*WorkspaceMember) ProtoMessage() {} func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[204] + mi := &file_openshell_proto_msgTypes[206] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14684,7 +14826,7 @@ func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkspaceMember.ProtoReflect.Descriptor instead. func (*WorkspaceMember) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{204} + return file_openshell_proto_rawDescGZIP(), []int{206} } func (x *WorkspaceMember) GetMetadata() *datamodelv1.ObjectMeta { @@ -14723,7 +14865,7 @@ type AddWorkspaceMemberRequest struct { func (x *AddWorkspaceMemberRequest) Reset() { *x = AddWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[205] + mi := &file_openshell_proto_msgTypes[207] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14735,7 +14877,7 @@ func (x *AddWorkspaceMemberRequest) String() string { func (*AddWorkspaceMemberRequest) ProtoMessage() {} func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[205] + mi := &file_openshell_proto_msgTypes[207] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14748,7 +14890,7 @@ func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{205} + return file_openshell_proto_rawDescGZIP(), []int{207} } func (x *AddWorkspaceMemberRequest) GetWorkspace() string { @@ -14782,7 +14924,7 @@ type AddWorkspaceMemberResponse struct { func (x *AddWorkspaceMemberResponse) Reset() { *x = AddWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[206] + mi := &file_openshell_proto_msgTypes[208] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14794,7 +14936,7 @@ func (x *AddWorkspaceMemberResponse) String() string { func (*AddWorkspaceMemberResponse) ProtoMessage() {} func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[206] + mi := &file_openshell_proto_msgTypes[208] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14807,7 +14949,7 @@ func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{206} + return file_openshell_proto_rawDescGZIP(), []int{208} } func (x *AddWorkspaceMemberResponse) GetMember() *WorkspaceMember { @@ -14830,7 +14972,7 @@ type RemoveWorkspaceMemberRequest struct { func (x *RemoveWorkspaceMemberRequest) Reset() { *x = RemoveWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[207] + mi := &file_openshell_proto_msgTypes[209] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14842,7 +14984,7 @@ func (x *RemoveWorkspaceMemberRequest) String() string { func (*RemoveWorkspaceMemberRequest) ProtoMessage() {} func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[207] + mi := &file_openshell_proto_msgTypes[209] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14855,7 +14997,7 @@ func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{207} + return file_openshell_proto_rawDescGZIP(), []int{209} } func (x *RemoveWorkspaceMemberRequest) GetWorkspace() string { @@ -14882,7 +15024,7 @@ type RemoveWorkspaceMemberResponse struct { func (x *RemoveWorkspaceMemberResponse) Reset() { *x = RemoveWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[208] + mi := &file_openshell_proto_msgTypes[210] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14894,7 +15036,7 @@ func (x *RemoveWorkspaceMemberResponse) String() string { func (*RemoveWorkspaceMemberResponse) ProtoMessage() {} func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[208] + mi := &file_openshell_proto_msgTypes[210] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14907,7 +15049,7 @@ func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{208} + return file_openshell_proto_rawDescGZIP(), []int{210} } func (x *RemoveWorkspaceMemberResponse) GetRemoved() bool { @@ -14930,7 +15072,7 @@ type ListWorkspaceMembersRequest struct { func (x *ListWorkspaceMembersRequest) Reset() { *x = ListWorkspaceMembersRequest{} - mi := &file_openshell_proto_msgTypes[209] + mi := &file_openshell_proto_msgTypes[211] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14942,7 +15084,7 @@ func (x *ListWorkspaceMembersRequest) String() string { func (*ListWorkspaceMembersRequest) ProtoMessage() {} func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[209] + mi := &file_openshell_proto_msgTypes[211] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14955,7 +15097,7 @@ func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersRequest.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{209} + return file_openshell_proto_rawDescGZIP(), []int{211} } func (x *ListWorkspaceMembersRequest) GetWorkspace() string { @@ -14989,7 +15131,7 @@ type ListWorkspaceMembersResponse struct { func (x *ListWorkspaceMembersResponse) Reset() { *x = ListWorkspaceMembersResponse{} - mi := &file_openshell_proto_msgTypes[210] + mi := &file_openshell_proto_msgTypes[212] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15001,7 +15143,7 @@ func (x *ListWorkspaceMembersResponse) String() string { func (*ListWorkspaceMembersResponse) ProtoMessage() {} func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[210] + mi := &file_openshell_proto_msgTypes[212] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15014,7 +15156,7 @@ func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersResponse.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{210} + return file_openshell_proto_rawDescGZIP(), []int{212} } func (x *ListWorkspaceMembersResponse) GetMembers() []*WorkspaceMember { @@ -15042,7 +15184,7 @@ type ExtensionServiceCredential struct { func (x *ExtensionServiceCredential) Reset() { *x = ExtensionServiceCredential{} - mi := &file_openshell_proto_msgTypes[211] + mi := &file_openshell_proto_msgTypes[213] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15054,7 +15196,7 @@ func (x *ExtensionServiceCredential) String() string { func (*ExtensionServiceCredential) ProtoMessage() {} func (x *ExtensionServiceCredential) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[211] + mi := &file_openshell_proto_msgTypes[213] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15067,7 +15209,7 @@ func (x *ExtensionServiceCredential) ProtoReflect() protoreflect.Message { // Deprecated: Use ExtensionServiceCredential.ProtoReflect.Descriptor instead. func (*ExtensionServiceCredential) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{211} + return file_openshell_proto_rawDescGZIP(), []int{213} } func (x *ExtensionServiceCredential) GetServiceName() string { @@ -15278,7 +15420,18 @@ const file_openshell_proto_rawDesc = "" + "\x1cListSandboxTemplatesResponse\x12C\n" + "\ttemplates\x18\x01 \x03(\v2%.openshell.v1.SandboxWorkloadTemplateR\ttemplates\"9\n" + "\x1dDeleteSandboxTemplateResponse\x12\x18\n" + - "\adeleted\x18\x01 \x01(\bR\adeleted\"E\n" + + "\adeleted\x18\x01 \x01(\bR\adeleted\"x\n" + + "\x1cBeginRootfsTarStagingRequest\x12\x1c\n" + + "\tworkspace\x18\x01 \x01(\tR\tworkspace\x12\x1b\n" + + "\tfile_name\x18\x02 \x01(\tR\bfileName\x12\x1d\n" + + "\n" + + "size_bytes\x18\x03 \x01(\x04R\tsizeBytes\"\xa6\x01\n" + + "\x1dBeginRootfsTarStagingResponse\x12#\n" + + "\rstaging_token\x18\x01 \x01(\tR\fstagingToken\x12\x1f\n" + + "\vupload_path\x18\x02 \x01(\tR\n" + + "uploadPath\x12\x1b\n" + + "\tmax_bytes\x18\x03 \x01(\x04R\bmaxBytes\x12\"\n" + + "\rexpires_at_ms\x18\x04 \x01(\x03R\vexpiresAtMs\"E\n" + "\x11GetSandboxRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" + "\tworkspace\x18\x02 \x01(\tR\tworkspace\"\xb0\x01\n" + @@ -16289,7 +16442,7 @@ const file_openshell_proto_rawDesc = "" + "1PROVIDER_CREDENTIAL_REFRESH_RECOVERY_ACTION_RETRY\x10\x01\x12;\n" + "7PROVIDER_CREDENTIAL_REFRESH_RECOVERY_ACTION_REAUTHORIZE\x10\x02\x12A\n" + "=PROVIDER_CREDENTIAL_REFRESH_RECOVERY_ACTION_FIX_CONFIGURATION\x10\x03\x12;\n" + - "7PROVIDER_CREDENTIAL_REFRESH_RECOVERY_ACTION_INVESTIGATE\x10\x042\xf7K\n" + + "7PROVIDER_CREDENTIAL_REFRESH_RECOVERY_ACTION_INVESTIGATE\x10\x042\x8dM\n" + "\tOpenShell\x12Z\n" + "\x06Health\x12\x1b.openshell.v1.HealthRequest\x1a\x1c.openshell.v1.HealthResponse\"\x15\x82\xb5\x18\x11\n" + "\x0funauthenticated\x12i\n" + @@ -16298,6 +16451,8 @@ const file_openshell_proto_rawDesc = "" + "\x0eGetGatewayInfo\x12#.openshell.v1.GetGatewayInfoRequest\x1a$.openshell.v1.GetGatewayInfoResponse\")\x82\xb5\x18%\n" + "\x06bearer\x1a\x0eplatform_admin\"\vconfig:read\x12u\n" + "\rCreateSandbox\x12\".openshell.v1.CreateSandboxRequest\x1a\x1d.openshell.v1.SandboxResponse\"!\x82\xb5\x18\x1d\n" + + "\x06bearer\x12\x04user\"\rsandbox:write\x12\x93\x01\n" + + "\x15BeginRootfsTarStaging\x12*.openshell.v1.BeginRootfsTarStagingRequest\x1a+.openshell.v1.BeginRootfsTarStagingResponse\"!\x82\xb5\x18\x1d\n" + "\x06bearer\x12\x04user\"\rsandbox:write\x12n\n" + "\n" + "GetSandbox\x12\x1f.openshell.v1.GetSandboxRequest\x1a\x1d.openshell.v1.SandboxResponse\" \x82\xb5\x18\x1c\n" + @@ -16454,7 +16609,7 @@ func file_openshell_proto_rawDescGZIP() []byte { } var file_openshell_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 238) +var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 240) var file_openshell_proto_goTypes = []any{ (SandboxPhase)(0), // 0: openshell.v1.SandboxPhase (ProviderCredentialTokenGrantType)(0), // 1: openshell.v1.ProviderCredentialTokenGrantType @@ -16503,225 +16658,227 @@ var file_openshell_proto_goTypes = []any{ (*SandboxTemplateResponse)(nil), // 44: openshell.v1.SandboxTemplateResponse (*ListSandboxTemplatesResponse)(nil), // 45: openshell.v1.ListSandboxTemplatesResponse (*DeleteSandboxTemplateResponse)(nil), // 46: openshell.v1.DeleteSandboxTemplateResponse - (*GetSandboxRequest)(nil), // 47: openshell.v1.GetSandboxRequest - (*ListSandboxesRequest)(nil), // 48: openshell.v1.ListSandboxesRequest - (*ListSandboxProvidersRequest)(nil), // 49: openshell.v1.ListSandboxProvidersRequest - (*AttachSandboxProviderRequest)(nil), // 50: openshell.v1.AttachSandboxProviderRequest - (*DetachSandboxProviderRequest)(nil), // 51: openshell.v1.DetachSandboxProviderRequest - (*DeleteSandboxRequest)(nil), // 52: openshell.v1.DeleteSandboxRequest - (*StopSandboxRequest)(nil), // 53: openshell.v1.StopSandboxRequest - (*StartSandboxRequest)(nil), // 54: openshell.v1.StartSandboxRequest - (*SandboxResponse)(nil), // 55: openshell.v1.SandboxResponse - (*ListSandboxesResponse)(nil), // 56: openshell.v1.ListSandboxesResponse - (*ListSandboxProvidersResponse)(nil), // 57: openshell.v1.ListSandboxProvidersResponse - (*AttachSandboxProviderResponse)(nil), // 58: openshell.v1.AttachSandboxProviderResponse - (*DetachSandboxProviderResponse)(nil), // 59: openshell.v1.DetachSandboxProviderResponse - (*DeleteSandboxResponse)(nil), // 60: openshell.v1.DeleteSandboxResponse - (*CreateSshSessionRequest)(nil), // 61: openshell.v1.CreateSshSessionRequest - (*CreateSshSessionResponse)(nil), // 62: openshell.v1.CreateSshSessionResponse - (*ExposeServiceRequest)(nil), // 63: openshell.v1.ExposeServiceRequest - (*GetServiceRequest)(nil), // 64: openshell.v1.GetServiceRequest - (*ListServicesRequest)(nil), // 65: openshell.v1.ListServicesRequest - (*ListServicesResponse)(nil), // 66: openshell.v1.ListServicesResponse - (*DeleteServiceRequest)(nil), // 67: openshell.v1.DeleteServiceRequest - (*DeleteServiceResponse)(nil), // 68: openshell.v1.DeleteServiceResponse - (*ServiceEndpoint)(nil), // 69: openshell.v1.ServiceEndpoint - (*ServiceEndpointResponse)(nil), // 70: openshell.v1.ServiceEndpointResponse - (*RevokeSshSessionRequest)(nil), // 71: openshell.v1.RevokeSshSessionRequest - (*RevokeSshSessionResponse)(nil), // 72: openshell.v1.RevokeSshSessionResponse - (*ExecSandboxRequest)(nil), // 73: openshell.v1.ExecSandboxRequest - (*ExecSandboxStdout)(nil), // 74: openshell.v1.ExecSandboxStdout - (*ExecSandboxStderr)(nil), // 75: openshell.v1.ExecSandboxStderr - (*ExecSandboxExit)(nil), // 76: openshell.v1.ExecSandboxExit - (*ExecSandboxEvent)(nil), // 77: openshell.v1.ExecSandboxEvent - (*TcpForwardInit)(nil), // 78: openshell.v1.TcpForwardInit - (*TcpForwardFrame)(nil), // 79: openshell.v1.TcpForwardFrame - (*ExecSandboxInput)(nil), // 80: openshell.v1.ExecSandboxInput - (*ExecSandboxWindowResize)(nil), // 81: openshell.v1.ExecSandboxWindowResize - (*SshSession)(nil), // 82: openshell.v1.SshSession - (*WatchSandboxRequest)(nil), // 83: openshell.v1.WatchSandboxRequest - (*SandboxStreamEvent)(nil), // 84: openshell.v1.SandboxStreamEvent - (*SandboxLogLine)(nil), // 85: openshell.v1.SandboxLogLine - (*SandboxStreamWarning)(nil), // 86: openshell.v1.SandboxStreamWarning - (*CreateProviderRequest)(nil), // 87: openshell.v1.CreateProviderRequest - (*GetProviderRequest)(nil), // 88: openshell.v1.GetProviderRequest - (*ListProvidersRequest)(nil), // 89: openshell.v1.ListProvidersRequest - (*UpdateProviderRequest)(nil), // 90: openshell.v1.UpdateProviderRequest - (*DeleteProviderRequest)(nil), // 91: openshell.v1.DeleteProviderRequest - (*ProviderResponse)(nil), // 92: openshell.v1.ProviderResponse - (*ListProvidersResponse)(nil), // 93: openshell.v1.ListProvidersResponse - (*ListProviderProfilesRequest)(nil), // 94: openshell.v1.ListProviderProfilesRequest - (*GetProviderProfileRequest)(nil), // 95: openshell.v1.GetProviderProfileRequest - (*ProviderProfileImportItem)(nil), // 96: openshell.v1.ProviderProfileImportItem - (*ProviderProfileDiagnostic)(nil), // 97: openshell.v1.ProviderProfileDiagnostic - (*ProviderCredentialTokenGrantAudienceOverride)(nil), // 98: openshell.v1.ProviderCredentialTokenGrantAudienceOverride - (*ProviderCredentialTokenGrantSubjectToken)(nil), // 99: openshell.v1.ProviderCredentialTokenGrantSubjectToken - (*ProviderCredentialTokenGrant)(nil), // 100: openshell.v1.ProviderCredentialTokenGrant - (*ProviderProfileCredential)(nil), // 101: openshell.v1.ProviderProfileCredential - (*ProviderCredentialRefreshMaterial)(nil), // 102: openshell.v1.ProviderCredentialRefreshMaterial - (*ProviderCredentialRefreshOutput)(nil), // 103: openshell.v1.ProviderCredentialRefreshOutput - (*ProviderCredentialRefresh)(nil), // 104: openshell.v1.ProviderCredentialRefresh - (*ProviderCredentialRefreshStatus)(nil), // 105: openshell.v1.ProviderCredentialRefreshStatus - (*ProviderProfileDiscovery)(nil), // 106: openshell.v1.ProviderProfileDiscovery - (*StoredProviderCredentialRefreshState)(nil), // 107: openshell.v1.StoredProviderCredentialRefreshState - (*StoredRefreshMaterialDeletion)(nil), // 108: openshell.v1.StoredRefreshMaterialDeletion - (*GetProviderRefreshStatusRequest)(nil), // 109: openshell.v1.GetProviderRefreshStatusRequest - (*GetProviderRefreshStatusResponse)(nil), // 110: openshell.v1.GetProviderRefreshStatusResponse - (*ConfigureProviderRefreshRequest)(nil), // 111: openshell.v1.ConfigureProviderRefreshRequest - (*ConfigureProviderRefreshResponse)(nil), // 112: openshell.v1.ConfigureProviderRefreshResponse - (*RotateProviderCredentialRequest)(nil), // 113: openshell.v1.RotateProviderCredentialRequest - (*RotateProviderCredentialResponse)(nil), // 114: openshell.v1.RotateProviderCredentialResponse - (*DeleteProviderRefreshRequest)(nil), // 115: openshell.v1.DeleteProviderRefreshRequest - (*DeleteProviderRefreshResponse)(nil), // 116: openshell.v1.DeleteProviderRefreshResponse - (*ProviderProfile)(nil), // 117: openshell.v1.ProviderProfile - (*StoredProviderProfile)(nil), // 118: openshell.v1.StoredProviderProfile - (*ProviderProfileResponse)(nil), // 119: openshell.v1.ProviderProfileResponse - (*ListProviderProfilesResponse)(nil), // 120: openshell.v1.ListProviderProfilesResponse - (*ImportProviderProfilesRequest)(nil), // 121: openshell.v1.ImportProviderProfilesRequest - (*ImportProviderProfilesResponse)(nil), // 122: openshell.v1.ImportProviderProfilesResponse - (*UpdateProviderProfilesRequest)(nil), // 123: openshell.v1.UpdateProviderProfilesRequest - (*UpdateProviderProfilesResponse)(nil), // 124: openshell.v1.UpdateProviderProfilesResponse - (*LintProviderProfilesRequest)(nil), // 125: openshell.v1.LintProviderProfilesRequest - (*LintProviderProfilesResponse)(nil), // 126: openshell.v1.LintProviderProfilesResponse - (*DeleteProviderResponse)(nil), // 127: openshell.v1.DeleteProviderResponse - (*DeleteProviderProfileRequest)(nil), // 128: openshell.v1.DeleteProviderProfileRequest - (*DeleteProviderProfileResponse)(nil), // 129: openshell.v1.DeleteProviderProfileResponse - (*GetSandboxProviderEnvironmentRequest)(nil), // 130: openshell.v1.GetSandboxProviderEnvironmentRequest - (*StaticCredentialEndpointBinding)(nil), // 131: openshell.v1.StaticCredentialEndpointBinding - (*StaticCredentialBinding)(nil), // 132: openshell.v1.StaticCredentialBinding - (*GetSandboxProviderEnvironmentResponse)(nil), // 133: openshell.v1.GetSandboxProviderEnvironmentResponse - (*ExchangeProviderSubjectTokenRequest)(nil), // 134: openshell.v1.ExchangeProviderSubjectTokenRequest - (*ExchangeProviderSubjectTokenResponse)(nil), // 135: openshell.v1.ExchangeProviderSubjectTokenResponse - (*UpdateConfigRequest)(nil), // 136: openshell.v1.UpdateConfigRequest - (*PolicyMergeOperation)(nil), // 137: openshell.v1.PolicyMergeOperation - (*AddNetworkRule)(nil), // 138: openshell.v1.AddNetworkRule - (*RemoveNetworkEndpoint)(nil), // 139: openshell.v1.RemoveNetworkEndpoint - (*RemoveNetworkRule)(nil), // 140: openshell.v1.RemoveNetworkRule - (*AddDenyRules)(nil), // 141: openshell.v1.AddDenyRules - (*AddAllowRules)(nil), // 142: openshell.v1.AddAllowRules - (*RemoveNetworkBinary)(nil), // 143: openshell.v1.RemoveNetworkBinary - (*UpdateConfigResponse)(nil), // 144: openshell.v1.UpdateConfigResponse - (*GetSandboxPolicyStatusRequest)(nil), // 145: openshell.v1.GetSandboxPolicyStatusRequest - (*GetSandboxPolicyStatusResponse)(nil), // 146: openshell.v1.GetSandboxPolicyStatusResponse - (*ListSandboxPoliciesRequest)(nil), // 147: openshell.v1.ListSandboxPoliciesRequest - (*ListSandboxPoliciesResponse)(nil), // 148: openshell.v1.ListSandboxPoliciesResponse - (*ReportPolicyStatusRequest)(nil), // 149: openshell.v1.ReportPolicyStatusRequest - (*ReportPolicyStatusResponse)(nil), // 150: openshell.v1.ReportPolicyStatusResponse - (*SandboxPolicyRevision)(nil), // 151: openshell.v1.SandboxPolicyRevision - (*GetSandboxLogsRequest)(nil), // 152: openshell.v1.GetSandboxLogsRequest - (*PushSandboxLogsRequest)(nil), // 153: openshell.v1.PushSandboxLogsRequest - (*PushSandboxLogsResponse)(nil), // 154: openshell.v1.PushSandboxLogsResponse - (*GetSandboxLogsResponse)(nil), // 155: openshell.v1.GetSandboxLogsResponse - (*SupervisorMessage)(nil), // 156: openshell.v1.SupervisorMessage - (*GatewayMessage)(nil), // 157: openshell.v1.GatewayMessage - (*SupervisorHello)(nil), // 158: openshell.v1.SupervisorHello - (*SessionAccepted)(nil), // 159: openshell.v1.SessionAccepted - (*SessionRejected)(nil), // 160: openshell.v1.SessionRejected - (*SupervisorHeartbeat)(nil), // 161: openshell.v1.SupervisorHeartbeat - (*GatewayHeartbeat)(nil), // 162: openshell.v1.GatewayHeartbeat - (*ReportMainProcessExitRequest)(nil), // 163: openshell.v1.ReportMainProcessExitRequest - (*ReportMainProcessExitResponse)(nil), // 164: openshell.v1.ReportMainProcessExitResponse - (*FinalizeMainProcessExitRequest)(nil), // 165: openshell.v1.FinalizeMainProcessExitRequest - (*FinalizeMainProcessExitResponse)(nil), // 166: openshell.v1.FinalizeMainProcessExitResponse - (*RelayOpen)(nil), // 167: openshell.v1.RelayOpen - (*SshRelayTarget)(nil), // 168: openshell.v1.SshRelayTarget - (*TcpRelayTarget)(nil), // 169: openshell.v1.TcpRelayTarget - (*RelayInit)(nil), // 170: openshell.v1.RelayInit - (*RelayFrame)(nil), // 171: openshell.v1.RelayFrame - (*RelayOpenResult)(nil), // 172: openshell.v1.RelayOpenResult - (*RelayClose)(nil), // 173: openshell.v1.RelayClose - (*L7RequestSample)(nil), // 174: openshell.v1.L7RequestSample - (*DenialSummary)(nil), // 175: openshell.v1.DenialSummary - (*DenialGroupCount)(nil), // 176: openshell.v1.DenialGroupCount - (*NetworkActivitySummary)(nil), // 177: openshell.v1.NetworkActivitySummary - (*PolicyChunk)(nil), // 178: openshell.v1.PolicyChunk - (*DraftPolicyUpdate)(nil), // 179: openshell.v1.DraftPolicyUpdate - (*SubmitPolicyAnalysisRequest)(nil), // 180: openshell.v1.SubmitPolicyAnalysisRequest - (*SubmitPolicyAnalysisResponse)(nil), // 181: openshell.v1.SubmitPolicyAnalysisResponse - (*GetDraftPolicyRequest)(nil), // 182: openshell.v1.GetDraftPolicyRequest - (*GetDraftPolicyResponse)(nil), // 183: openshell.v1.GetDraftPolicyResponse - (*ApproveDraftChunkRequest)(nil), // 184: openshell.v1.ApproveDraftChunkRequest - (*ApproveDraftChunkResponse)(nil), // 185: openshell.v1.ApproveDraftChunkResponse - (*RejectDraftChunkRequest)(nil), // 186: openshell.v1.RejectDraftChunkRequest - (*RejectDraftChunkResponse)(nil), // 187: openshell.v1.RejectDraftChunkResponse - (*DraftChunkApproval)(nil), // 188: openshell.v1.DraftChunkApproval - (*ApproveAllDraftChunksRequest)(nil), // 189: openshell.v1.ApproveAllDraftChunksRequest - (*ApproveAllDraftChunksResponse)(nil), // 190: openshell.v1.ApproveAllDraftChunksResponse - (*EditDraftChunkRequest)(nil), // 191: openshell.v1.EditDraftChunkRequest - (*EditDraftChunkResponse)(nil), // 192: openshell.v1.EditDraftChunkResponse - (*UndoDraftChunkRequest)(nil), // 193: openshell.v1.UndoDraftChunkRequest - (*UndoDraftChunkResponse)(nil), // 194: openshell.v1.UndoDraftChunkResponse - (*ClearDraftChunksRequest)(nil), // 195: openshell.v1.ClearDraftChunksRequest - (*ClearDraftChunksResponse)(nil), // 196: openshell.v1.ClearDraftChunksResponse - (*GetDraftHistoryRequest)(nil), // 197: openshell.v1.GetDraftHistoryRequest - (*DraftHistoryEntry)(nil), // 198: openshell.v1.DraftHistoryEntry - (*GetDraftHistoryResponse)(nil), // 199: openshell.v1.GetDraftHistoryResponse - (*PolicyRevisionPayload)(nil), // 200: openshell.v1.PolicyRevisionPayload - (*DraftChunkPayload)(nil), // 201: openshell.v1.DraftChunkPayload - (*StoredPolicyRevision)(nil), // 202: openshell.v1.StoredPolicyRevision - (*StoredDraftChunk)(nil), // 203: openshell.v1.StoredDraftChunk - (*CreateWorkspaceRequest)(nil), // 204: openshell.v1.CreateWorkspaceRequest - (*CreateWorkspaceResponse)(nil), // 205: openshell.v1.CreateWorkspaceResponse - (*GetWorkspaceRequest)(nil), // 206: openshell.v1.GetWorkspaceRequest - (*GetWorkspaceResponse)(nil), // 207: openshell.v1.GetWorkspaceResponse - (*ListWorkspacesRequest)(nil), // 208: openshell.v1.ListWorkspacesRequest - (*ListWorkspacesResponse)(nil), // 209: openshell.v1.ListWorkspacesResponse - (*DeleteWorkspaceRequest)(nil), // 210: openshell.v1.DeleteWorkspaceRequest - (*DeleteWorkspaceResponse)(nil), // 211: openshell.v1.DeleteWorkspaceResponse - (*WorkspaceMember)(nil), // 212: openshell.v1.WorkspaceMember - (*AddWorkspaceMemberRequest)(nil), // 213: openshell.v1.AddWorkspaceMemberRequest - (*AddWorkspaceMemberResponse)(nil), // 214: openshell.v1.AddWorkspaceMemberResponse - (*RemoveWorkspaceMemberRequest)(nil), // 215: openshell.v1.RemoveWorkspaceMemberRequest - (*RemoveWorkspaceMemberResponse)(nil), // 216: openshell.v1.RemoveWorkspaceMemberResponse - (*ListWorkspaceMembersRequest)(nil), // 217: openshell.v1.ListWorkspaceMembersRequest - (*ListWorkspaceMembersResponse)(nil), // 218: openshell.v1.ListWorkspaceMembersResponse - (*ExtensionServiceCredential)(nil), // 219: openshell.v1.ExtensionServiceCredential - nil, // 220: openshell.v1.SandboxSpec.EnvironmentEntry - nil, // 221: openshell.v1.SandboxTemplate.LabelsEntry - nil, // 222: openshell.v1.SandboxTemplate.AnnotationsEntry - nil, // 223: openshell.v1.SandboxTemplate.EnvironmentEntry - nil, // 224: openshell.v1.SandboxWorkloadConfig.EnvironmentEntry - nil, // 225: openshell.v1.PlatformEvent.MetadataEntry - nil, // 226: openshell.v1.CreateSandboxRequest.LabelsEntry - nil, // 227: openshell.v1.CreateSandboxRequest.AnnotationsEntry - nil, // 228: openshell.v1.ExecSandboxRequest.EnvironmentEntry - nil, // 229: openshell.v1.SandboxLogLine.FieldsEntry - nil, // 230: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry - nil, // 231: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry - nil, // 232: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - nil, // 233: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry - nil, // 234: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - nil, // 235: openshell.v1.ProviderProfile.AnnotationsEntry - nil, // 236: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - nil, // 237: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - nil, // 238: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - nil, // 239: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - nil, // 240: openshell.v1.UpdateConfigRequest.AnnotationsEntry - nil, // 241: openshell.v1.UpdateConfigResponse.AnnotationsEntry - nil, // 242: openshell.v1.SandboxPolicyRevision.ProvenanceEntry - nil, // 243: openshell.v1.PolicyRevisionPayload.ProvenanceEntry - nil, // 244: openshell.v1.StoredPolicyRevision.ProvenanceEntry - nil, // 245: openshell.v1.CreateWorkspaceRequest.LabelsEntry - (*datamodelv1.ObjectMeta)(nil), // 246: openshell.datamodel.v1.ObjectMeta - (*sandboxv1.SandboxPolicy)(nil), // 247: openshell.sandbox.v1.SandboxPolicy - (*structpb.Struct)(nil), // 248: google.protobuf.Struct - (*durationpb.Duration)(nil), // 249: google.protobuf.Duration - (*datamodelv1.Provider)(nil), // 250: openshell.datamodel.v1.Provider - (*datamodelv1.CredentialHandle)(nil), // 251: openshell.datamodel.v1.CredentialHandle - (*sandboxv1.NetworkEndpoint)(nil), // 252: openshell.sandbox.v1.NetworkEndpoint - (*sandboxv1.NetworkBinary)(nil), // 253: openshell.sandbox.v1.NetworkBinary - (*sandboxv1.SettingValue)(nil), // 254: openshell.sandbox.v1.SettingValue - (*sandboxv1.NetworkPolicyRule)(nil), // 255: openshell.sandbox.v1.NetworkPolicyRule - (*sandboxv1.L7DenyRule)(nil), // 256: openshell.sandbox.v1.L7DenyRule - (*sandboxv1.L7Rule)(nil), // 257: openshell.sandbox.v1.L7Rule - (*datamodelv1.Workspace)(nil), // 258: openshell.datamodel.v1.Workspace - (*sandboxv1.GetSandboxConfigRequest)(nil), // 259: openshell.sandbox.v1.GetSandboxConfigRequest - (*sandboxv1.GetGatewayConfigRequest)(nil), // 260: openshell.sandbox.v1.GetGatewayConfigRequest - (*sandboxv1.GetSandboxConfigResponse)(nil), // 261: openshell.sandbox.v1.GetSandboxConfigResponse - (*sandboxv1.GetGatewayConfigResponse)(nil), // 262: openshell.sandbox.v1.GetGatewayConfigResponse + (*BeginRootfsTarStagingRequest)(nil), // 47: openshell.v1.BeginRootfsTarStagingRequest + (*BeginRootfsTarStagingResponse)(nil), // 48: openshell.v1.BeginRootfsTarStagingResponse + (*GetSandboxRequest)(nil), // 49: openshell.v1.GetSandboxRequest + (*ListSandboxesRequest)(nil), // 50: openshell.v1.ListSandboxesRequest + (*ListSandboxProvidersRequest)(nil), // 51: openshell.v1.ListSandboxProvidersRequest + (*AttachSandboxProviderRequest)(nil), // 52: openshell.v1.AttachSandboxProviderRequest + (*DetachSandboxProviderRequest)(nil), // 53: openshell.v1.DetachSandboxProviderRequest + (*DeleteSandboxRequest)(nil), // 54: openshell.v1.DeleteSandboxRequest + (*StopSandboxRequest)(nil), // 55: openshell.v1.StopSandboxRequest + (*StartSandboxRequest)(nil), // 56: openshell.v1.StartSandboxRequest + (*SandboxResponse)(nil), // 57: openshell.v1.SandboxResponse + (*ListSandboxesResponse)(nil), // 58: openshell.v1.ListSandboxesResponse + (*ListSandboxProvidersResponse)(nil), // 59: openshell.v1.ListSandboxProvidersResponse + (*AttachSandboxProviderResponse)(nil), // 60: openshell.v1.AttachSandboxProviderResponse + (*DetachSandboxProviderResponse)(nil), // 61: openshell.v1.DetachSandboxProviderResponse + (*DeleteSandboxResponse)(nil), // 62: openshell.v1.DeleteSandboxResponse + (*CreateSshSessionRequest)(nil), // 63: openshell.v1.CreateSshSessionRequest + (*CreateSshSessionResponse)(nil), // 64: openshell.v1.CreateSshSessionResponse + (*ExposeServiceRequest)(nil), // 65: openshell.v1.ExposeServiceRequest + (*GetServiceRequest)(nil), // 66: openshell.v1.GetServiceRequest + (*ListServicesRequest)(nil), // 67: openshell.v1.ListServicesRequest + (*ListServicesResponse)(nil), // 68: openshell.v1.ListServicesResponse + (*DeleteServiceRequest)(nil), // 69: openshell.v1.DeleteServiceRequest + (*DeleteServiceResponse)(nil), // 70: openshell.v1.DeleteServiceResponse + (*ServiceEndpoint)(nil), // 71: openshell.v1.ServiceEndpoint + (*ServiceEndpointResponse)(nil), // 72: openshell.v1.ServiceEndpointResponse + (*RevokeSshSessionRequest)(nil), // 73: openshell.v1.RevokeSshSessionRequest + (*RevokeSshSessionResponse)(nil), // 74: openshell.v1.RevokeSshSessionResponse + (*ExecSandboxRequest)(nil), // 75: openshell.v1.ExecSandboxRequest + (*ExecSandboxStdout)(nil), // 76: openshell.v1.ExecSandboxStdout + (*ExecSandboxStderr)(nil), // 77: openshell.v1.ExecSandboxStderr + (*ExecSandboxExit)(nil), // 78: openshell.v1.ExecSandboxExit + (*ExecSandboxEvent)(nil), // 79: openshell.v1.ExecSandboxEvent + (*TcpForwardInit)(nil), // 80: openshell.v1.TcpForwardInit + (*TcpForwardFrame)(nil), // 81: openshell.v1.TcpForwardFrame + (*ExecSandboxInput)(nil), // 82: openshell.v1.ExecSandboxInput + (*ExecSandboxWindowResize)(nil), // 83: openshell.v1.ExecSandboxWindowResize + (*SshSession)(nil), // 84: openshell.v1.SshSession + (*WatchSandboxRequest)(nil), // 85: openshell.v1.WatchSandboxRequest + (*SandboxStreamEvent)(nil), // 86: openshell.v1.SandboxStreamEvent + (*SandboxLogLine)(nil), // 87: openshell.v1.SandboxLogLine + (*SandboxStreamWarning)(nil), // 88: openshell.v1.SandboxStreamWarning + (*CreateProviderRequest)(nil), // 89: openshell.v1.CreateProviderRequest + (*GetProviderRequest)(nil), // 90: openshell.v1.GetProviderRequest + (*ListProvidersRequest)(nil), // 91: openshell.v1.ListProvidersRequest + (*UpdateProviderRequest)(nil), // 92: openshell.v1.UpdateProviderRequest + (*DeleteProviderRequest)(nil), // 93: openshell.v1.DeleteProviderRequest + (*ProviderResponse)(nil), // 94: openshell.v1.ProviderResponse + (*ListProvidersResponse)(nil), // 95: openshell.v1.ListProvidersResponse + (*ListProviderProfilesRequest)(nil), // 96: openshell.v1.ListProviderProfilesRequest + (*GetProviderProfileRequest)(nil), // 97: openshell.v1.GetProviderProfileRequest + (*ProviderProfileImportItem)(nil), // 98: openshell.v1.ProviderProfileImportItem + (*ProviderProfileDiagnostic)(nil), // 99: openshell.v1.ProviderProfileDiagnostic + (*ProviderCredentialTokenGrantAudienceOverride)(nil), // 100: openshell.v1.ProviderCredentialTokenGrantAudienceOverride + (*ProviderCredentialTokenGrantSubjectToken)(nil), // 101: openshell.v1.ProviderCredentialTokenGrantSubjectToken + (*ProviderCredentialTokenGrant)(nil), // 102: openshell.v1.ProviderCredentialTokenGrant + (*ProviderProfileCredential)(nil), // 103: openshell.v1.ProviderProfileCredential + (*ProviderCredentialRefreshMaterial)(nil), // 104: openshell.v1.ProviderCredentialRefreshMaterial + (*ProviderCredentialRefreshOutput)(nil), // 105: openshell.v1.ProviderCredentialRefreshOutput + (*ProviderCredentialRefresh)(nil), // 106: openshell.v1.ProviderCredentialRefresh + (*ProviderCredentialRefreshStatus)(nil), // 107: openshell.v1.ProviderCredentialRefreshStatus + (*ProviderProfileDiscovery)(nil), // 108: openshell.v1.ProviderProfileDiscovery + (*StoredProviderCredentialRefreshState)(nil), // 109: openshell.v1.StoredProviderCredentialRefreshState + (*StoredRefreshMaterialDeletion)(nil), // 110: openshell.v1.StoredRefreshMaterialDeletion + (*GetProviderRefreshStatusRequest)(nil), // 111: openshell.v1.GetProviderRefreshStatusRequest + (*GetProviderRefreshStatusResponse)(nil), // 112: openshell.v1.GetProviderRefreshStatusResponse + (*ConfigureProviderRefreshRequest)(nil), // 113: openshell.v1.ConfigureProviderRefreshRequest + (*ConfigureProviderRefreshResponse)(nil), // 114: openshell.v1.ConfigureProviderRefreshResponse + (*RotateProviderCredentialRequest)(nil), // 115: openshell.v1.RotateProviderCredentialRequest + (*RotateProviderCredentialResponse)(nil), // 116: openshell.v1.RotateProviderCredentialResponse + (*DeleteProviderRefreshRequest)(nil), // 117: openshell.v1.DeleteProviderRefreshRequest + (*DeleteProviderRefreshResponse)(nil), // 118: openshell.v1.DeleteProviderRefreshResponse + (*ProviderProfile)(nil), // 119: openshell.v1.ProviderProfile + (*StoredProviderProfile)(nil), // 120: openshell.v1.StoredProviderProfile + (*ProviderProfileResponse)(nil), // 121: openshell.v1.ProviderProfileResponse + (*ListProviderProfilesResponse)(nil), // 122: openshell.v1.ListProviderProfilesResponse + (*ImportProviderProfilesRequest)(nil), // 123: openshell.v1.ImportProviderProfilesRequest + (*ImportProviderProfilesResponse)(nil), // 124: openshell.v1.ImportProviderProfilesResponse + (*UpdateProviderProfilesRequest)(nil), // 125: openshell.v1.UpdateProviderProfilesRequest + (*UpdateProviderProfilesResponse)(nil), // 126: openshell.v1.UpdateProviderProfilesResponse + (*LintProviderProfilesRequest)(nil), // 127: openshell.v1.LintProviderProfilesRequest + (*LintProviderProfilesResponse)(nil), // 128: openshell.v1.LintProviderProfilesResponse + (*DeleteProviderResponse)(nil), // 129: openshell.v1.DeleteProviderResponse + (*DeleteProviderProfileRequest)(nil), // 130: openshell.v1.DeleteProviderProfileRequest + (*DeleteProviderProfileResponse)(nil), // 131: openshell.v1.DeleteProviderProfileResponse + (*GetSandboxProviderEnvironmentRequest)(nil), // 132: openshell.v1.GetSandboxProviderEnvironmentRequest + (*StaticCredentialEndpointBinding)(nil), // 133: openshell.v1.StaticCredentialEndpointBinding + (*StaticCredentialBinding)(nil), // 134: openshell.v1.StaticCredentialBinding + (*GetSandboxProviderEnvironmentResponse)(nil), // 135: openshell.v1.GetSandboxProviderEnvironmentResponse + (*ExchangeProviderSubjectTokenRequest)(nil), // 136: openshell.v1.ExchangeProviderSubjectTokenRequest + (*ExchangeProviderSubjectTokenResponse)(nil), // 137: openshell.v1.ExchangeProviderSubjectTokenResponse + (*UpdateConfigRequest)(nil), // 138: openshell.v1.UpdateConfigRequest + (*PolicyMergeOperation)(nil), // 139: openshell.v1.PolicyMergeOperation + (*AddNetworkRule)(nil), // 140: openshell.v1.AddNetworkRule + (*RemoveNetworkEndpoint)(nil), // 141: openshell.v1.RemoveNetworkEndpoint + (*RemoveNetworkRule)(nil), // 142: openshell.v1.RemoveNetworkRule + (*AddDenyRules)(nil), // 143: openshell.v1.AddDenyRules + (*AddAllowRules)(nil), // 144: openshell.v1.AddAllowRules + (*RemoveNetworkBinary)(nil), // 145: openshell.v1.RemoveNetworkBinary + (*UpdateConfigResponse)(nil), // 146: openshell.v1.UpdateConfigResponse + (*GetSandboxPolicyStatusRequest)(nil), // 147: openshell.v1.GetSandboxPolicyStatusRequest + (*GetSandboxPolicyStatusResponse)(nil), // 148: openshell.v1.GetSandboxPolicyStatusResponse + (*ListSandboxPoliciesRequest)(nil), // 149: openshell.v1.ListSandboxPoliciesRequest + (*ListSandboxPoliciesResponse)(nil), // 150: openshell.v1.ListSandboxPoliciesResponse + (*ReportPolicyStatusRequest)(nil), // 151: openshell.v1.ReportPolicyStatusRequest + (*ReportPolicyStatusResponse)(nil), // 152: openshell.v1.ReportPolicyStatusResponse + (*SandboxPolicyRevision)(nil), // 153: openshell.v1.SandboxPolicyRevision + (*GetSandboxLogsRequest)(nil), // 154: openshell.v1.GetSandboxLogsRequest + (*PushSandboxLogsRequest)(nil), // 155: openshell.v1.PushSandboxLogsRequest + (*PushSandboxLogsResponse)(nil), // 156: openshell.v1.PushSandboxLogsResponse + (*GetSandboxLogsResponse)(nil), // 157: openshell.v1.GetSandboxLogsResponse + (*SupervisorMessage)(nil), // 158: openshell.v1.SupervisorMessage + (*GatewayMessage)(nil), // 159: openshell.v1.GatewayMessage + (*SupervisorHello)(nil), // 160: openshell.v1.SupervisorHello + (*SessionAccepted)(nil), // 161: openshell.v1.SessionAccepted + (*SessionRejected)(nil), // 162: openshell.v1.SessionRejected + (*SupervisorHeartbeat)(nil), // 163: openshell.v1.SupervisorHeartbeat + (*GatewayHeartbeat)(nil), // 164: openshell.v1.GatewayHeartbeat + (*ReportMainProcessExitRequest)(nil), // 165: openshell.v1.ReportMainProcessExitRequest + (*ReportMainProcessExitResponse)(nil), // 166: openshell.v1.ReportMainProcessExitResponse + (*FinalizeMainProcessExitRequest)(nil), // 167: openshell.v1.FinalizeMainProcessExitRequest + (*FinalizeMainProcessExitResponse)(nil), // 168: openshell.v1.FinalizeMainProcessExitResponse + (*RelayOpen)(nil), // 169: openshell.v1.RelayOpen + (*SshRelayTarget)(nil), // 170: openshell.v1.SshRelayTarget + (*TcpRelayTarget)(nil), // 171: openshell.v1.TcpRelayTarget + (*RelayInit)(nil), // 172: openshell.v1.RelayInit + (*RelayFrame)(nil), // 173: openshell.v1.RelayFrame + (*RelayOpenResult)(nil), // 174: openshell.v1.RelayOpenResult + (*RelayClose)(nil), // 175: openshell.v1.RelayClose + (*L7RequestSample)(nil), // 176: openshell.v1.L7RequestSample + (*DenialSummary)(nil), // 177: openshell.v1.DenialSummary + (*DenialGroupCount)(nil), // 178: openshell.v1.DenialGroupCount + (*NetworkActivitySummary)(nil), // 179: openshell.v1.NetworkActivitySummary + (*PolicyChunk)(nil), // 180: openshell.v1.PolicyChunk + (*DraftPolicyUpdate)(nil), // 181: openshell.v1.DraftPolicyUpdate + (*SubmitPolicyAnalysisRequest)(nil), // 182: openshell.v1.SubmitPolicyAnalysisRequest + (*SubmitPolicyAnalysisResponse)(nil), // 183: openshell.v1.SubmitPolicyAnalysisResponse + (*GetDraftPolicyRequest)(nil), // 184: openshell.v1.GetDraftPolicyRequest + (*GetDraftPolicyResponse)(nil), // 185: openshell.v1.GetDraftPolicyResponse + (*ApproveDraftChunkRequest)(nil), // 186: openshell.v1.ApproveDraftChunkRequest + (*ApproveDraftChunkResponse)(nil), // 187: openshell.v1.ApproveDraftChunkResponse + (*RejectDraftChunkRequest)(nil), // 188: openshell.v1.RejectDraftChunkRequest + (*RejectDraftChunkResponse)(nil), // 189: openshell.v1.RejectDraftChunkResponse + (*DraftChunkApproval)(nil), // 190: openshell.v1.DraftChunkApproval + (*ApproveAllDraftChunksRequest)(nil), // 191: openshell.v1.ApproveAllDraftChunksRequest + (*ApproveAllDraftChunksResponse)(nil), // 192: openshell.v1.ApproveAllDraftChunksResponse + (*EditDraftChunkRequest)(nil), // 193: openshell.v1.EditDraftChunkRequest + (*EditDraftChunkResponse)(nil), // 194: openshell.v1.EditDraftChunkResponse + (*UndoDraftChunkRequest)(nil), // 195: openshell.v1.UndoDraftChunkRequest + (*UndoDraftChunkResponse)(nil), // 196: openshell.v1.UndoDraftChunkResponse + (*ClearDraftChunksRequest)(nil), // 197: openshell.v1.ClearDraftChunksRequest + (*ClearDraftChunksResponse)(nil), // 198: openshell.v1.ClearDraftChunksResponse + (*GetDraftHistoryRequest)(nil), // 199: openshell.v1.GetDraftHistoryRequest + (*DraftHistoryEntry)(nil), // 200: openshell.v1.DraftHistoryEntry + (*GetDraftHistoryResponse)(nil), // 201: openshell.v1.GetDraftHistoryResponse + (*PolicyRevisionPayload)(nil), // 202: openshell.v1.PolicyRevisionPayload + (*DraftChunkPayload)(nil), // 203: openshell.v1.DraftChunkPayload + (*StoredPolicyRevision)(nil), // 204: openshell.v1.StoredPolicyRevision + (*StoredDraftChunk)(nil), // 205: openshell.v1.StoredDraftChunk + (*CreateWorkspaceRequest)(nil), // 206: openshell.v1.CreateWorkspaceRequest + (*CreateWorkspaceResponse)(nil), // 207: openshell.v1.CreateWorkspaceResponse + (*GetWorkspaceRequest)(nil), // 208: openshell.v1.GetWorkspaceRequest + (*GetWorkspaceResponse)(nil), // 209: openshell.v1.GetWorkspaceResponse + (*ListWorkspacesRequest)(nil), // 210: openshell.v1.ListWorkspacesRequest + (*ListWorkspacesResponse)(nil), // 211: openshell.v1.ListWorkspacesResponse + (*DeleteWorkspaceRequest)(nil), // 212: openshell.v1.DeleteWorkspaceRequest + (*DeleteWorkspaceResponse)(nil), // 213: openshell.v1.DeleteWorkspaceResponse + (*WorkspaceMember)(nil), // 214: openshell.v1.WorkspaceMember + (*AddWorkspaceMemberRequest)(nil), // 215: openshell.v1.AddWorkspaceMemberRequest + (*AddWorkspaceMemberResponse)(nil), // 216: openshell.v1.AddWorkspaceMemberResponse + (*RemoveWorkspaceMemberRequest)(nil), // 217: openshell.v1.RemoveWorkspaceMemberRequest + (*RemoveWorkspaceMemberResponse)(nil), // 218: openshell.v1.RemoveWorkspaceMemberResponse + (*ListWorkspaceMembersRequest)(nil), // 219: openshell.v1.ListWorkspaceMembersRequest + (*ListWorkspaceMembersResponse)(nil), // 220: openshell.v1.ListWorkspaceMembersResponse + (*ExtensionServiceCredential)(nil), // 221: openshell.v1.ExtensionServiceCredential + nil, // 222: openshell.v1.SandboxSpec.EnvironmentEntry + nil, // 223: openshell.v1.SandboxTemplate.LabelsEntry + nil, // 224: openshell.v1.SandboxTemplate.AnnotationsEntry + nil, // 225: openshell.v1.SandboxTemplate.EnvironmentEntry + nil, // 226: openshell.v1.SandboxWorkloadConfig.EnvironmentEntry + nil, // 227: openshell.v1.PlatformEvent.MetadataEntry + nil, // 228: openshell.v1.CreateSandboxRequest.LabelsEntry + nil, // 229: openshell.v1.CreateSandboxRequest.AnnotationsEntry + nil, // 230: openshell.v1.ExecSandboxRequest.EnvironmentEntry + nil, // 231: openshell.v1.SandboxLogLine.FieldsEntry + nil, // 232: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry + nil, // 233: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry + nil, // 234: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry + nil, // 235: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry + nil, // 236: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + nil, // 237: openshell.v1.ProviderProfile.AnnotationsEntry + nil, // 238: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + nil, // 239: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + nil, // 240: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + nil, // 241: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + nil, // 242: openshell.v1.UpdateConfigRequest.AnnotationsEntry + nil, // 243: openshell.v1.UpdateConfigResponse.AnnotationsEntry + nil, // 244: openshell.v1.SandboxPolicyRevision.ProvenanceEntry + nil, // 245: openshell.v1.PolicyRevisionPayload.ProvenanceEntry + nil, // 246: openshell.v1.StoredPolicyRevision.ProvenanceEntry + nil, // 247: openshell.v1.CreateWorkspaceRequest.LabelsEntry + (*datamodelv1.ObjectMeta)(nil), // 248: openshell.datamodel.v1.ObjectMeta + (*sandboxv1.SandboxPolicy)(nil), // 249: openshell.sandbox.v1.SandboxPolicy + (*structpb.Struct)(nil), // 250: google.protobuf.Struct + (*durationpb.Duration)(nil), // 251: google.protobuf.Duration + (*datamodelv1.Provider)(nil), // 252: openshell.datamodel.v1.Provider + (*datamodelv1.CredentialHandle)(nil), // 253: openshell.datamodel.v1.CredentialHandle + (*sandboxv1.NetworkEndpoint)(nil), // 254: openshell.sandbox.v1.NetworkEndpoint + (*sandboxv1.NetworkBinary)(nil), // 255: openshell.sandbox.v1.NetworkBinary + (*sandboxv1.SettingValue)(nil), // 256: openshell.sandbox.v1.SettingValue + (*sandboxv1.NetworkPolicyRule)(nil), // 257: openshell.sandbox.v1.NetworkPolicyRule + (*sandboxv1.L7DenyRule)(nil), // 258: openshell.sandbox.v1.L7DenyRule + (*sandboxv1.L7Rule)(nil), // 259: openshell.sandbox.v1.L7Rule + (*datamodelv1.Workspace)(nil), // 260: openshell.datamodel.v1.Workspace + (*sandboxv1.GetSandboxConfigRequest)(nil), // 261: openshell.sandbox.v1.GetSandboxConfigRequest + (*sandboxv1.GetGatewayConfigRequest)(nil), // 262: openshell.sandbox.v1.GetGatewayConfigRequest + (*sandboxv1.GetSandboxConfigResponse)(nil), // 263: openshell.sandbox.v1.GetSandboxConfigResponse + (*sandboxv1.GetGatewayConfigResponse)(nil), // 264: openshell.sandbox.v1.GetGatewayConfigResponse } var file_openshell_proto_depIdxs = []int32{ - 219, // 0: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential + 221, // 0: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential 5, // 1: openshell.v1.HealthResponse.status:type_name -> openshell.v1.ServiceStatus 5, // 2: openshell.v1.GetGatewayInfoResponse.status:type_name -> openshell.v1.ServiceStatus 18, // 3: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo @@ -16730,329 +16887,331 @@ var file_openshell_proto_depIdxs = []int32{ 21, // 6: openshell.v1.ResourceCapabilities.cpu:type_name -> openshell.v1.CpuResourceCapabilities 22, // 7: openshell.v1.ResourceCapabilities.memory:type_name -> openshell.v1.MemoryResourceCapabilities 23, // 8: openshell.v1.ResourceCapabilities.gpu:type_name -> openshell.v1.GpuResourceCapabilities - 246, // 9: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 248, // 9: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 25, // 10: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec 36, // 11: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus 35, // 12: openshell.v1.Sandbox.created_from_workload_template:type_name -> openshell.v1.SandboxWorkloadTemplateProvenance - 220, // 13: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry + 222, // 13: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry 28, // 14: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate - 247, // 15: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 249, // 15: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy 26, // 16: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements 27, // 17: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements - 221, // 18: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry - 222, // 19: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry - 223, // 20: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry - 248, // 21: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct - 248, // 22: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct - 246, // 23: openshell.v1.SandboxWorkloadTemplate.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 223, // 18: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry + 224, // 19: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry + 225, // 20: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry + 250, // 21: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct + 250, // 22: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct + 248, // 23: openshell.v1.SandboxWorkloadTemplate.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 30, // 24: openshell.v1.SandboxWorkloadTemplate.spec:type_name -> openshell.v1.SandboxWorkloadTemplateSpec 31, // 25: openshell.v1.SandboxWorkloadTemplateSpec.workload:type_name -> openshell.v1.SandboxWorkloadConfig - 248, // 26: openshell.v1.SandboxWorkloadTemplateSpec.driver_config:type_name -> google.protobuf.Struct + 250, // 26: openshell.v1.SandboxWorkloadTemplateSpec.driver_config:type_name -> google.protobuf.Struct 33, // 27: openshell.v1.SandboxWorkloadTemplateSpec.desired_service_level:type_name -> openshell.v1.SandboxServiceLevel - 224, // 28: openshell.v1.SandboxWorkloadConfig.environment:type_name -> openshell.v1.SandboxWorkloadConfig.EnvironmentEntry + 226, // 28: openshell.v1.SandboxWorkloadConfig.environment:type_name -> openshell.v1.SandboxWorkloadConfig.EnvironmentEntry 32, // 29: openshell.v1.SandboxWorkloadConfig.resources:type_name -> openshell.v1.SandboxResources 27, // 30: openshell.v1.SandboxResources.gpu:type_name -> openshell.v1.GpuResourceRequirements 34, // 31: openshell.v1.SandboxServiceLevel.startup:type_name -> openshell.v1.SandboxStartup - 249, // 32: openshell.v1.SandboxStartup.ready_within:type_name -> google.protobuf.Duration + 251, // 32: openshell.v1.SandboxStartup.ready_within:type_name -> google.protobuf.Duration 37, // 33: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition 0, // 34: openshell.v1.SandboxStatus.phase:type_name -> openshell.v1.SandboxPhase - 225, // 35: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry + 227, // 35: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry 25, // 36: openshell.v1.CreateSandboxRequest.spec:type_name -> openshell.v1.SandboxSpec - 226, // 37: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry - 227, // 38: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry + 228, // 37: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry + 229, // 38: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry 29, // 39: openshell.v1.CreateSandboxTemplateRequest.template:type_name -> openshell.v1.SandboxWorkloadTemplate 29, // 40: openshell.v1.SandboxTemplateResponse.template:type_name -> openshell.v1.SandboxWorkloadTemplate 29, // 41: openshell.v1.ListSandboxTemplatesResponse.templates:type_name -> openshell.v1.SandboxWorkloadTemplate 24, // 42: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox 24, // 43: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox - 250, // 44: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 252, // 44: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider 24, // 45: openshell.v1.AttachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox 24, // 46: openshell.v1.DetachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox - 70, // 47: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse - 246, // 48: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 69, // 49: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint - 228, // 50: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry - 74, // 51: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout - 75, // 52: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr - 76, // 53: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit - 168, // 54: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget - 169, // 55: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget - 78, // 56: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit - 73, // 57: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest - 81, // 58: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize - 246, // 59: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 72, // 47: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse + 248, // 48: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 71, // 49: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint + 230, // 50: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry + 76, // 51: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout + 77, // 52: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr + 78, // 53: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit + 170, // 54: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget + 171, // 55: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget + 80, // 56: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit + 75, // 57: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest + 83, // 58: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize + 248, // 59: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 24, // 60: openshell.v1.SandboxStreamEvent.sandbox:type_name -> openshell.v1.Sandbox - 85, // 61: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine + 87, // 61: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine 38, // 62: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent - 86, // 63: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning - 179, // 64: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate - 229, // 65: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry - 250, // 66: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 250, // 67: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 230, // 68: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry - 250, // 69: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider - 250, // 70: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider - 117, // 71: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile - 98, // 72: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride + 88, // 63: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning + 181, // 64: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate + 231, // 65: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry + 252, // 66: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 252, // 67: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 232, // 68: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry + 252, // 69: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider + 252, // 70: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 119, // 71: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile + 100, // 72: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride 1, // 73: openshell.v1.ProviderCredentialTokenGrant.grant_type:type_name -> openshell.v1.ProviderCredentialTokenGrantType - 99, // 74: openshell.v1.ProviderCredentialTokenGrant.subject_token:type_name -> openshell.v1.ProviderCredentialTokenGrantSubjectToken - 104, // 75: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh - 100, // 76: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant + 101, // 74: openshell.v1.ProviderCredentialTokenGrant.subject_token:type_name -> openshell.v1.ProviderCredentialTokenGrantSubjectToken + 106, // 75: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh + 102, // 76: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant 2, // 77: openshell.v1.ProviderCredentialRefresh.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 102, // 78: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial - 103, // 79: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput + 104, // 78: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial + 105, // 79: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput 2, // 80: openshell.v1.ProviderCredentialRefreshStatus.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy 7, // 81: openshell.v1.ProviderCredentialRefreshStatus.recovery_action:type_name -> openshell.v1.ProviderCredentialRefreshRecoveryAction - 246, // 82: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 248, // 82: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 2, // 83: openshell.v1.StoredProviderCredentialRefreshState.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 231, // 84: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry - 232, // 85: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - 233, // 86: openshell.v1.StoredProviderCredentialRefreshState.secret_material_handles:type_name -> openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry - 108, // 87: openshell.v1.StoredProviderCredentialRefreshState.pending_secret_deletions:type_name -> openshell.v1.StoredRefreshMaterialDeletion + 233, // 84: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry + 234, // 85: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry + 235, // 86: openshell.v1.StoredProviderCredentialRefreshState.secret_material_handles:type_name -> openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry + 110, // 87: openshell.v1.StoredProviderCredentialRefreshState.pending_secret_deletions:type_name -> openshell.v1.StoredRefreshMaterialDeletion 7, // 88: openshell.v1.StoredProviderCredentialRefreshState.recovery_action:type_name -> openshell.v1.ProviderCredentialRefreshRecoveryAction - 251, // 89: openshell.v1.StoredRefreshMaterialDeletion.handle:type_name -> openshell.datamodel.v1.CredentialHandle - 105, // 90: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 253, // 89: openshell.v1.StoredRefreshMaterialDeletion.handle:type_name -> openshell.datamodel.v1.CredentialHandle + 107, // 90: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus 2, // 91: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 234, // 92: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - 105, // 93: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 105, // 94: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 236, // 92: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + 107, // 93: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 107, // 94: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus 3, // 95: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory - 101, // 96: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential - 252, // 97: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint - 253, // 98: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 106, // 99: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery - 235, // 100: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry - 246, // 101: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 117, // 102: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile - 117, // 103: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile - 117, // 104: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 96, // 105: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 97, // 106: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 117, // 107: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 96, // 108: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem - 97, // 109: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 117, // 110: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile - 96, // 111: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 97, // 112: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 131, // 113: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding - 236, // 114: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - 237, // 115: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - 238, // 116: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - 239, // 117: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - 247, // 118: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 254, // 119: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue - 137, // 120: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation - 240, // 121: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry - 138, // 122: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule - 139, // 123: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint - 140, // 124: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule - 141, // 125: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules - 142, // 126: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules - 143, // 127: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary - 255, // 128: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 256, // 129: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule - 257, // 130: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule - 241, // 131: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry - 151, // 132: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision - 151, // 133: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision + 103, // 96: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential + 254, // 97: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint + 255, // 98: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 108, // 99: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery + 237, // 100: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry + 248, // 101: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 119, // 102: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile + 119, // 103: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile + 119, // 104: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 98, // 105: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 99, // 106: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 119, // 107: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 98, // 108: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem + 99, // 109: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 119, // 110: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile + 98, // 111: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 99, // 112: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 133, // 113: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding + 238, // 114: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + 239, // 115: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + 240, // 116: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + 241, // 117: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + 249, // 118: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 256, // 119: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue + 139, // 120: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation + 242, // 121: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry + 140, // 122: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule + 141, // 123: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint + 142, // 124: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule + 143, // 125: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules + 144, // 126: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules + 145, // 127: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary + 257, // 128: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 258, // 129: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule + 259, // 130: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule + 243, // 131: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry + 153, // 132: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision + 153, // 133: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision 4, // 134: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus 4, // 135: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus - 247, // 136: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 242, // 137: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry - 85, // 138: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine - 85, // 139: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine - 158, // 140: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello - 161, // 141: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat - 172, // 142: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult - 173, // 143: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose - 159, // 144: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted - 160, // 145: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected - 162, // 146: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat - 167, // 147: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen - 173, // 148: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose - 168, // 149: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget - 169, // 150: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget - 170, // 151: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit - 174, // 152: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample - 176, // 153: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount - 255, // 154: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 247, // 155: openshell.v1.PolicyChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 247, // 156: openshell.v1.PolicyChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 175, // 157: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary - 178, // 158: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk - 177, // 159: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary - 178, // 160: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk - 188, // 161: openshell.v1.ApproveAllDraftChunksRequest.approvals:type_name -> openshell.v1.DraftChunkApproval - 255, // 162: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 198, // 163: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry - 247, // 164: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 243, // 165: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry - 255, // 166: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 247, // 167: openshell.v1.DraftChunkPayload.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 247, // 168: openshell.v1.DraftChunkPayload.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 244, // 169: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry - 247, // 170: openshell.v1.StoredDraftChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 247, // 171: openshell.v1.StoredDraftChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 245, // 172: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry - 258, // 173: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 258, // 174: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 258, // 175: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace - 246, // 176: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 249, // 136: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 244, // 137: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry + 87, // 138: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine + 87, // 139: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine + 160, // 140: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello + 163, // 141: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat + 174, // 142: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult + 175, // 143: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose + 161, // 144: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted + 162, // 145: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected + 164, // 146: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat + 169, // 147: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen + 175, // 148: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose + 170, // 149: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget + 171, // 150: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget + 172, // 151: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit + 176, // 152: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample + 178, // 153: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount + 257, // 154: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 249, // 155: openshell.v1.PolicyChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 249, // 156: openshell.v1.PolicyChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 177, // 157: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary + 180, // 158: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk + 179, // 159: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary + 180, // 160: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk + 190, // 161: openshell.v1.ApproveAllDraftChunksRequest.approvals:type_name -> openshell.v1.DraftChunkApproval + 257, // 162: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 200, // 163: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry + 249, // 164: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 245, // 165: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry + 257, // 166: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 249, // 167: openshell.v1.DraftChunkPayload.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 249, // 168: openshell.v1.DraftChunkPayload.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 246, // 169: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry + 249, // 170: openshell.v1.StoredDraftChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 249, // 171: openshell.v1.StoredDraftChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 247, // 172: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry + 260, // 173: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 260, // 174: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 260, // 175: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace + 248, // 176: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 6, // 177: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole 6, // 178: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole - 212, // 179: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember - 212, // 180: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember - 251, // 181: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle - 101, // 182: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential - 132, // 183: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding + 214, // 179: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember + 214, // 180: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember + 253, // 181: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle + 103, // 182: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 134, // 183: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding 12, // 184: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest 14, // 185: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest 16, // 186: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest 39, // 187: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest - 47, // 188: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest - 48, // 189: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest - 40, // 190: openshell.v1.OpenShell.CreateSandboxTemplate:input_type -> openshell.v1.CreateSandboxTemplateRequest - 41, // 191: openshell.v1.OpenShell.GetSandboxTemplate:input_type -> openshell.v1.GetSandboxTemplateRequest - 42, // 192: openshell.v1.OpenShell.ListSandboxTemplates:input_type -> openshell.v1.ListSandboxTemplatesRequest - 43, // 193: openshell.v1.OpenShell.DeleteSandboxTemplate:input_type -> openshell.v1.DeleteSandboxTemplateRequest - 49, // 194: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest - 50, // 195: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest - 51, // 196: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest - 52, // 197: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest - 53, // 198: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest - 54, // 199: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest - 61, // 200: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest - 63, // 201: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest - 64, // 202: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest - 65, // 203: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest - 67, // 204: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest - 71, // 205: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest - 73, // 206: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest - 79, // 207: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame - 80, // 208: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput - 87, // 209: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest - 88, // 210: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest - 89, // 211: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest - 94, // 212: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest - 95, // 213: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest - 121, // 214: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest - 123, // 215: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest - 125, // 216: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest - 90, // 217: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest - 109, // 218: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest - 111, // 219: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest - 113, // 220: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest - 115, // 221: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest - 91, // 222: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest - 128, // 223: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest - 259, // 224: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest - 260, // 225: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest - 136, // 226: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest - 145, // 227: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest - 147, // 228: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest - 149, // 229: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest - 130, // 230: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest - 134, // 231: openshell.v1.OpenShell.ExchangeProviderSubjectToken:input_type -> openshell.v1.ExchangeProviderSubjectTokenRequest - 152, // 232: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest - 153, // 233: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest - 156, // 234: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage - 163, // 235: openshell.v1.OpenShell.ReportMainProcessExit:input_type -> openshell.v1.ReportMainProcessExitRequest - 165, // 236: openshell.v1.OpenShell.FinalizeMainProcessExit:input_type -> openshell.v1.FinalizeMainProcessExitRequest - 171, // 237: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame - 83, // 238: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest - 180, // 239: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest - 182, // 240: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest - 184, // 241: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest - 186, // 242: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest - 189, // 243: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest - 191, // 244: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest - 193, // 245: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest - 195, // 246: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest - 197, // 247: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest - 8, // 248: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest - 10, // 249: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest - 204, // 250: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest - 206, // 251: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest - 208, // 252: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest - 210, // 253: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest - 213, // 254: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest - 215, // 255: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest - 217, // 256: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest - 13, // 257: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse - 15, // 258: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse - 17, // 259: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse - 55, // 260: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse - 55, // 261: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse - 56, // 262: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse - 44, // 263: openshell.v1.OpenShell.CreateSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse - 44, // 264: openshell.v1.OpenShell.GetSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse - 45, // 265: openshell.v1.OpenShell.ListSandboxTemplates:output_type -> openshell.v1.ListSandboxTemplatesResponse - 46, // 266: openshell.v1.OpenShell.DeleteSandboxTemplate:output_type -> openshell.v1.DeleteSandboxTemplateResponse - 57, // 267: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse - 58, // 268: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse - 59, // 269: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse - 60, // 270: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse - 55, // 271: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse - 55, // 272: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse - 62, // 273: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse - 70, // 274: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse - 70, // 275: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse - 66, // 276: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse - 68, // 277: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse - 72, // 278: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse - 77, // 279: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent - 79, // 280: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame - 77, // 281: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent - 92, // 282: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse - 92, // 283: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse - 93, // 284: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse - 120, // 285: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse - 119, // 286: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse - 122, // 287: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse - 124, // 288: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse - 126, // 289: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse - 92, // 290: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse - 110, // 291: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse - 112, // 292: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse - 114, // 293: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse - 116, // 294: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse - 127, // 295: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse - 129, // 296: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse - 261, // 297: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse - 262, // 298: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse - 144, // 299: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse - 146, // 300: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse - 148, // 301: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse - 150, // 302: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse - 133, // 303: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse - 135, // 304: openshell.v1.OpenShell.ExchangeProviderSubjectToken:output_type -> openshell.v1.ExchangeProviderSubjectTokenResponse - 155, // 305: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse - 154, // 306: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse - 157, // 307: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage - 164, // 308: openshell.v1.OpenShell.ReportMainProcessExit:output_type -> openshell.v1.ReportMainProcessExitResponse - 166, // 309: openshell.v1.OpenShell.FinalizeMainProcessExit:output_type -> openshell.v1.FinalizeMainProcessExitResponse - 171, // 310: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame - 84, // 311: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent - 181, // 312: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse - 183, // 313: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse - 185, // 314: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse - 187, // 315: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse - 190, // 316: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse - 192, // 317: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse - 194, // 318: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse - 196, // 319: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse - 199, // 320: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse - 9, // 321: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse - 11, // 322: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse - 205, // 323: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse - 207, // 324: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse - 209, // 325: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse - 211, // 326: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse - 214, // 327: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse - 216, // 328: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse - 218, // 329: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse - 257, // [257:330] is the sub-list for method output_type - 184, // [184:257] is the sub-list for method input_type + 47, // 188: openshell.v1.OpenShell.BeginRootfsTarStaging:input_type -> openshell.v1.BeginRootfsTarStagingRequest + 49, // 189: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest + 50, // 190: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest + 40, // 191: openshell.v1.OpenShell.CreateSandboxTemplate:input_type -> openshell.v1.CreateSandboxTemplateRequest + 41, // 192: openshell.v1.OpenShell.GetSandboxTemplate:input_type -> openshell.v1.GetSandboxTemplateRequest + 42, // 193: openshell.v1.OpenShell.ListSandboxTemplates:input_type -> openshell.v1.ListSandboxTemplatesRequest + 43, // 194: openshell.v1.OpenShell.DeleteSandboxTemplate:input_type -> openshell.v1.DeleteSandboxTemplateRequest + 51, // 195: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest + 52, // 196: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest + 53, // 197: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest + 54, // 198: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest + 55, // 199: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest + 56, // 200: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest + 63, // 201: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest + 65, // 202: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest + 66, // 203: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest + 67, // 204: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest + 69, // 205: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest + 73, // 206: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest + 75, // 207: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest + 81, // 208: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame + 82, // 209: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput + 89, // 210: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest + 90, // 211: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest + 91, // 212: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest + 96, // 213: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest + 97, // 214: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest + 123, // 215: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest + 125, // 216: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest + 127, // 217: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest + 92, // 218: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest + 111, // 219: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest + 113, // 220: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest + 115, // 221: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest + 117, // 222: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest + 93, // 223: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest + 130, // 224: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest + 261, // 225: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest + 262, // 226: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest + 138, // 227: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest + 147, // 228: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest + 149, // 229: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest + 151, // 230: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest + 132, // 231: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest + 136, // 232: openshell.v1.OpenShell.ExchangeProviderSubjectToken:input_type -> openshell.v1.ExchangeProviderSubjectTokenRequest + 154, // 233: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest + 155, // 234: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest + 158, // 235: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage + 165, // 236: openshell.v1.OpenShell.ReportMainProcessExit:input_type -> openshell.v1.ReportMainProcessExitRequest + 167, // 237: openshell.v1.OpenShell.FinalizeMainProcessExit:input_type -> openshell.v1.FinalizeMainProcessExitRequest + 173, // 238: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame + 85, // 239: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest + 182, // 240: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest + 184, // 241: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest + 186, // 242: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest + 188, // 243: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest + 191, // 244: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest + 193, // 245: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest + 195, // 246: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest + 197, // 247: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest + 199, // 248: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest + 8, // 249: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest + 10, // 250: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest + 206, // 251: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest + 208, // 252: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest + 210, // 253: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest + 212, // 254: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest + 215, // 255: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest + 217, // 256: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest + 219, // 257: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest + 13, // 258: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse + 15, // 259: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse + 17, // 260: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse + 57, // 261: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse + 48, // 262: openshell.v1.OpenShell.BeginRootfsTarStaging:output_type -> openshell.v1.BeginRootfsTarStagingResponse + 57, // 263: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse + 58, // 264: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse + 44, // 265: openshell.v1.OpenShell.CreateSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse + 44, // 266: openshell.v1.OpenShell.GetSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse + 45, // 267: openshell.v1.OpenShell.ListSandboxTemplates:output_type -> openshell.v1.ListSandboxTemplatesResponse + 46, // 268: openshell.v1.OpenShell.DeleteSandboxTemplate:output_type -> openshell.v1.DeleteSandboxTemplateResponse + 59, // 269: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse + 60, // 270: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse + 61, // 271: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse + 62, // 272: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse + 57, // 273: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse + 57, // 274: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse + 64, // 275: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse + 72, // 276: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse + 72, // 277: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse + 68, // 278: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse + 70, // 279: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse + 74, // 280: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse + 79, // 281: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent + 81, // 282: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame + 79, // 283: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent + 94, // 284: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse + 94, // 285: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse + 95, // 286: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse + 122, // 287: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse + 121, // 288: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse + 124, // 289: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse + 126, // 290: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse + 128, // 291: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse + 94, // 292: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse + 112, // 293: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse + 114, // 294: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse + 116, // 295: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse + 118, // 296: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse + 129, // 297: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse + 131, // 298: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse + 263, // 299: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse + 264, // 300: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse + 146, // 301: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse + 148, // 302: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse + 150, // 303: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse + 152, // 304: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse + 135, // 305: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse + 137, // 306: openshell.v1.OpenShell.ExchangeProviderSubjectToken:output_type -> openshell.v1.ExchangeProviderSubjectTokenResponse + 157, // 307: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse + 156, // 308: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse + 159, // 309: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage + 166, // 310: openshell.v1.OpenShell.ReportMainProcessExit:output_type -> openshell.v1.ReportMainProcessExitResponse + 168, // 311: openshell.v1.OpenShell.FinalizeMainProcessExit:output_type -> openshell.v1.FinalizeMainProcessExitResponse + 173, // 312: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame + 86, // 313: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent + 183, // 314: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse + 185, // 315: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse + 187, // 316: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse + 189, // 317: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse + 192, // 318: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse + 194, // 319: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse + 196, // 320: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse + 198, // 321: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse + 201, // 322: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse + 9, // 323: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse + 11, // 324: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse + 207, // 325: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse + 209, // 326: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse + 211, // 327: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse + 213, // 328: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse + 216, // 329: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse + 218, // 330: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse + 220, // 331: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse + 258, // [258:332] is the sub-list for method output_type + 184, // [184:258] is the sub-list for method input_type 184, // [184:184] is the sub-list for extension type_name 184, // [184:184] is the sub-list for extension extendee 0, // [0:184] is the sub-list for field type_name @@ -17066,33 +17225,33 @@ func file_openshell_proto_init() { file_openshell_proto_msgTypes[19].OneofWrappers = []any{} file_openshell_proto_msgTypes[20].OneofWrappers = []any{} file_openshell_proto_msgTypes[28].OneofWrappers = []any{} - file_openshell_proto_msgTypes[69].OneofWrappers = []any{ + file_openshell_proto_msgTypes[71].OneofWrappers = []any{ (*ExecSandboxEvent_Stdout)(nil), (*ExecSandboxEvent_Stderr)(nil), (*ExecSandboxEvent_Exit)(nil), } - file_openshell_proto_msgTypes[70].OneofWrappers = []any{ + file_openshell_proto_msgTypes[72].OneofWrappers = []any{ (*TcpForwardInit_Ssh)(nil), (*TcpForwardInit_Tcp)(nil), } - file_openshell_proto_msgTypes[71].OneofWrappers = []any{ + file_openshell_proto_msgTypes[73].OneofWrappers = []any{ (*TcpForwardFrame_Init)(nil), (*TcpForwardFrame_Data)(nil), } - file_openshell_proto_msgTypes[72].OneofWrappers = []any{ + file_openshell_proto_msgTypes[74].OneofWrappers = []any{ (*ExecSandboxInput_Start)(nil), (*ExecSandboxInput_Stdin)(nil), (*ExecSandboxInput_Resize)(nil), } - file_openshell_proto_msgTypes[76].OneofWrappers = []any{ + file_openshell_proto_msgTypes[78].OneofWrappers = []any{ (*SandboxStreamEvent_Sandbox)(nil), (*SandboxStreamEvent_Log)(nil), (*SandboxStreamEvent_Event)(nil), (*SandboxStreamEvent_Warning)(nil), (*SandboxStreamEvent_DraftPolicyUpdate)(nil), } - file_openshell_proto_msgTypes[103].OneofWrappers = []any{} - file_openshell_proto_msgTypes[129].OneofWrappers = []any{ + file_openshell_proto_msgTypes[105].OneofWrappers = []any{} + file_openshell_proto_msgTypes[131].OneofWrappers = []any{ (*PolicyMergeOperation_AddRule)(nil), (*PolicyMergeOperation_RemoveEndpoint)(nil), (*PolicyMergeOperation_RemoveRule)(nil), @@ -17100,36 +17259,36 @@ func file_openshell_proto_init() { (*PolicyMergeOperation_AddAllowRules)(nil), (*PolicyMergeOperation_RemoveBinary)(nil), } - file_openshell_proto_msgTypes[148].OneofWrappers = []any{ + file_openshell_proto_msgTypes[150].OneofWrappers = []any{ (*SupervisorMessage_Hello)(nil), (*SupervisorMessage_Heartbeat)(nil), (*SupervisorMessage_RelayOpenResult)(nil), (*SupervisorMessage_RelayClose)(nil), } - file_openshell_proto_msgTypes[149].OneofWrappers = []any{ + file_openshell_proto_msgTypes[151].OneofWrappers = []any{ (*GatewayMessage_SessionAccepted)(nil), (*GatewayMessage_SessionRejected)(nil), (*GatewayMessage_Heartbeat)(nil), (*GatewayMessage_RelayOpen)(nil), (*GatewayMessage_RelayClose)(nil), } - file_openshell_proto_msgTypes[159].OneofWrappers = []any{ + file_openshell_proto_msgTypes[161].OneofWrappers = []any{ (*RelayOpen_Ssh)(nil), (*RelayOpen_Tcp)(nil), } - file_openshell_proto_msgTypes[163].OneofWrappers = []any{ + file_openshell_proto_msgTypes[165].OneofWrappers = []any{ (*RelayFrame_Init)(nil), (*RelayFrame_Data)(nil), } - file_openshell_proto_msgTypes[194].OneofWrappers = []any{} - file_openshell_proto_msgTypes[195].OneofWrappers = []any{} + file_openshell_proto_msgTypes[196].OneofWrappers = []any{} + file_openshell_proto_msgTypes[197].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_openshell_proto_rawDesc), len(file_openshell_proto_rawDesc)), NumEnums: 8, - NumMessages: 238, + NumMessages: 240, NumExtensions: 0, NumServices: 1, }, diff --git a/sdk/go/proto/openshellv1/openshell_grpc.pb.go b/sdk/go/proto/openshellv1/openshell_grpc.pb.go index 61bc081437..d8f3c91008 100644 --- a/sdk/go/proto/openshellv1/openshell_grpc.pb.go +++ b/sdk/go/proto/openshellv1/openshell_grpc.pb.go @@ -27,6 +27,7 @@ const ( OpenShell_GetCurrentUser_FullMethodName = "/openshell.v1.OpenShell/GetCurrentUser" OpenShell_GetGatewayInfo_FullMethodName = "/openshell.v1.OpenShell/GetGatewayInfo" OpenShell_CreateSandbox_FullMethodName = "/openshell.v1.OpenShell/CreateSandbox" + OpenShell_BeginRootfsTarStaging_FullMethodName = "/openshell.v1.OpenShell/BeginRootfsTarStaging" OpenShell_GetSandbox_FullMethodName = "/openshell.v1.OpenShell/GetSandbox" OpenShell_ListSandboxes_FullMethodName = "/openshell.v1.OpenShell/ListSandboxes" OpenShell_CreateSandboxTemplate_FullMethodName = "/openshell.v1.OpenShell/CreateSandboxTemplate" @@ -119,6 +120,15 @@ type OpenShellClient interface { GetGatewayInfo(ctx context.Context, in *GetGatewayInfoRequest, opts ...grpc.CallOption) (*GetGatewayInfoResponse, error) // Create a new sandbox. CreateSandbox(ctx context.Context, in *CreateSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) + // Allocate a gateway-owned staging slot for a local rootfs tar archive. + // + // The gateway creates a request-scoped directory inside the compute driver's + // staging root and returns an opaque single-use token plus the absolute path + // the client must write the archive to. The token is then passed as + // `template.driver_config..rootfs_tar_staging_token` on + // CreateSandbox; callers never name a filesystem path themselves. Only a + // client sharing the gateway's filesystem can complete the upload. + BeginRootfsTarStaging(ctx context.Context, in *BeginRootfsTarStagingRequest, opts ...grpc.CallOption) (*BeginRootfsTarStagingResponse, error) // Fetch a sandbox by name. GetSandbox(ctx context.Context, in *GetSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) // List sandboxes. @@ -346,6 +356,16 @@ func (c *openShellClient) CreateSandbox(ctx context.Context, in *CreateSandboxRe return out, nil } +func (c *openShellClient) BeginRootfsTarStaging(ctx context.Context, in *BeginRootfsTarStagingRequest, opts ...grpc.CallOption) (*BeginRootfsTarStagingResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(BeginRootfsTarStagingResponse) + err := c.cc.Invoke(ctx, OpenShell_BeginRootfsTarStaging_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *openShellClient) GetSandbox(ctx context.Context, in *GetSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(SandboxResponse) @@ -1090,6 +1110,15 @@ type OpenShellServer interface { GetGatewayInfo(context.Context, *GetGatewayInfoRequest) (*GetGatewayInfoResponse, error) // Create a new sandbox. CreateSandbox(context.Context, *CreateSandboxRequest) (*SandboxResponse, error) + // Allocate a gateway-owned staging slot for a local rootfs tar archive. + // + // The gateway creates a request-scoped directory inside the compute driver's + // staging root and returns an opaque single-use token plus the absolute path + // the client must write the archive to. The token is then passed as + // `template.driver_config..rootfs_tar_staging_token` on + // CreateSandbox; callers never name a filesystem path themselves. Only a + // client sharing the gateway's filesystem can complete the upload. + BeginRootfsTarStaging(context.Context, *BeginRootfsTarStagingRequest) (*BeginRootfsTarStagingResponse, error) // Fetch a sandbox by name. GetSandbox(context.Context, *GetSandboxRequest) (*SandboxResponse, error) // List sandboxes. @@ -1289,6 +1318,9 @@ func (UnimplementedOpenShellServer) GetGatewayInfo(context.Context, *GetGatewayI func (UnimplementedOpenShellServer) CreateSandbox(context.Context, *CreateSandboxRequest) (*SandboxResponse, error) { return nil, status.Error(codes.Unimplemented, "method CreateSandbox not implemented") } +func (UnimplementedOpenShellServer) BeginRootfsTarStaging(context.Context, *BeginRootfsTarStagingRequest) (*BeginRootfsTarStagingResponse, error) { + return nil, status.Error(codes.Unimplemented, "method BeginRootfsTarStaging not implemented") +} func (UnimplementedOpenShellServer) GetSandbox(context.Context, *GetSandboxRequest) (*SandboxResponse, error) { return nil, status.Error(codes.Unimplemented, "method GetSandbox not implemented") } @@ -1589,6 +1621,24 @@ func _OpenShell_CreateSandbox_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _OpenShell_BeginRootfsTarStaging_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BeginRootfsTarStagingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OpenShellServer).BeginRootfsTarStaging(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: OpenShell_BeginRootfsTarStaging_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OpenShellServer).BeginRootfsTarStaging(ctx, req.(*BeginRootfsTarStagingRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _OpenShell_GetSandbox_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetSandboxRequest) if err := dec(in); err != nil { @@ -2785,6 +2835,10 @@ var OpenShell_ServiceDesc = grpc.ServiceDesc{ MethodName: "CreateSandbox", Handler: _OpenShell_CreateSandbox_Handler, }, + { + MethodName: "BeginRootfsTarStaging", + Handler: _OpenShell_BeginRootfsTarStaging_Handler, + }, { MethodName: "GetSandbox", Handler: _OpenShell_GetSandbox_Handler, From 9eec9916799f533f1aa634963268af3571e9b2d3 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Mon, 31 Aug 2026 10:57:32 +0200 Subject: [PATCH 7/8] fix(vm): derive rootfs tar cache identity from archive contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prepared-disk cache key combined the archive's full path with an mtime truncated to seconds, then mapped punctuation to `-`. Distinct paths such as `/tmp/a/b.tar` and `/tmp/a-b.tar` collapsed onto the same key and reused each other's disk, a rewrite within the same second kept stale contents, and a long path could exceed filesystem component limits. Identity is now a SHA-256 of the archive contents. This is also what makes the cache work at all now that the gateway allocates a fresh staging directory per request: a path-derived key would miss on every create. The archive is hashed, the cache checked, and only on a miss copied — so a hit skips writing a multi-gigabyte file. The copy is hashed as it is written and rejected if the digest differs from the first pass, which closes the window where the source changes during staging rather than approximating it with a re-stat. Refs #2175 Signed-off-by: Philippe Martin --- crates/openshell-driver-vm/src/driver.rs | 344 +++++++++++++++++++++-- 1 file changed, 326 insertions(+), 18 deletions(-) diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index fd87b13989..03ed708f29 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -62,7 +62,7 @@ use sha2::{Digest, Sha256}; use std::collections::{HashMap, HashSet}; use std::fs; use std::future::Future; -use std::io::Read; +use std::io::{Read, Write}; use std::net::{IpAddr, Ipv4Addr}; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; @@ -2901,20 +2901,30 @@ impl VmDriver { } }; - let metadata = tokio::fs::metadata(tar_path).await.map_err(|err| { - Status::failed_precondition(format!( - "rootfs tar not accessible at {}: {err}", - tar_path.display() - )) - })?; - let mtime = metadata - .modified() - .unwrap_or(std::time::SystemTime::UNIX_EPOCH) - .duration_since(std::time::SystemTime::UNIX_EPOCH) - .unwrap_or_default() - .as_secs(); - let tar_identity = format!("rootfs-tar:{}:{mtime}", tar_path.display()); - let cache_identity = prepared_image_cache_identity(&tar_identity); + // Identity comes from the archive contents. See `rootfs_tar_cache_identity`. + let hash_source = tar_path.to_path_buf(); + let source_digest = match tokio::task::spawn_blocking(move || { + compute_file_sha256_hex(&hash_source) + }) + .await + { + Ok(Ok(digest)) => digest, + Ok(Err(err)) => { + cleanup_request_staging().await; + return Err(Status::failed_precondition(format!( + "rootfs tar not readable at {}: {err}", + tar_path.display() + ))); + } + Err(err) => { + cleanup_request_staging().await; + return Err(Status::internal(format!( + "failed to hash rootfs tar at {}: {err}", + tar_path.display() + ))); + } + }; + let cache_identity = rootfs_tar_cache_identity(&source_digest); let image_path = image_cache_rootfs_image(&self.config.state_dir, &cache_identity); let tar_display = tar_path.display().to_string(); @@ -2962,11 +2972,37 @@ impl VmDriver { ("image_identity".to_string(), cache_identity.clone()), ]), ); - if let Err(err) = tokio::fs::copy(tar_path, &rootfs_archive).await { + let copy_src = tar_path.to_path_buf(); + let copy_dst = rootfs_archive.clone(); + let copied_digest = + match tokio::task::spawn_blocking(move || copy_file_sha256_hex(©_src, ©_dst)) + .await + { + Ok(Ok(digest)) => digest, + Ok(Err(err)) => { + let _ = tokio::fs::remove_dir_all(&staging_dir).await; + cleanup_request_staging().await; + return Err(Status::internal(format!( + "failed to copy rootfs tar to staging: {err}" + ))); + } + Err(err) => { + let _ = tokio::fs::remove_dir_all(&staging_dir).await; + cleanup_request_staging().await; + return Err(Status::internal(format!( + "failed to copy rootfs tar to staging: {err}" + ))); + } + }; + + // The archive changed between the hash pass and the copy: the prepared + // disk we are about to build would not match the identity it is cached + // under. Reject rather than poison the cache. + if copied_digest != source_digest { let _ = tokio::fs::remove_dir_all(&staging_dir).await; cleanup_request_staging().await; - return Err(Status::internal(format!( - "failed to copy rootfs tar to staging: {err}" + return Err(Status::aborted(format!( + "rootfs tar {tar_display} changed while it was being staged; retry the request" ))); } cleanup_request_staging().await; @@ -4791,6 +4827,46 @@ fn compute_bytes_sha256_hex(bytes: &[u8]) -> String { format!("{:x}", hasher.finalize()) } +/// Copy `src` to `dst` and return the SHA-256 of the bytes actually written. +/// +/// Hashing the copy rather than re-reading the source is what lets the caller +/// detect an archive that changed underneath it during staging: the digest +/// describes exactly the bytes that landed in the image cache. +fn copy_file_sha256_hex(src: &Path, dst: &Path) -> Result { + let mut reader = fs::File::open(src).map_err(|err| format!("open {}: {err}", src.display()))?; + let mut writer = + fs::File::create(dst).map_err(|err| format!("create {}: {err}", dst.display()))?; + let mut hasher = Sha256::new(); + let mut buffer = vec![0_u8; 64 * 1024].into_boxed_slice(); + loop { + let read = reader + .read(&mut buffer) + .map_err(|err| format!("read {}: {err}", src.display()))?; + if read == 0 { + break; + } + hasher.update(&buffer[..read]); + writer + .write_all(&buffer[..read]) + .map_err(|err| format!("write {}: {err}", dst.display()))?; + } + writer + .flush() + .map_err(|err| format!("flush {}: {err}", dst.display()))?; + Ok(format!("{:x}", hasher.finalize())) +} + +/// Cache identity for a rootfs tar archive, derived from its contents. +/// +/// Deliberately not path- or mtime-derived: staging directories are unique per +/// request, so a path-based key would never hit the cache, and a +/// seconds-truncated mtime cannot distinguish two writes within the same +/// second. A fixed-length digest also keeps the cache directory name inside +/// filesystem component limits regardless of how long the source path was. +fn rootfs_tar_cache_identity(digest: &str) -> String { + prepared_image_cache_identity(&format!("rootfs-tar:sha256:{digest}")) +} + fn extract_layer_blob_to_dir( blob_path: &Path, media_type: &str, @@ -8934,6 +9010,238 @@ mod tests { }; use crate::runtime::VmBackend; + /// Driver whose rootfs tar staging root is an isolated temp directory. + fn rootfs_tar_test_driver(staging_root: &Path, max_bytes: Option) -> VmDriver { + let (events, _) = broadcast::channel(WATCH_BUFFER); + VmDriver { + config: VmDriverConfig { + rootfs_tar_staging_dir: Some(staging_root.to_path_buf()), + rootfs_tar_max_bytes: max_bytes, + ..Default::default() + }, + launcher_bin: PathBuf::from("openshell-driver-vm"), + registry: Arc::new(Mutex::new(HashMap::new())), + image_cache_lock: Arc::new(Mutex::new(())), + events, + gpu_inventory: None, + subnet_allocator: Arc::new(std::sync::Mutex::new(SubnetAllocator::new( + Ipv4Addr::new(10, 0, 128, 0), + 17, + ))), + lifecycle_extensions: Arc::new(LifecycleExtensionRegistry::new()), + } + } + + /// `/req-/` with `contents`, the shape the + /// gateway allocates for one create request. + fn staged_rootfs_tar(staging_root: &Path, request: &str, contents: &[u8]) -> PathBuf { + let request_dir = staging_root.join(format!("req-{request}")); + std::fs::create_dir_all(&request_dir).expect("create request dir"); + let archive = request_dir.join("rootfs.tar"); + std::fs::write(&archive, contents).expect("write archive"); + archive + } + + #[tokio::test] + async fn validate_rootfs_tar_path_accepts_staged_archive() { + let root = unique_temp_dir(); + std::fs::create_dir_all(&root).expect("create staging root"); + let archive = staged_rootfs_tar(&root, "a", b"payload"); + let driver = rootfs_tar_test_driver(&root, None); + + let resolved = driver + .validate_rootfs_tar_path(&archive) + .await + .expect("a correctly staged archive is accepted"); + + assert_eq!( + resolved, + archive.canonicalize().expect("canonicalize archive") + ); + let _ = std::fs::remove_dir_all(&root); + } + + /// The core of the fix: a caller-named host path must never reach + /// privileged driver I/O, even if the caller is authenticated. + #[tokio::test] + async fn validate_rootfs_tar_path_rejects_arbitrary_host_paths() { + let root = unique_temp_dir(); + std::fs::create_dir_all(&root).expect("create staging root"); + let driver = rootfs_tar_test_driver(&root, None); + + for candidate in ["/etc/passwd", "/dev/zero"] { + let path = Path::new(candidate); + if !path.exists() { + continue; + } + let Err(err) = driver.validate_rootfs_tar_path(path).await else { + panic!("{candidate} must be rejected"); + }; + assert_eq!( + err.code(), + Code::PermissionDenied, + "{candidate} should be denied, got: {err}" + ); + } + let _ = std::fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn validate_rootfs_tar_path_rejects_symlink_escape() { + let root = unique_temp_dir(); + let request_dir = root.join("req-a"); + std::fs::create_dir_all(&request_dir).expect("create request dir"); + let target = unique_temp_dir(); + std::fs::create_dir_all(&target).expect("create escape target dir"); + let secret = target.join("secret.tar"); + std::fs::write(&secret, b"not yours").expect("write escape target"); + let link = request_dir.join("rootfs.tar"); + std::os::unix::fs::symlink(&secret, &link).expect("create symlink"); + let driver = rootfs_tar_test_driver(&root, None); + + let err = driver + .validate_rootfs_tar_path(&link) + .await + .expect_err("a symlink out of the staging root must be rejected"); + + assert_eq!(err.code(), Code::PermissionDenied, "{err}"); + let _ = std::fs::remove_dir_all(&root); + let _ = std::fs::remove_dir_all(&target); + } + + #[tokio::test] + async fn validate_rootfs_tar_path_rejects_wrong_depth() { + let root = unique_temp_dir(); + std::fs::create_dir_all(&root).expect("create staging root"); + let shallow = root.join("rootfs.tar"); + std::fs::write(&shallow, b"payload").expect("write shallow archive"); + let deep_dir = root.join("req-a").join("nested"); + std::fs::create_dir_all(&deep_dir).expect("create deep dir"); + let deep = deep_dir.join("rootfs.tar"); + std::fs::write(&deep, b"payload").expect("write deep archive"); + let driver = rootfs_tar_test_driver(&root, None); + + for path in [&shallow, &deep] { + let err = driver + .validate_rootfs_tar_path(path) + .await + .expect_err("only request-directory depth is accepted"); + assert_eq!(err.code(), Code::PermissionDenied, "{err}"); + } + let _ = std::fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn validate_rootfs_tar_path_rejects_directory() { + let root = unique_temp_dir(); + let request_dir = root.join("req-a"); + let not_a_file = request_dir.join("rootfs.tar"); + std::fs::create_dir_all(¬_a_file).expect("create directory in archive position"); + let driver = rootfs_tar_test_driver(&root, None); + + let err = driver + .validate_rootfs_tar_path(¬_a_file) + .await + .expect_err("a directory is not a rootfs tar"); + + assert_eq!(err.code(), Code::InvalidArgument, "{err}"); + let _ = std::fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn validate_rootfs_tar_path_enforces_max_bytes() { + let root = unique_temp_dir(); + std::fs::create_dir_all(&root).expect("create staging root"); + let archive = staged_rootfs_tar(&root, "a", &[0_u8; 64]); + let driver = rootfs_tar_test_driver(&root, Some(16)); + + let err = driver + .validate_rootfs_tar_path(&archive) + .await + .expect_err("an oversized archive must be rejected"); + + assert_eq!(err.code(), Code::InvalidArgument, "{err}"); + let _ = std::fs::remove_dir_all(&root); + } + + /// Identity must follow the bytes, not the path. The gateway hands every + /// request its own staging directory, so a path-derived key would miss the + /// cache on every single create. + #[test] + fn rootfs_tar_cache_identity_tracks_contents_not_path() { + let same_a = rootfs_tar_cache_identity(&compute_bytes_sha256_hex(b"rootfs-bytes")); + let same_b = rootfs_tar_cache_identity(&compute_bytes_sha256_hex(b"rootfs-bytes")); + let different = rootfs_tar_cache_identity(&compute_bytes_sha256_hex(b"other-bytes")); + + assert_eq!( + same_a, same_b, + "identical contents must share one prepared disk" + ); + assert_ne!( + same_a, different, + "different contents must not collide on one prepared disk" + ); + } + + /// The old key was `path + seconds-truncated mtime` run through a + /// punctuation sanitizer, so `/tmp/a/b.tar` and `/tmp/a-b.tar` collided and + /// a long path could blow past filesystem component limits. + #[test] + fn rootfs_tar_cache_identity_is_bounded_and_separator_safe() { + let long_path_digest = compute_bytes_sha256_hex(&vec![7_u8; 4096]); + let identity = rootfs_tar_cache_identity(&long_path_digest); + let sanitized = sanitize_image_identity(&identity); + + assert!( + sanitized.len() < 255, + "cache directory component must stay within filesystem limits, got {}", + sanitized.len() + ); + assert_ne!( + rootfs_tar_cache_identity(&compute_bytes_sha256_hex(b"/tmp/a/b.tar")), + rootfs_tar_cache_identity(&compute_bytes_sha256_hex(b"/tmp/a-b.tar")), + "separator-colliding inputs must not share an identity" + ); + } + + #[test] + fn copy_file_sha256_hex_matches_source_digest() { + let base = unique_temp_dir(); + std::fs::create_dir_all(&base).expect("create base dir"); + let src = base.join("src.tar"); + let dst = base.join("dst.tar"); + let payload = vec![3_u8; 200 * 1024]; + std::fs::write(&src, &payload).expect("write source"); + + let copied = copy_file_sha256_hex(&src, &dst).expect("copy should succeed"); + + assert_eq!(copied, compute_file_sha256_hex(&src).expect("hash source")); + assert_eq!(copied, compute_bytes_sha256_hex(&payload)); + assert_eq!(std::fs::read(&dst).expect("read copy"), payload); + let _ = std::fs::remove_dir_all(&base); + } + + /// An archive rewritten between the hash pass and the copy pass yields a + /// different digest, which is what lets the caller reject it instead of + /// caching a disk under an identity that does not describe it. + #[test] + fn copy_file_sha256_hex_detects_content_change_between_passes() { + let base = unique_temp_dir(); + std::fs::create_dir_all(&base).expect("create base dir"); + let src = base.join("src.tar"); + std::fs::write(&src, b"original").expect("write source"); + let first = compute_file_sha256_hex(&src).expect("hash source"); + + std::fs::write(&src, b"replaced").expect("rewrite source"); + let second = copy_file_sha256_hex(&src, &base.join("dst.tar")).expect("copy"); + + assert_ne!( + first, second, + "a mid-staging rewrite must produce a different digest" + ); + let _ = std::fs::remove_dir_all(&base); + } + fn test_driver_with_extensions(extensions: LifecycleExtensionRegistry) -> VmDriver { let (events, _) = broadcast::channel(WATCH_BUFFER); VmDriver { From 00c9bda65bd77f0e4111f6d685e7f7be4e9232f1 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Fri, 4 Sep 2026 11:21:00 +0200 Subject: [PATCH 8/8] fix(vm): decompress gzip rootfs tar archives during staging `--from` accepts `.tar.gz` and `.tgz`, but the driver staged whatever bytes it was given and the guest image-prep VM extracts the staged file with a plain `tar -xpf`. Compressed sources therefore depended on the guest tar auto-detecting gzip, and the prepared disk was sized from the compressed length, which is far too small for the expanded rootfs. Staging now detects gzip from the archive's magic bytes -- the driver only ever sees a gateway-issued staging path, never the caller's file name -- and writes an uncompressed tar. The digest still covers the source bytes, so the "archive changed while staging" check is unaffected, and expansion is bounded by `rootfs_tar_max_bytes` so a compression bomb cannot fill the host disk. `extract_rootfs_archive_to` sniffs gzip as well, so the host-side extraction path matches. Adds unit coverage for gzip staging, bounded expansion, and gzip extraction, plus an e2e sandbox created from a gzip-compressed export. Signed-off-by: Philippe Martin --- crates/openshell-driver-vm/src/driver.rs | 221 +++++++++++++++++++---- crates/openshell-driver-vm/src/rootfs.rs | 58 +++++- docs/reference/gateway-config.mdx | 2 + docs/sandboxes/manage-sandboxes.mdx | 7 +- e2e/rust/tests/rootfs_tar.rs | 84 ++++++--- 5 files changed, 308 insertions(+), 64 deletions(-) diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index 03ed708f29..896daa48a5 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -18,7 +18,7 @@ use bollard::Docker; use bollard::errors::Error as BollardError; use bollard::models::ContainerCreateBody; use bollard::query_parameters::{CreateContainerOptionsBuilder, RemoveContainerOptionsBuilder}; -use flate2::read::GzDecoder; +use flate2::read::{GzDecoder, MultiGzDecoder}; use futures::{Stream, StreamExt, TryStreamExt}; use nix::errno::Errno; use nix::sys::signal::{Signal, kill}; @@ -62,7 +62,7 @@ use sha2::{Digest, Sha256}; use std::collections::{HashMap, HashSet}; use std::fs; use std::future::Future; -use std::io::{Read, Write}; +use std::io::{BufRead, BufReader, BufWriter, Read, Write}; use std::net::{IpAddr, Ipv4Addr}; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; @@ -2974,26 +2974,28 @@ impl VmDriver { ); let copy_src = tar_path.to_path_buf(); let copy_dst = rootfs_archive.clone(); - let copied_digest = - match tokio::task::spawn_blocking(move || copy_file_sha256_hex(©_src, ©_dst)) - .await - { - Ok(Ok(digest)) => digest, - Ok(Err(err)) => { - let _ = tokio::fs::remove_dir_all(&staging_dir).await; - cleanup_request_staging().await; - return Err(Status::internal(format!( - "failed to copy rootfs tar to staging: {err}" - ))); - } - Err(err) => { - let _ = tokio::fs::remove_dir_all(&staging_dir).await; - cleanup_request_staging().await; - return Err(Status::internal(format!( - "failed to copy rootfs tar to staging: {err}" - ))); - } - }; + let max_bytes = self.config.rootfs_tar_max_bytes(); + let copied_digest = match tokio::task::spawn_blocking(move || { + stage_rootfs_tar_archive(©_src, ©_dst, max_bytes) + }) + .await + { + Ok(Ok(digest)) => digest, + Ok(Err(err)) => { + let _ = tokio::fs::remove_dir_all(&staging_dir).await; + cleanup_request_staging().await; + return Err(Status::internal(format!( + "failed to copy rootfs tar to staging: {err}" + ))); + } + Err(err) => { + let _ = tokio::fs::remove_dir_all(&staging_dir).await; + cleanup_request_staging().await; + return Err(Status::internal(format!( + "failed to copy rootfs tar to staging: {err}" + ))); + } + }; // The archive changed between the hash pass and the copy: the prepared // disk we are about to build would not match the identity it is cached @@ -4827,33 +4829,100 @@ fn compute_bytes_sha256_hex(bytes: &[u8]) -> String { format!("{:x}", hasher.finalize()) } -/// Copy `src` to `dst` and return the SHA-256 of the bytes actually written. +/// Stage the caller-supplied rootfs archive at `src` into the image cache at +/// `dst`, and return the SHA-256 of the source bytes that were read. /// -/// Hashing the copy rather than re-reading the source is what lets the caller -/// detect an archive that changed underneath it during staging: the digest -/// describes exactly the bytes that landed in the image cache. -fn copy_file_sha256_hex(src: &Path, dst: &Path) -> Result { - let mut reader = fs::File::open(src).map_err(|err| format!("open {}: {err}", src.display()))?; - let mut writer = - fs::File::create(dst).map_err(|err| format!("create {}: {err}", dst.display()))?; - let mut hasher = Sha256::new(); +/// The staged file is always an uncompressed tar. `--from` accepts `.tar.gz` +/// and `.tgz`, but the guest image-prep VM extracts the staged file with a +/// plain `tar -xpf`, and the prepared disk is sized from that file's length, +/// so leaving gzip bytes on disk would both depend on the guest tar +/// auto-detecting compression and size the disk from the compressed length. +/// Compression is detected from the magic bytes: the driver only ever sees a +/// gateway-issued staging path, never the caller's file name. +/// +/// Expansion is bounded by `max_bytes` — the same limit the driver applies to +/// the archive it accepts — so a compression bomb cannot fill the host disk. +/// +/// The digest covers the source bytes rather than the bytes written, which is +/// what lets the caller detect an archive that changed underneath it during +/// staging: it stays comparable with the pre-copy hash pass whether or not the +/// source was compressed. +fn stage_rootfs_tar_archive(src: &Path, dst: &Path, max_bytes: u64) -> Result { + let file = fs::File::open(src).map_err(|err| format!("open {}: {err}", src.display()))?; + let mut reader = BufReader::new(file); + let compressed = reader + .fill_buf() + .map_err(|err| format!("read {}: {err}", src.display()))? + .starts_with(&crate::rootfs::GZIP_MAGIC); + + let mut source = HashingReader::new(reader); + if compressed { + write_stream_to_file(MultiGzDecoder::new(&mut source), dst, max_bytes)?; + } else { + write_stream_to_file(&mut source, dst, max_bytes)?; + } + + // A decoder stops at the end of the compressed stream, so drain whatever + // it left behind: the digest has to describe the whole source file for the + // caller's change-detection comparison to mean anything. + std::io::copy(&mut source, &mut std::io::sink()) + .map_err(|err| format!("read {}: {err}", src.display()))?; + Ok(source.finish()) +} + +/// Reader adapter that digests every byte it yields. +struct HashingReader { + inner: R, + hasher: Sha256, +} + +impl HashingReader { + fn new(inner: R) -> Self { + Self { + inner, + hasher: Sha256::new(), + } + } + + fn finish(self) -> String { + format!("{:x}", self.hasher.finalize()) + } +} + +impl Read for HashingReader { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let read = self.inner.read(buf)?; + self.hasher.update(&buf[..read]); + Ok(read) + } +} + +fn write_stream_to_file(mut reader: impl Read, dst: &Path, max_bytes: u64) -> Result<(), String> { + let mut writer = BufWriter::new( + fs::File::create(dst).map_err(|err| format!("create {}: {err}", dst.display()))?, + ); let mut buffer = vec![0_u8; 64 * 1024].into_boxed_slice(); + let mut written = 0_u64; loop { let read = reader .read(&mut buffer) - .map_err(|err| format!("read {}: {err}", src.display()))?; + .map_err(|err| format!("read rootfs tar: {err}"))?; if read == 0 { break; } - hasher.update(&buffer[..read]); + written = written.saturating_add(u64::try_from(read).unwrap_or(u64::MAX)); + if written > max_bytes { + return Err(format!( + "rootfs tar expands to more than the {max_bytes} byte limit" + )); + } writer .write_all(&buffer[..read]) .map_err(|err| format!("write {}: {err}", dst.display()))?; } writer .flush() - .map_err(|err| format!("flush {}: {err}", dst.display()))?; - Ok(format!("{:x}", hasher.finalize())) + .map_err(|err| format!("flush {}: {err}", dst.display())) } /// Cache identity for a rootfs tar archive, derived from its contents. @@ -9204,8 +9273,29 @@ mod tests { ); } + const TEST_STAGING_LIMIT: u64 = 10 * 1024 * 1024; + + /// Build an uncompressed tar holding a single file. + fn tar_bytes_with_file(name: &str, contents: &[u8]) -> Vec { + let mut builder = tar::Builder::new(Vec::new()); + let mut header = tar::Header::new_gnu(); + header.set_size(u64::try_from(contents.len()).expect("tar entry size fits u64")); + header.set_mode(0o644); + header.set_cksum(); + builder + .append_data(&mut header, name, contents) + .expect("append tar entry"); + builder.into_inner().expect("finish tar") + } + + fn gzip_bytes(bytes: &[u8]) -> Vec { + let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default()); + encoder.write_all(bytes).expect("gzip payload"); + encoder.finish().expect("finish gzip") + } + #[test] - fn copy_file_sha256_hex_matches_source_digest() { + fn stage_rootfs_tar_archive_matches_source_digest() { let base = unique_temp_dir(); std::fs::create_dir_all(&base).expect("create base dir"); let src = base.join("src.tar"); @@ -9213,7 +9303,8 @@ mod tests { let payload = vec![3_u8; 200 * 1024]; std::fs::write(&src, &payload).expect("write source"); - let copied = copy_file_sha256_hex(&src, &dst).expect("copy should succeed"); + let copied = + stage_rootfs_tar_archive(&src, &dst, TEST_STAGING_LIMIT).expect("copy should succeed"); assert_eq!(copied, compute_file_sha256_hex(&src).expect("hash source")); assert_eq!(copied, compute_bytes_sha256_hex(&payload)); @@ -9225,7 +9316,7 @@ mod tests { /// different digest, which is what lets the caller reject it instead of /// caching a disk under an identity that does not describe it. #[test] - fn copy_file_sha256_hex_detects_content_change_between_passes() { + fn stage_rootfs_tar_archive_detects_content_change_between_passes() { let base = unique_temp_dir(); std::fs::create_dir_all(&base).expect("create base dir"); let src = base.join("src.tar"); @@ -9233,7 +9324,8 @@ mod tests { let first = compute_file_sha256_hex(&src).expect("hash source"); std::fs::write(&src, b"replaced").expect("rewrite source"); - let second = copy_file_sha256_hex(&src, &base.join("dst.tar")).expect("copy"); + let second = stage_rootfs_tar_archive(&src, &base.join("dst.tar"), TEST_STAGING_LIMIT) + .expect("copy"); assert_ne!( first, second, @@ -9242,6 +9334,57 @@ mod tests { let _ = std::fs::remove_dir_all(&base); } + /// `--from` accepts `.tar.gz`/`.tgz`, and the guest extracts the staged + /// file as a plain tar, so staging has to decompress on the way in. + #[test] + fn stage_rootfs_tar_archive_decompresses_gzip_sources() { + let base = unique_temp_dir(); + std::fs::create_dir_all(&base).expect("create base dir"); + let tar = tar_bytes_with_file("etc/marker.txt", b"rootfs-tar-gzip\n"); + let gzipped = gzip_bytes(&tar); + let src = base.join("src.tar.gz"); + let dst = base.join("source-rootfs.tar"); + std::fs::write(&src, &gzipped).expect("write source"); + + let digest = + stage_rootfs_tar_archive(&src, &dst, TEST_STAGING_LIMIT).expect("stage gzip archive"); + + assert_eq!( + digest, + compute_bytes_sha256_hex(&gzipped), + "the digest must cover the whole compressed source" + ); + assert_eq!( + std::fs::read(&dst).expect("read staged archive"), + tar, + "the staged archive must be an uncompressed tar" + ); + + let extracted = base.join("extracted"); + extract_rootfs_archive_to(&dst, &extracted).expect("extract staged archive"); + assert_eq!( + std::fs::read_to_string(extracted.join("etc/marker.txt")).expect("read marker"), + "rootfs-tar-gzip\n" + ); + let _ = std::fs::remove_dir_all(&base); + } + + /// The configured limit bounds what the driver writes, not just what it + /// accepts, so a highly compressible archive cannot fill the host disk. + #[test] + fn stage_rootfs_tar_archive_rejects_oversized_expansion() { + let base = unique_temp_dir(); + std::fs::create_dir_all(&base).expect("create base dir"); + let src = base.join("bomb.tar.gz"); + std::fs::write(&src, gzip_bytes(&vec![0_u8; 4 * 1024 * 1024])).expect("write source"); + + let err = stage_rootfs_tar_archive(&src, &base.join("dst.tar"), 64 * 1024) + .expect_err("expansion beyond the limit must be rejected"); + + assert!(err.contains("65536"), "unexpected error: {err}"); + let _ = std::fs::remove_dir_all(&base); + } + fn test_driver_with_extensions(extensions: LifecycleExtensionRegistry) -> VmDriver { let (events, _) = broadcast::channel(WATCH_BUFFER); VmDriver { diff --git a/crates/openshell-driver-vm/src/rootfs.rs b/crates/openshell-driver-vm/src/rootfs.rs index 9046913c9d..5e8de5f695 100644 --- a/crates/openshell-driver-vm/src/rootfs.rs +++ b/crates/openshell-driver-vm/src/rootfs.rs @@ -1,11 +1,12 @@ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 +use flate2::read::MultiGzDecoder; use std::fs; use std::fs::File; #[cfg(test)] use std::io::BufWriter; -use std::io::{Cursor, Read, Seek, SeekFrom, Write}; +use std::io::{BufRead, BufReader, Cursor, Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; use std::process::Command; use std::sync::atomic::{AtomicU64, Ordering}; @@ -13,6 +14,9 @@ use std::sync::atomic::{AtomicU64, Ordering}; const SUPERVISOR: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/openshell-sandbox.zst")); const UMOCI: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/umoci.zst")); const ROOTFS_VARIANT_MARKER: &str = ".openshell-rootfs-variant"; +/// Leading bytes of a gzip stream, used to recognize `.tar.gz`/`.tgz` input +/// without trusting the file name. +pub const GZIP_MAGIC: [u8; 2] = [0x1f, 0x8b]; const SANDBOX_GUEST_INIT_PATH: &str = "/srv/openshell-vm-sandbox-init.sh"; const SANDBOX_SUPERVISOR_PATH: &str = openshell_core::driver_utils::SUPERVISOR_CONTAINER_BINARY; const SANDBOX_UMOCI_PATH: &str = openshell_core::container_paths::VM_UMOCI_PATH; @@ -44,6 +48,12 @@ pub fn prepare_sandbox_rootfs_from_image_root( Ok(()) } +/// Extract a rootfs tarball, transparently decompressing gzip archives. +/// +/// Compression is detected from the magic bytes rather than the file name: +/// `--from` accepts `.tar.gz` and `.tgz`, but nothing guarantees a caller's +/// extension matches the bytes, and the archives this crate stages internally +/// carry no extension at all. pub fn extract_rootfs_archive_to(archive_path: &Path, dest: &Path) -> Result<(), String> { if dest.exists() { fs::remove_dir_all(dest) @@ -53,8 +63,20 @@ pub fn extract_rootfs_archive_to(archive_path: &Path, dest: &Path) -> Result<(), fs::create_dir_all(dest).map_err(|e| format!("create rootfs dir {}: {e}", dest.display()))?; let file = File::open(archive_path).map_err(|e| format!("open {}: {e}", archive_path.display()))?; - let mut archive = tar::Archive::new(file); - archive + let mut reader = BufReader::new(file); + let compressed = reader + .fill_buf() + .map_err(|e| format!("read {}: {e}", archive_path.display()))? + .starts_with(&GZIP_MAGIC); + if compressed { + unpack_tar_reader(MultiGzDecoder::new(reader), dest) + } else { + unpack_tar_reader(reader, dest) + } +} + +fn unpack_tar_reader(reader: impl Read, dest: &Path) -> Result<(), String> { + tar::Archive::new(reader) .unpack(dest) .map_err(|e| format!("extract rootfs tarball into {}: {e}", dest.display())) } @@ -1031,6 +1053,36 @@ mod tests { let _ = fs::remove_dir_all(&dir); } + /// `--from` accepts `.tar.gz` and `.tgz`, so extraction must recognize a + /// gzip stream instead of handing compressed bytes to the tar reader. + #[test] + fn extract_rootfs_archive_accepts_gzip_archives() { + let dir = unique_temp_dir(); + let rootfs = dir.join("rootfs"); + let extracted = dir.join("extracted"); + let archive = dir.join("rootfs.tar"); + let gz_archive = dir.join("rootfs.tar.gz"); + + fs::create_dir_all(rootfs.join("etc")).expect("create etc"); + fs::write(rootfs.join("etc/marker.txt"), "gzip-rootfs\n").expect("write marker"); + create_rootfs_archive_from_dir(&rootfs, &archive).expect("archive rootfs"); + + let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default()); + encoder + .write_all(&fs::read(&archive).expect("read archive")) + .expect("gzip archive"); + fs::write(&gz_archive, encoder.finish().expect("finish gzip")).expect("write gzip archive"); + + extract_rootfs_archive_to(&gz_archive, &extracted).expect("extract gzip rootfs"); + + assert_eq!( + fs::read_to_string(extracted.join("etc/marker.txt")).expect("read extracted marker"), + "gzip-rootfs\n" + ); + + let _ = fs::remove_dir_all(&dir); + } + #[cfg(unix)] #[test] fn create_rootfs_archive_preserves_broken_symlinks() { diff --git a/docs/reference/gateway-config.mdx b/docs/reference/gateway-config.mdx index 81c2411129..14cdb05ece 100644 --- a/docs/reference/gateway-config.mdx +++ b/docs/reference/gateway-config.mdx @@ -845,6 +845,8 @@ guest_tls_key = "/var/lib/openshell/guest-tls/client-key.pem" # request-scoped subdirectory per staging slot and removes it after use. # rootfs_tar_staging_dir = "/var/lib/openshell/vm/rootfs-tar-staging" # Largest rootfs tar archive the driver accepts, in bytes. Defaults to 10 GiB. +# Gzip archives are decompressed while staging, and the limit also bounds the +# expanded tar. # rootfs_tar_max_bytes = 10737418240 ``` diff --git a/docs/sandboxes/manage-sandboxes.mdx b/docs/sandboxes/manage-sandboxes.mdx index fffc6cf04c..40b35e4237 100644 --- a/docs/sandboxes/manage-sandboxes.mdx +++ b/docs/sandboxes/manage-sandboxes.mdx @@ -182,9 +182,14 @@ the gateway host's filesystem, the two must share a filesystem and run as the same user. Gateways using the Docker, Podman, or Kubernetes drivers reject rootfs tar sources. +Gzip-compressed archives (`.tar.gz`, `.tgz`) are decompressed while the gateway +stages them, so the sandbox sees the same filesystem either way. Compression is +detected from the archive contents, not the file name. + The gateway caps archive size (10 GiB by default, configurable with the VM driver's `rootfs_tar_max_bytes`), and reclaims an unused staging slot after 30 -minutes. +minutes. The cap applies to the expanded archive too: a compressed source that +decompresses past the limit is rejected. ## Reuse Workload Templates diff --git a/e2e/rust/tests/rootfs_tar.rs b/e2e/rust/tests/rootfs_tar.rs index e3d303654c..7f7164fb99 100644 --- a/e2e/rust/tests/rootfs_tar.rs +++ b/e2e/rust/tests/rootfs_tar.rs @@ -3,7 +3,8 @@ #![cfg(feature = "e2e")] -//! E2E test: create a sandbox from a flat rootfs tar archive. +//! E2E tests: create a sandbox from a flat rootfs tar archive, plain and +//! gzip-compressed. //! //! Prerequisites: //! - A running VM-backed openshell gateway with a default sandbox image configured @@ -13,6 +14,8 @@ use openshell_e2e::harness::container::ContainerEngine; use openshell_e2e::harness::output::strip_ansi; use openshell_e2e::harness::sandbox::SandboxGuard; +use std::path::{Path, PathBuf}; +use std::process::Command; const DOCKERFILE_CONTENT: &str = r#"FROM public.ecr.aws/docker/library/python:3.13-slim @@ -31,19 +34,16 @@ CMD ["sleep", "infinity"] const MARKER: &str = "rootfs-tar-e2e-marker"; -/// Build a Docker image, export its filesystem as a flat rootfs tar, then -/// create a sandbox from that tar and verify it contains the expected marker. -#[tokio::test] -async fn sandbox_from_rootfs_tar() { - let engine = ContainerEngine::from_env().expect("container engine available"); - let tmpdir = tempfile::tempdir().expect("create tmpdir"); - - // Step 1: Write a Dockerfile and build an image. - let dockerfile_path = tmpdir.path().join("Dockerfile"); +/// Build a Docker image and export its filesystem as a flat rootfs tar. +/// +/// `suffix` keeps the image tag and temporary container name unique so tests +/// exercising different archive formats can run concurrently. +fn export_rootfs_tar(engine: &ContainerEngine, tmpdir: &Path, suffix: &str) -> PathBuf { + let dockerfile_path = tmpdir.join("Dockerfile"); std::fs::write(&dockerfile_path, DOCKERFILE_CONTENT).expect("write Dockerfile"); let tag = format!( - "openshell/e2e-rootfs-tar-test:{}", + "openshell/e2e-rootfs-tar-test-{suffix}:{}", std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() @@ -54,7 +54,7 @@ async fn sandbox_from_rootfs_tar() { .command() .args(["build", "-t", &tag, "-f"]) .arg(&dockerfile_path) - .arg(tmpdir.path()) + .arg(tmpdir) .output() .expect("spawn docker build"); @@ -64,9 +64,12 @@ async fn sandbox_from_rootfs_tar() { String::from_utf8_lossy(&build_output.stderr) ); - // Step 2: Create a temporary container and export its filesystem as a - // flat rootfs tar (equivalent to `docker export`). - let container_name = format!("openshell-e2e-rootfs-export-{}", std::process::id()); + // Create a temporary container and export its filesystem as a flat rootfs + // tar (equivalent to `docker export`). + let container_name = format!( + "openshell-e2e-rootfs-export-{suffix}-{}", + std::process::id() + ); let create_output = engine .command() @@ -80,7 +83,7 @@ async fn sandbox_from_rootfs_tar() { String::from_utf8_lossy(&create_output.stderr) ); - let rootfs_tar_path = tmpdir.path().join("rootfs.tar"); + let rootfs_tar_path = tmpdir.join("rootfs.tar"); let export_output = engine .command() .args(["export", "-o"]) @@ -99,18 +102,57 @@ async fn sandbox_from_rootfs_tar() { let _ = engine.command().args(["rm", &container_name]).output(); let _ = engine.command().args(["rmi", &tag]).output(); - // Step 3: Create a sandbox from the rootfs tar. - let tar_str = rootfs_tar_path.to_str().expect("tar path is UTF-8"); - let mut guard = SandboxGuard::create(&["--from", tar_str, "--", "cat", "/etc/marker.txt"]) + rootfs_tar_path +} + +/// Create a sandbox from `archive` and assert the marker baked into the image +/// shows up in its output. +async fn assert_sandbox_from_archive(archive: &Path) { + let archive_str = archive.to_str().expect("archive path is UTF-8"); + let mut guard = SandboxGuard::create(&["--from", archive_str, "--", "cat", "/etc/marker.txt"]) .await .expect("sandbox create from rootfs tar"); - // Step 4: Verify the marker file content appears in the output. let clean_output = strip_ansi(&guard.create_output); assert!( clean_output.contains(MARKER), - "expected marker '{MARKER}' in sandbox output:\n{clean_output}" + "expected marker '{MARKER}' in sandbox output for {}:\n{clean_output}", + archive.display() ); guard.cleanup().await; } + +/// Build a Docker image, export its filesystem as a flat rootfs tar, then +/// create a sandbox from that tar and verify it contains the expected marker. +#[tokio::test] +async fn sandbox_from_rootfs_tar() { + let engine = ContainerEngine::from_env().expect("container engine available"); + let tmpdir = tempfile::tempdir().expect("create tmpdir"); + + let rootfs_tar_path = export_rootfs_tar(&engine, tmpdir.path(), "plain"); + + assert_sandbox_from_archive(&rootfs_tar_path).await; +} + +/// The CLI advertises `.tar.gz` and `.tgz` sources, so a gzip-compressed +/// export has to reach the sandbox the same way a plain tar does. +#[tokio::test] +async fn sandbox_from_gzipped_rootfs_tar() { + let engine = ContainerEngine::from_env().expect("container engine available"); + let tmpdir = tempfile::tempdir().expect("create tmpdir"); + + let rootfs_tar_path = export_rootfs_tar(&engine, tmpdir.path(), "gzip"); + let gzipped_path = tmpdir.path().join("rootfs.tar.gz"); + let gzipped = std::fs::File::create(&gzipped_path).expect("create gzip archive"); + let gzip_status = Command::new("gzip") + .arg("-c") + .arg(&rootfs_tar_path) + .stdout(gzipped) + .status() + .expect("spawn gzip"); + assert!(gzip_status.success(), "gzip failed: {gzip_status}"); + std::fs::remove_file(&rootfs_tar_path).expect("remove uncompressed archive"); + + assert_sandbox_from_archive(&gzipped_path).await; +}