mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-08 00:03:07 +00:00
feat(nsjail): make tmpfs size configurable via instance setting (#9261)
* feat(nsjail): make tmpfs size configurable via instance setting Adds a new `nsjail_tmpfs_size_mb` instance setting that overrides the size of the `/tmp` tmpfs mount inside the nsjail sandbox across all languages. When unset, the existing per-language defaults (500MB or 800MB) continue to apply, so no behavior change for existing deployments. The setting is exposed under Settings → Jobs and is read at job execution time, so changes take effect on the next job without a restart. Fixes WIN-1963 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(nsjail): unify default tmpfs size to 800MB Previously each executor passed its own per-language default (500MB or 800MB) to resolve_nsjail_tmpfs_size. Unify on a single DEFAULT_NSJAIL_TMPFS_SIZE_BYTES constant (800MB) so the placeholder behavior is consistent across languages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(nsjail): resolve tmpfs size outside ruby download closure The download.ruby config render runs inside a sync closure passed to par_install_language_dependencies_seq, so `.await` on resolve_nsjail_tmpfs_size() was a compile error under the `ruby` feature. Resolve the size once before the closure and capture the string instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(nsjail): rename resolver to *_bytes and clarify fallback Addresses CI review feedback: - Rename `resolve_nsjail_tmpfs_size` to `resolve_nsjail_tmpfs_size_bytes` so the returned unit is unambiguous at the call site (cubic P2). - Fix the `NSJAIL_TMPFS_SIZE_MB` doc comment that still said "per-language default" — there is no per-language fallback anymore, all unset values resolve to the unified 800MB `DEFAULT_NSJAIL_TMPFS_SIZE_BYTES` (codex/pi P2). - Expand the resolver doc to call out that `Some(0)` and negative values also fall back, since the match arm is `Some(mb) if mb > 0`. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
271f0cbd08
commit
9111f8908d
+13
-11
@@ -51,14 +51,14 @@ use windmill_common::{
|
||||
JOB_DEFAULT_TIMEOUT_SECS_SETTING, JOB_ISOLATION_SETTING, JWT_SECRET_SETTING,
|
||||
KEEP_JOB_DIR_SETTING, LICENSE_KEY_SETTING, MAVEN_REPOS_SETTING, MAVEN_SETTINGS_XML_SETTING,
|
||||
MONITOR_LOGS_ON_OBJECT_STORE_SETTING, NO_DEFAULT_MAVEN_SETTING,
|
||||
NPM_CONFIG_REGISTRY_SETTING, NUGET_CONFIG_SETTING, OAUTH_SETTING, OTEL_SETTING,
|
||||
OTEL_TRACING_PROXY_SETTING, PIP_INDEX_URL_SETTING, POWERSHELL_REPO_PAT_SETTING,
|
||||
POWERSHELL_REPO_URL_SETTING, PREVIEW_TAGS_OVERRIDE_SETTING, REQUEST_SIZE_LIMIT_SETTING,
|
||||
REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING, RESTART_COORDINATION_SETTING,
|
||||
RETENTION_PERIOD_SECS_SETTING, RUBY_REPOS_SETTING, SAML_METADATA_SETTING,
|
||||
SCIM_TOKEN_SETTING, SMTP_SETTING, STORE_AUDIT_LOGS_S3_SETTING, TEAMS_SETTING,
|
||||
TIMEOUT_WAIT_RESULT_SETTING, UV_EXCLUDE_NEWER_SETTING, UV_INDEX_STRATEGY_SETTING,
|
||||
WORKSPACE_REGISTRIES_SETTING,
|
||||
NPM_CONFIG_REGISTRY_SETTING, NSJAIL_TMPFS_SIZE_MB_SETTING, NUGET_CONFIG_SETTING,
|
||||
OAUTH_SETTING, OTEL_SETTING, OTEL_TRACING_PROXY_SETTING, PIP_INDEX_URL_SETTING,
|
||||
POWERSHELL_REPO_PAT_SETTING, POWERSHELL_REPO_URL_SETTING, PREVIEW_TAGS_OVERRIDE_SETTING,
|
||||
REQUEST_SIZE_LIMIT_SETTING, REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING,
|
||||
RESTART_COORDINATION_SETTING, RETENTION_PERIOD_SECS_SETTING, RUBY_REPOS_SETTING,
|
||||
SAML_METADATA_SETTING, SCIM_TOKEN_SETTING, SMTP_SETTING, STORE_AUDIT_LOGS_S3_SETTING,
|
||||
TEAMS_SETTING, TIMEOUT_WAIT_RESULT_SETTING, UV_EXCLUDE_NEWER_SETTING,
|
||||
UV_INDEX_STRATEGY_SETTING, WORKSPACE_REGISTRIES_SETTING,
|
||||
},
|
||||
scripts::ScriptLang,
|
||||
stats_oss::schedule_stats,
|
||||
@@ -127,9 +127,10 @@ use crate::monitor::{
|
||||
reload_http_route_workspaced_route_setting, reload_hub_api_secret_setting,
|
||||
reload_hub_base_url_setting, reload_instance_events_webhook_setting,
|
||||
reload_job_default_timeout_setting, reload_job_isolation_setting, reload_jwt_secret_setting,
|
||||
reload_license_key, reload_npm_config_registry_setting, reload_otel_tracing_proxy_setting,
|
||||
reload_pip_index_url_setting, reload_retention_period_setting, reload_scim_token_setting,
|
||||
reload_smtp_config, reload_store_audit_logs_s3_setting, reload_uv_exclude_newer_setting,
|
||||
reload_license_key, reload_npm_config_registry_setting, reload_nsjail_tmpfs_size_setting,
|
||||
reload_otel_tracing_proxy_setting, reload_pip_index_url_setting,
|
||||
reload_retention_period_setting, reload_scim_token_setting, reload_smtp_config,
|
||||
reload_store_audit_logs_s3_setting, reload_uv_exclude_newer_setting,
|
||||
reload_uv_index_strategy_setting, reload_worker_config, MonitorIteration,
|
||||
};
|
||||
|
||||
@@ -1782,6 +1783,7 @@ async fn process_notify_event(
|
||||
STORE_AUDIT_LOGS_S3_SETTING => reload_store_audit_logs_s3_setting(conn).await,
|
||||
JOB_DEFAULT_TIMEOUT_SECS_SETTING => reload_job_default_timeout_setting(conn).await,
|
||||
JOB_ISOLATION_SETTING => reload_job_isolation_setting(conn).await,
|
||||
NSJAIL_TMPFS_SIZE_MB_SETTING => reload_nsjail_tmpfs_size_setting(conn).await,
|
||||
#[cfg(feature = "parquet")]
|
||||
OBJECT_STORE_CONFIG_SETTING => {
|
||||
if !disable_s3_store {
|
||||
|
||||
+21
-9
@@ -62,12 +62,12 @@ use windmill_common::{
|
||||
HUB_BASE_URL_SETTING, INSTANCE_PYTHON_VERSION_SETTING, JOB_DEFAULT_TIMEOUT_SECS_SETTING,
|
||||
JOB_ISOLATION_SETTING, JWT_SECRET_SETTING, KEEP_JOB_DIR_SETTING, LICENSE_KEY_SETTING,
|
||||
MONITOR_LOGS_ON_OBJECT_STORE_SETTING, NPMRC_SETTING, NPM_CONFIG_REGISTRY_SETTING,
|
||||
NUGET_CONFIG_SETTING, OTEL_SETTING, OTEL_TRACING_PROXY_SETTING, PIP_INDEX_URL_SETTING,
|
||||
POWERSHELL_REPO_PAT_SETTING, POWERSHELL_REPO_URL_SETTING, PREVIEW_TAGS_OVERRIDE_SETTING,
|
||||
REQUEST_SIZE_LIMIT_SETTING, REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING,
|
||||
RETENTION_PERIOD_SECS_SETTING, SAML_METADATA_SETTING, SCIM_TOKEN_SETTING,
|
||||
STORE_AUDIT_LOGS_S3_SETTING, TIMEOUT_WAIT_RESULT_SETTING, UV_EXCLUDE_NEWER_SETTING,
|
||||
UV_INDEX_STRATEGY_SETTING,
|
||||
NSJAIL_TMPFS_SIZE_MB_SETTING, NUGET_CONFIG_SETTING, OTEL_SETTING,
|
||||
OTEL_TRACING_PROXY_SETTING, PIP_INDEX_URL_SETTING, POWERSHELL_REPO_PAT_SETTING,
|
||||
POWERSHELL_REPO_URL_SETTING, PREVIEW_TAGS_OVERRIDE_SETTING, REQUEST_SIZE_LIMIT_SETTING,
|
||||
REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING, RETENTION_PERIOD_SECS_SETTING,
|
||||
SAML_METADATA_SETTING, SCIM_TOKEN_SETTING, STORE_AUDIT_LOGS_S3_SETTING,
|
||||
TIMEOUT_WAIT_RESULT_SETTING, UV_EXCLUDE_NEWER_SETTING, UV_INDEX_STRATEGY_SETTING,
|
||||
},
|
||||
indexer::load_indexer_config,
|
||||
jwt::JWT_SECRET,
|
||||
@@ -106,9 +106,10 @@ use windmill_worker::{
|
||||
OtelTracingProxySettings, SameWorkerSender, WorkspaceRegistryMap, BUNFIG_INSTALL_SCOPES,
|
||||
BUN_INSTALL_MIN_RELEASE_AGE, CARGO_REGISTRIES, INSTANCE_PYTHON_VERSION, JAVA_HOME_DIR,
|
||||
JOB_DEFAULT_TIMEOUT, JOB_ISOLATION, KEEP_JOB_DIR, MAVEN_REPOS, MAVEN_SETTINGS_XML,
|
||||
NO_DEFAULT_MAVEN, NPMRC, NPM_CONFIG_REGISTRY, NSJAIL_AVAILABLE, NUGET_CONFIG,
|
||||
OTEL_TRACING_PROXY_SETTINGS, PIP_EXTRA_INDEX_URL, PIP_INDEX_URL, POWERSHELL_REPO_PAT,
|
||||
POWERSHELL_REPO_URL, UNSHARE_PATH, UV_EXCLUDE_NEWER, UV_INDEX_STRATEGY, WORKSPACE_REGISTRIES,
|
||||
NO_DEFAULT_MAVEN, NPMRC, NPM_CONFIG_REGISTRY, NSJAIL_AVAILABLE, NSJAIL_TMPFS_SIZE_MB,
|
||||
NUGET_CONFIG, OTEL_TRACING_PROXY_SETTINGS, PIP_EXTRA_INDEX_URL, PIP_INDEX_URL,
|
||||
POWERSHELL_REPO_PAT, POWERSHELL_REPO_URL, UNSHARE_PATH, UV_EXCLUDE_NEWER, UV_INDEX_STRATEGY,
|
||||
WORKSPACE_REGISTRIES,
|
||||
};
|
||||
|
||||
#[cfg(feature = "parquet")]
|
||||
@@ -384,6 +385,7 @@ pub async fn initial_load(
|
||||
if worker_mode {
|
||||
reload_job_default_timeout_setting(&conn).await;
|
||||
reload_job_isolation_setting(&conn).await;
|
||||
reload_nsjail_tmpfs_size_setting(&conn).await;
|
||||
reload_extra_pip_index_url_setting(&conn).await;
|
||||
reload_pip_index_url_setting(&conn).await;
|
||||
reload_uv_index_strategy_setting(&conn).await;
|
||||
@@ -1885,6 +1887,16 @@ pub async fn reload_job_default_timeout_setting(conn: &Connection) {
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn reload_nsjail_tmpfs_size_setting(conn: &Connection) {
|
||||
reload_option_setting_with_tracing(
|
||||
conn,
|
||||
NSJAIL_TMPFS_SIZE_MB_SETTING,
|
||||
"NSJAIL_TMPFS_SIZE_MB",
|
||||
NSJAIL_TMPFS_SIZE_MB.clone(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn reload_job_isolation_setting(conn: &Connection) {
|
||||
let value =
|
||||
match load_value_from_global_settings_with_conn(conn, JOB_ISOLATION_SETTING, true).await {
|
||||
|
||||
@@ -53,6 +53,7 @@ pub const EXPOSE_DEBUG_METRICS_SETTING: &str = "expose_debug_metrics";
|
||||
pub const KEEP_JOB_DIR_SETTING: &str = "keep_job_dir";
|
||||
pub const REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING: &str = "require_preexisting_user_for_oauth";
|
||||
pub const JOB_ISOLATION_SETTING: &str = "job_isolation";
|
||||
pub const NSJAIL_TMPFS_SIZE_MB_SETTING: &str = "nsjail_tmpfs_size_mb";
|
||||
pub const OBJECT_STORE_CONFIG_SETTING: &str = "object_store_cache_config";
|
||||
pub const HUB_API_SECRET_SETTING: &str = "hub_api_secret";
|
||||
|
||||
|
||||
@@ -221,6 +221,8 @@ pub struct GlobalSettings {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub job_default_timeout: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub nsjail_tmpfs_size_mb: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub bun_install_min_release_age: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub uv_exclude_newer: Option<i64>,
|
||||
|
||||
@@ -90,7 +90,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -53,7 +53,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -70,7 +70,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=800000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -72,7 +72,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=800000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -64,7 +64,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -61,7 +61,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=800000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -55,7 +55,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=800000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -68,7 +68,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=800000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -58,7 +58,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
mount {
|
||||
|
||||
@@ -55,7 +55,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ mount {
|
||||
dst: "/tmp"
|
||||
fstype: "tmpfs"
|
||||
rw: true
|
||||
options: "size=500000000"
|
||||
options: "size={NSJAIL_TMPFS_SIZE}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ use crate::{
|
||||
bash_executor::BIN_BASH,
|
||||
common::{
|
||||
build_command_with_isolation, check_executor_binary_exists, get_reserved_variables,
|
||||
read_and_check_result, resolve_nsjail_timeout, start_child_process, transform_json,
|
||||
OccupancyMetrics,
|
||||
read_and_check_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes,
|
||||
start_child_process, transform_json, OccupancyMetrics,
|
||||
},
|
||||
handle_child::handle_child,
|
||||
is_sandboxing_enabled,
|
||||
@@ -1456,6 +1456,10 @@ mount {{
|
||||
"{ADDITIONAL_PYTHON_PATHS}",
|
||||
additional_python_paths_folders.as_str(),
|
||||
)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
} else {
|
||||
|
||||
@@ -41,8 +41,8 @@ use crate::handle_child::run_future_with_polling_update_job_poller;
|
||||
use crate::{
|
||||
common::{
|
||||
build_args_map, build_command_with_isolation, get_reserved_variables, read_file,
|
||||
read_file_content, resolve_nsjail_timeout, start_child_process, OccupancyMetrics,
|
||||
DEV_CONF_NSJAIL,
|
||||
read_file_content, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::handle_child,
|
||||
@@ -215,6 +215,10 @@ exit $exit_status
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut cmd_args = vec![
|
||||
|
||||
@@ -16,8 +16,8 @@ use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables,
|
||||
parse_npm_config, read_file, read_file_content, read_result, resolve_nsjail_timeout,
|
||||
start_child_process, write_file_binary, MaybeLock, OccupancyMetrics, StreamNotifier,
|
||||
DEV_CONF_NSJAIL,
|
||||
resolve_nsjail_tmpfs_size_bytes, start_child_process, write_file_binary, MaybeLock,
|
||||
OccupancyMetrics, StreamNotifier, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::handle_child,
|
||||
@@ -2185,6 +2185,10 @@ try {{
|
||||
)
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ use windmill_common::{variables, DB};
|
||||
use tokio::{io::AsyncWriteExt, time::Instant};
|
||||
|
||||
use crate::agent_workers::UPDATE_PING_URL;
|
||||
use crate::{JOB_DEFAULT_TIMEOUT, MAX_RESULT_SIZE, MAX_TIMEOUT_DURATION, PATH_ENV};
|
||||
use crate::{
|
||||
JOB_DEFAULT_TIMEOUT, MAX_RESULT_SIZE, MAX_TIMEOUT_DURATION, NSJAIL_TMPFS_SIZE_MB, PATH_ENV,
|
||||
};
|
||||
use windmill_common::client::AuthedClient;
|
||||
|
||||
/// Additional nsjail config for development. Currently used for nix flake.
|
||||
@@ -1006,6 +1008,21 @@ pub async fn resolve_nsjail_timeout(
|
||||
(duration.as_secs() + 15).to_string()
|
||||
}
|
||||
|
||||
/// Default size (in bytes) of the `/tmp` tmpfs mount inside nsjail sandboxes,
|
||||
/// used when the `nsjail_tmpfs_size_mb` instance setting is unset.
|
||||
pub const DEFAULT_NSJAIL_TMPFS_SIZE_BYTES: u64 = 800_000_000;
|
||||
|
||||
/// Resolve the tmpfs `size=` value (in bytes, formatted for the nsjail proto)
|
||||
/// for the `/tmp` tmpfs mount. When the `nsjail_tmpfs_size_mb` instance setting
|
||||
/// is `None`, `Some(0)`, or negative, falls back to
|
||||
/// [`DEFAULT_NSJAIL_TMPFS_SIZE_BYTES`].
|
||||
pub async fn resolve_nsjail_tmpfs_size_bytes() -> String {
|
||||
match *NSJAIL_TMPFS_SIZE_MB.read().await {
|
||||
Some(mb) if mb > 0 => ((mb as u64).saturating_mul(1_000_000)).to_string(),
|
||||
_ => DEFAULT_NSJAIL_TMPFS_SIZE_BYTES.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn hash_args(
|
||||
#[allow(unused)] db: &DB,
|
||||
#[allow(unused)] client: &AuthedClient,
|
||||
|
||||
@@ -27,8 +27,8 @@ use windmill_queue::CanceledBy;
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, check_executor_binary_exists, create_args_and_out_file,
|
||||
get_reserved_variables, read_result, resolve_nsjail_timeout, start_child_process,
|
||||
DEV_CONF_NSJAIL,
|
||||
get_reserved_variables, read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes,
|
||||
start_child_process, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::handle_child,
|
||||
@@ -603,6 +603,10 @@ pub async fn handle_csharp_job(
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -22,8 +22,8 @@ use windmill_queue::{append_logs, CanceledBy, MiniPulledJob};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, capitalize, create_args_and_out_file, get_reserved_variables,
|
||||
read_result, resolve_nsjail_timeout, start_child_process, OccupancyMetrics,
|
||||
DEV_CONF_NSJAIL,
|
||||
read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
},
|
||||
handle_child::handle_child,
|
||||
is_sandboxing_enabled, read_ee_registry, DISABLE_NUSER, GOPRIVATE, GOPROXY, GO_BIN_CACHE_DIR,
|
||||
@@ -351,6 +351,10 @@ func Run(req Req) (interface{{}}, error){{
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -23,7 +23,8 @@ use windmill_queue::{append_logs, CanceledBy, MiniPulledJob};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables,
|
||||
read_result, resolve_nsjail_timeout, start_child_process, OccupancyMetrics,
|
||||
read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
OccupancyMetrics,
|
||||
},
|
||||
handle_child, is_sandboxing_enabled, read_ee_registry_bool_with_workspace_override,
|
||||
read_ee_registry_with_workspace_override,
|
||||
@@ -669,6 +670,10 @@ async fn run<'a>(
|
||||
.replace("{SHARED_MOUNT}", &shared_mount)
|
||||
// .replace("{CACHED_TARGET}", &shared_mount)
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -14,8 +14,8 @@ use windmill_queue::{append_logs, CanceledBy, MiniPulledJob};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables,
|
||||
read_result, resolve_nsjail_timeout, start_child_process, OccupancyMetrics,
|
||||
DEV_CONF_NSJAIL,
|
||||
read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang, handle_child, is_sandboxing_enabled, DISABLE_NUSER, NSJAIL_PATH,
|
||||
PATH_ENV, TRACING_PROXY_CA_CERT_PATH,
|
||||
@@ -258,6 +258,10 @@ async fn run<'a>(
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -20,8 +20,8 @@ use windmill_queue::{append_logs, CanceledBy};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, check_executor_binary_exists, create_args_and_out_file,
|
||||
get_reserved_variables, read_result, resolve_nsjail_timeout, start_child_process,
|
||||
MaybeLock, OccupancyMetrics,
|
||||
get_reserved_variables, read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes,
|
||||
start_child_process, MaybeLock, OccupancyMetrics,
|
||||
},
|
||||
handle_child::handle_child,
|
||||
is_sandboxing_enabled, COMPOSER_CACHE_DIR, COMPOSER_PATH, DISABLE_NUSER, NSJAIL_PATH, PHP_PATH,
|
||||
@@ -425,6 +425,10 @@ try {{
|
||||
.replace("{JOB_DIR}", job_dir)
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ lazy_static::lazy_static! {
|
||||
use crate::{
|
||||
common::{
|
||||
build_args_map, build_command_with_isolation, get_reserved_variables, read_file,
|
||||
read_file_content, resolve_nsjail_timeout, start_child_process, MaybeLock,
|
||||
OccupancyMetrics,
|
||||
read_file_content, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
MaybeLock, OccupancyMetrics,
|
||||
},
|
||||
handle_child::handle_child,
|
||||
is_sandboxing_enabled, read_ee_registry_with_workspace_override, DISABLE_NUSER, HOME_ENV,
|
||||
@@ -682,6 +682,10 @@ $env:PSModulePath = \"{};$PSModulePathBackup\"",
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace("{CACHE_DIR}", &*POWERSHELL_CACHE_DIR)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let cmd_args = vec![
|
||||
|
||||
@@ -146,8 +146,8 @@ use windmill_object_store::OBJECT_STORE_SETTINGS;
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables, read_file,
|
||||
read_result, resolve_nsjail_timeout, start_child_process, OccupancyMetrics, StreamNotifier,
|
||||
DEV_CONF_NSJAIL,
|
||||
read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
OccupancyMetrics, StreamNotifier, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::handle_child,
|
||||
@@ -1023,6 +1023,10 @@ mount {{
|
||||
)
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
} else {
|
||||
@@ -2043,6 +2047,10 @@ async fn spawn_uv_install(
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.as_str(),
|
||||
)?;
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ use windmill_queue::{append_logs, CanceledBy, MiniPulledJob};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables,
|
||||
read_result, start_child_process, OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
read_result, resolve_nsjail_tmpfs_size_bytes, start_child_process, OccupancyMetrics,
|
||||
DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::{self},
|
||||
@@ -580,6 +581,10 @@ async fn run<'a>(
|
||||
.replace("{R_CACHE_DIR}", &*R_CACHE_DIR)
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string()),
|
||||
)?;
|
||||
let mut cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -23,8 +23,8 @@ use windmill_queue::{append_logs, CanceledBy, MiniPulledJob};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables,
|
||||
read_result, resolve_nsjail_timeout, start_child_process, OccupancyMetrics,
|
||||
DEV_CONF_NSJAIL,
|
||||
read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes, start_child_process,
|
||||
OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::{self},
|
||||
@@ -619,6 +619,7 @@ async fn install<'a>(
|
||||
envs.clone(),
|
||||
get_reserved_variables(job, &client.token, conn, parent_runnable_path.clone()).await?,
|
||||
);
|
||||
let nsjail_tmpfs_size = resolve_nsjail_tmpfs_size_bytes().await;
|
||||
par_install_language_dependencies_seq(
|
||||
InstallDeps::Flat(deps.clone()),
|
||||
"ruby",
|
||||
@@ -638,6 +639,7 @@ async fn install<'a>(
|
||||
.replace("{TARGET}", &dependency.path)
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("{NSJAIL_TMPFS_SIZE}", &nsjail_tmpfs_size)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL), // .replace("{BUILD}", &build_dir),
|
||||
)?;
|
||||
let mut cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
@@ -810,6 +812,7 @@ mount {{
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace("{NSJAIL_TMPFS_SIZE}", &resolve_nsjail_tmpfs_size_bytes().await)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -23,8 +23,8 @@ use windmill_queue::{append_logs, CanceledBy};
|
||||
use crate::{
|
||||
common::{
|
||||
build_command_with_isolation, check_executor_binary_exists, create_args_and_out_file,
|
||||
get_reserved_variables, read_result, resolve_nsjail_timeout, start_child_process,
|
||||
OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
get_reserved_variables, read_result, resolve_nsjail_timeout, resolve_nsjail_tmpfs_size_bytes,
|
||||
start_child_process, OccupancyMetrics, DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
handle_child::handle_child,
|
||||
@@ -480,6 +480,10 @@ pub async fn build_rust_crate(
|
||||
.replace("{RUSTUP_HOME}", RUSTUP_HOME.as_str())
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{BUILD}", &build_dir),
|
||||
)?;
|
||||
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
@@ -701,6 +705,10 @@ pub async fn handle_rust_job(
|
||||
.replace("{TRACING_PROXY_CA_CERT_PATH}", &*TRACING_PROXY_CA_CERT_PATH)
|
||||
.replace("#{DEV}", DEV_CONF_NSJAIL)
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace(
|
||||
"{NSJAIL_TMPFS_SIZE}",
|
||||
&resolve_nsjail_tmpfs_size_bytes().await,
|
||||
)
|
||||
.replace("{TIMEOUT}", &nsjail_timeout),
|
||||
)?;
|
||||
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
|
||||
@@ -681,6 +681,13 @@ lazy_static::lazy_static! {
|
||||
pub static ref FLOW_RUNNER_RUNNING: Mutex<bool> = Mutex::new(false);
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
/// Optional override for the size of the `/tmp` tmpfs mount in nsjail sandboxes (in megabytes).
|
||||
/// When `None` (or non-positive), executors fall back to the unified
|
||||
/// `DEFAULT_NSJAIL_TMPFS_SIZE_BYTES` (800MB).
|
||||
pub static ref NSJAIL_TMPFS_SIZE_MB: Arc<RwLock<Option<i64>>> = Arc::new(RwLock::new(None));
|
||||
}
|
||||
|
||||
pub fn sleep_queue() -> u64 {
|
||||
if NATIVE_MODE_RESOLVED.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
300
|
||||
|
||||
@@ -245,6 +245,15 @@ export const settings: Record<string, Setting[]> = {
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Nsjail tmpfs size (MB)',
|
||||
key: 'nsjail_tmpfs_size_mb',
|
||||
description:
|
||||
'Override the size of the <code>/tmp</code> tmpfs mount inside the nsjail sandbox (in MB). When left empty, defaults to 800MB. Only applies when the job isolation mode is set to Nsjail.',
|
||||
fieldType: 'number',
|
||||
placeholder: '800',
|
||||
storage: 'setting'
|
||||
},
|
||||
{
|
||||
label: 'Default timeout',
|
||||
key: 'job_default_timeout',
|
||||
|
||||
Reference in New Issue
Block a user