mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-13 16:05:00 +00:00
* feat: add sandboxed docker v2 runtime via '# docker <image>' Run a container image as a subprogram of the job's own nsjail sandbox: extract the image rootfs with podman (rootless) and run it chrooted inside the job's nsjail, so the container inherits the job's confinement and is safe under nsjail / for untrusted code. Selected by '# docker <image>'; a bare '# docker' keeps the v1 (dind) path untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: default to daemonless docker (drop dind from compose, allow docker on cloud) docker-compose no longer ships the dind sidecar (v2 is daemonless: podman + nsjail in the worker); removed the dind service, DOCKER_HOST env, depends_on and volume. Removed the language-picker guard that blocked Docker scripts on the multi-tenant platform, now that v2 makes docker safe to run sandboxed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: select sandboxed container via # sandbox <image>; add pull policy + size guards - Surface moved from '# docker <image>' to '# sandbox <image>' (groups under the sandbox annotation; '# docker' stays v1-only, '# sandbox' stays nsjail-bash). - SANDBOX_IMAGE_PULL_POLICY (default 'newer') so moving tags don't go stale. - SANDBOX_IMAGE_MAX_SIZE_MB rejects oversized images before extraction. - SANDBOX_IMAGE_CACHE_MAX_MB best-effort LRU eviction of podman's image store. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(sandbox): support # volume, honor nsjail tmp instance settings, v2 docker template - Thread shared_mount into the sandbox container nsjail config so '# volume' mounts (and the same-worker /tmp/shared folder) apply inside the container. - Use resolve_nsjail_tmp_mount_block for the container's /tmp so it honors the same nsjail_tmp_backing / nsjail_tmpfs_size_mb instance settings as other nsjail jobs. - docker-compose comment + the editor's Docker template now use '# sandbox <image>'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(sandbox): make image size/cache/pull-policy UI instance settings Convert SANDBOX_IMAGE_* from worker env vars to DB-backed instance settings (sandbox_image_max_size_mb, sandbox_image_cache_max_mb, sandbox_image_pull_policy), hot-reloaded via the same mechanism as nsjail_tmpfs_size_mb and configurable in #superadmin-settings. No worker restart needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(sandbox): windmill-managed registry — default registry + private auth Two new instance settings: - sandbox_image_default_registry: prepended to unqualified image refs (alpine -> <registry>/alpine); fully-qualified refs untouched. - sandbox_registry_auth: docker/podman auth.json blob written to a per-job authfile (0600, removed with the job) and passed to podman --authfile for private registries. Both hot-reloaded and configurable in #superadmin-settings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(sandbox): protobuf-safe proto_str escaper, atomic 0600 authfile, registry tests Addresses local-review P2s: proto_str now emits valid protobuf octal escapes for control/non-ASCII bytes (not Rust \u{..} that nsjail would reject); the registry authfile is created 0600 atomically (no world-readable window); add a registry_qualified table test + a non-ASCII proto_str case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(sandbox): P0 — deliver image env via nsjail envar:, never the launcher process env CI review (P0): the image's OCI Env (attacker-controlled keys+values) was applied to the nsjail launcher process via .envs(), so a hostile image could set LD_PRELOAD/ LD_LIBRARY_PATH/LD_AUDIT on nsjail itself and execute code as the worker outside the jail. Now the image env is rendered as proto-escaped 'envar:' directives (child-only) and nsjail's process env carries only windmill-trusted keys (reserved vars + proxy). Also: warn instead of silently bypassing the size guard on inspect failure; reset the eviction guard via a Drop guard (no stuck flag on panic/early-return). +render_envars test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(sandbox): P0 symlink-write escape via rootfs script; P1 redact registry-auth logging CI review: - P0 (Codex): the body was written into the image-controlled rootfs as .windmill_docker_main.sh via write_file (follows symlinks) — a hostile image could plant that path as a symlink to a host file and capture the worker's write before nsjail starts. Now the body is passed straight to 'sh -c <body> sh <args>'; no file is written into the rootfs at all. - P1 (Codex): sandbox_registry_auth flowed through the generic setting loader which logs the value (raw auth.json credentials). Replaced with a secret-aware reload that loads directly and logs only a redacted 'configured=' message. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(sandbox): redact sandbox_registry_auth in instance-settings write log too The settings API also logs 'Set global setting <key> to <value>' via format_setting_value; add sandbox_registry_auth to SENSITIVE_SETTINGS so the credential is redacted there as well as on reload. * fix(sandbox): don't silently disable cache eviction on podman images parse error Re-review (cubic/Claude P2): serde_json::from_slice(...).unwrap_or_default() meant any parse hiccup (e.g. podman omitting Size/Created via omitempty for a zero value, or schema drift) silently degraded to an empty Vec and disabled eviction with no log. Now Size/Created are #[serde(default)] (a missing omitempty key -> 0, not a whole-array parse failure) and a real parse error warns + breaks instead of being swallowed. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
116 lines
3.0 KiB
Rust
116 lines
3.0 KiB
Rust
#[cfg(all(feature = "enterprise", feature = "bigquery"))]
|
|
mod bigquery_executor;
|
|
#[cfg(all(feature = "enterprise", feature = "mssql"))]
|
|
mod mssql_executor;
|
|
#[cfg(feature = "enterprise")]
|
|
mod snowflake_executor;
|
|
|
|
mod agent_workers;
|
|
#[cfg(feature = "python")]
|
|
mod ansible_executor;
|
|
mod bash_executor;
|
|
mod pwsh_executor;
|
|
|
|
#[cfg(feature = "java")]
|
|
mod java_executor;
|
|
|
|
#[cfg(feature = "ruby")]
|
|
mod ruby_executor;
|
|
|
|
#[cfg(feature = "rlang")]
|
|
mod r_executor;
|
|
|
|
mod ai;
|
|
mod ai_executor;
|
|
mod bun_executor;
|
|
pub mod common;
|
|
mod config;
|
|
mod csharp_executor;
|
|
|
|
#[cfg(feature = "private")]
|
|
mod dedicated_worker_ee;
|
|
mod dedicated_worker_oss;
|
|
mod deno_executor;
|
|
mod docker_v2;
|
|
#[cfg(feature = "duckdb")]
|
|
mod duckdb_executor;
|
|
mod global_cache;
|
|
mod go_executor;
|
|
mod graphql_executor;
|
|
mod handle_child;
|
|
pub mod job_logger;
|
|
#[cfg(feature = "private")]
|
|
pub mod job_logger_ee;
|
|
mod job_logger_oss;
|
|
mod js_eval;
|
|
pub mod memory_common;
|
|
#[cfg(feature = "private")]
|
|
pub mod memory_ee;
|
|
pub mod memory_oss;
|
|
#[cfg(feature = "mysql")]
|
|
mod mysql_executor;
|
|
#[cfg(feature = "nu")]
|
|
mod nu_executor;
|
|
#[cfg(feature = "oracledb")]
|
|
mod oracledb_executor;
|
|
#[cfg(feature = "private")]
|
|
pub mod otel_ee;
|
|
mod otel_oss;
|
|
#[cfg(all(feature = "private", feature = "enterprise"))]
|
|
mod otel_tracing_proxy_ee;
|
|
mod otel_tracing_proxy_oss;
|
|
pub mod pg_executor;
|
|
mod pg_raw_output;
|
|
#[cfg(feature = "php")]
|
|
mod php_executor;
|
|
mod prepare_deps;
|
|
#[cfg(feature = "python")]
|
|
mod python_executor;
|
|
#[cfg(feature = "python")]
|
|
mod python_versions;
|
|
pub mod result_processor;
|
|
#[cfg(feature = "rust")]
|
|
mod rust_executor;
|
|
mod sanitized_sql_params;
|
|
mod schema;
|
|
mod sql_s3_input;
|
|
pub mod sql_utils;
|
|
mod universal_pkg_installer;
|
|
#[cfg(feature = "private")]
|
|
mod volume_ee;
|
|
mod volume_oss;
|
|
pub mod wac_executor;
|
|
mod worker;
|
|
mod worker_flow;
|
|
mod worker_lockfiles;
|
|
mod worker_utils;
|
|
|
|
#[cfg(all(feature = "private", feature = "enterprise"))]
|
|
pub use otel_tracing_proxy_ee::start_jobs_otel_tracing;
|
|
#[cfg(all(feature = "private", feature = "enterprise", feature = "deno_core"))]
|
|
pub use otel_tracing_proxy_ee::{load_internal_otel_exporter, DENO_OTEL_INITIALIZED};
|
|
pub use worker::*;
|
|
|
|
pub use bun_executor::{
|
|
build_loader, compute_bundle_local_and_remote_path, ensure_bundle_output_exists,
|
|
generate_bun_bundle, get_common_bun_proc_envs, install_bun_lockfile, prebundle_bun_script,
|
|
prepare_job_dir, LoaderMode, BUN_DEDICATED_WORKER_ARGS, RELATIVE_BUN_BUILDER,
|
|
RELATIVE_BUN_LOADER,
|
|
};
|
|
#[cfg(any(feature = "private", test))]
|
|
pub use bun_executor::{
|
|
compute_ts_codegen, generate_multi_script_wrapper, TsScriptCodegen, TsScriptEntry,
|
|
};
|
|
#[cfg(any(feature = "private", test))]
|
|
pub use deno_executor::generate_dedicated_worker_wrapper as generate_deno_dedicated_worker_wrapper;
|
|
pub use deno_executor::{generate_deno_lock, DENO_UNSTABLE_ARGS};
|
|
pub use prepare_deps::run_prepare_deps_cli;
|
|
|
|
#[cfg(all(feature = "python", any(feature = "private", test)))]
|
|
pub use python_executor::{
|
|
compute_py_codegen, generate_multi_script_wrapper as generate_py_multi_script_wrapper,
|
|
PyScriptCodegen, PyScriptEntry,
|
|
};
|
|
#[cfg(feature = "python")]
|
|
pub use python_versions::PyV;
|