mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-21 16:03:26 +00:00
feat: add a no_network annotation for sandboxed jobs (#11844)
* feat: add a no_network annotation for sandboxed python, bash, bun and r jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep nodejs relative imports and dedicated workers working under no_network Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bundle bun no_network jobs so relative imports resolve before the run Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: point ee-repo-ref at the runner group no_network fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor: state the no_network token rule once Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: refuse no_network jobs whose workspace imports would be fetched at run time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: let type-only workspace imports through the no_network import check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: update ee-repo-ref to ca4a1959a0d2257d413a57349939053ac3473c6b This commit updates the EE repository reference after PR #895 was merged in windmill-ee-private. Previous ee-repo-ref: 3841923cfd117b6b907ac3e84b26f07bde41f8ed New ee-repo-ref: ca4a1959a0d2257d413a57349939053ac3473c6b Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
windmill-internal-app[bot]
parent
b0c97b34ca
commit
feb7b1ad90
@@ -149,15 +149,16 @@ use crate::global_cache::pull_from_tar;
|
||||
use windmill_object_store::get_cache_object_store;
|
||||
|
||||
use crate::{
|
||||
check_no_network_jailed,
|
||||
common::{
|
||||
build_command_with_isolation, create_args_and_out_file, get_reserved_variables, read_file,
|
||||
read_result, render_nsjail_rlimit_as, resolve_nsjail_timeout,
|
||||
resolve_nsjail_tmp_mount_block, start_child_process, OccupancyMetrics, StreamNotifier,
|
||||
DEV_CONF_NSJAIL,
|
||||
},
|
||||
get_proxy_envs_for_lang,
|
||||
get_proxy_envs_for_lang, get_run_proxy_envs,
|
||||
handle_child::handle_child,
|
||||
is_sandboxing_enabled, read_ee_registry,
|
||||
is_sandboxing_enabled, nsjail_clone_newnet, read_ee_registry,
|
||||
worker_utils::ping_job_status,
|
||||
PyV, DISABLE_NUSER, HOME_ENV, INDEX_CERT, NATIVE_CERT, NSJAIL_AVAILABLE, NSJAIL_PATH,
|
||||
NSJAIL_PY_RLIMIT_AS_MB, PATH_ENV, PIP_EXTRA_INDEX_URL, PIP_INDEX_URL, PROXY_ENVS,
|
||||
@@ -775,6 +776,8 @@ pub async fn handle_python_job(
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
let jailed = is_sandboxing_enabled() || annotations.sandbox;
|
||||
check_no_network_jailed(annotations.no_network, jailed)?;
|
||||
|
||||
// Preview jobs may carry _TEMP_SCRIPT_REFS so relative imports resolve from
|
||||
// not-yet-deployed local content uploaded to raw_script_temp. Gated on
|
||||
@@ -792,6 +795,19 @@ pub async fn handle_python_job(
|
||||
};
|
||||
|
||||
let module_sources = windmill_parser_py_imports::module_sources(&script_path, modules.as_ref());
|
||||
if annotations.no_network {
|
||||
let imports = std::iter::once((script_path.as_str(), inner_content.as_str()))
|
||||
.chain(
|
||||
module_sources
|
||||
.iter()
|
||||
.flatten()
|
||||
.map(|(path, code)| (path.as_str(), code.as_str())),
|
||||
)
|
||||
.flat_map(|(path, code)| {
|
||||
windmill_parser_py_imports::parse_relative_imports(code, path).unwrap_or_default()
|
||||
});
|
||||
crate::check_no_network_imports(imports, &script_path, modules.as_ref(), "Python")?;
|
||||
}
|
||||
let (py_version, mut additional_python_paths) = handle_python_deps_with_modules(
|
||||
job_dir,
|
||||
requirements_o,
|
||||
@@ -839,6 +855,9 @@ pub async fn handle_python_job(
|
||||
if annotations.sandbox {
|
||||
logs.push_str("sandbox mode (nsjail)\n");
|
||||
}
|
||||
if annotations.no_network {
|
||||
logs.push_str("no network\n");
|
||||
}
|
||||
append_logs(&job.id, &job.workspace_id, logs, conn).await;
|
||||
}
|
||||
let (
|
||||
@@ -1080,6 +1099,7 @@ except BaseException as e:
|
||||
|
||||
let mut reserved_variables =
|
||||
get_reserved_variables(job, &client.token, conn, parent_runnable_path).await?;
|
||||
crate::strip_no_network_token(&mut reserved_variables, annotations.no_network);
|
||||
|
||||
// Add /tmp/windmill/cache/python_x_y_z/global-site-packages to PYTHONPATH.
|
||||
// Usefull if certain wheels needs to be preinstalled before execution.
|
||||
@@ -1112,7 +1132,7 @@ except BaseException as e:
|
||||
#[cfg(windows)]
|
||||
let additional_python_paths_folders = additional_python_paths_folders.replace(":", ";");
|
||||
|
||||
if is_sandboxing_enabled() || annotations.sandbox {
|
||||
if jailed {
|
||||
let shared_deps = additional_python_paths
|
||||
.into_iter()
|
||||
.map(|pp| {
|
||||
@@ -1141,6 +1161,10 @@ mount {{
|
||||
.replace("{JOB_DIR}", job_dir)
|
||||
.replace("{PY_INSTALL_DIR}", &*PY_INSTALL_DIR)
|
||||
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string())
|
||||
.replace(
|
||||
"{CLONE_NEWNET}",
|
||||
nsjail_clone_newnet(annotations.no_network),
|
||||
)
|
||||
.replace("{SHARED_MOUNT}", shared_mount)
|
||||
.replace("{SHARED_DEPENDENCIES}", shared_deps.as_str())
|
||||
.replace("{GLOBAL_SITE_PACKAGES}", &global_site_packages_path)
|
||||
@@ -1167,7 +1191,7 @@ mount {{
|
||||
job.id
|
||||
);
|
||||
|
||||
let child = if is_sandboxing_enabled() || annotations.sandbox {
|
||||
let child = if jailed {
|
||||
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
|
||||
nsjail_cmd
|
||||
.current_dir(job_dir)
|
||||
@@ -1175,12 +1199,13 @@ mount {{
|
||||
// inject PYTHONPATH here - for some reason I had to do it in nsjail conf
|
||||
.envs(reserved_variables)
|
||||
.envs(
|
||||
get_proxy_envs_for_lang(
|
||||
get_run_proxy_envs(
|
||||
&ScriptLang::Python3,
|
||||
job.kind,
|
||||
&job.id,
|
||||
&job.workspace_id,
|
||||
conn,
|
||||
annotations.no_network,
|
||||
)
|
||||
.await?,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user