Skip to content

Commit abf094b

Browse files
authored
fix uv install for nsjail (#5222)
1 parent 6d33cd2 commit abf094b

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

backend/windmill-queue/src/jobs.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,9 @@ pub async fn add_completed_job<T: Serialize + Send + Sync + ValidableJson>(
898898
sqlx::query_scalar!("SELECT premium FROM workspace WHERE id = $1", w_id)
899899
.fetch_one(db)
900900
.await
901-
.map_err(|e| Error::internal_err(format!("fetching if {w_id} is premium: {e:#}")))?;
901+
.map_err(|e| {
902+
Error::internal_err(format!("fetching if {w_id} is premium: {e:#}"))
903+
})?;
902904
let _ = sqlx::query!(
903905
"INSERT INTO usage (id, is_workspace, month_, usage)
904906
VALUES ($1, TRUE, EXTRACT(YEAR FROM current_date) * 12 + EXTRACT(MONTH FROM current_date), $2)
@@ -2333,7 +2335,9 @@ pub async fn get_result_and_success_by_id_from_flow(
23332335
.fetch_optional(db)
23342336
.await?
23352337
.ok_or_else(|| {
2336-
error::Error::internal_err(format!("Could not get success from flow job status"))
2338+
error::Error::internal_err(format!(
2339+
"Could not get success from flow job status"
2340+
))
23372341
})?
23382342
}
23392343
};

backend/windmill-worker/nsjail/download.py.config.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ keep_caps: true
2222
keep_env: true
2323
mount_proc: true
2424

25+
2526
mount {
2627
src: "/bin"
2728
dst: "/bin"
@@ -74,6 +75,13 @@ mount {
7475
is_bind: true
7576
}
7677

78+
mount {
79+
src: "{TARGET_DIR}"
80+
dst: "{TARGET_DIR}"
81+
is_bind: true
82+
rw: true
83+
}
84+
7785
mount {
7886
src: "{PY_INSTALL_DIR}"
7987
dst: "{PY_INSTALL_DIR}"

backend/windmill-worker/src/python_executor.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,7 @@ async fn spawn_uv_install(
16151615
// If none, it is system python
16161616
py_path: Option<String>,
16171617
no_uv_install: bool,
1618+
worker_dir: &str,
16181619
) -> Result<tokio::process::Child, Error> {
16191620
if !*DISABLE_NSJAIL {
16201621
tracing::info!(
@@ -1649,13 +1650,30 @@ async fn spawn_uv_install(
16491650
vars.push(("REQ", &req));
16501651
vars.push(("TARGET", venv_p));
16511652

1653+
std::fs::create_dir_all(venv_p)?;
1654+
let nsjail_proto = format!("{req}.config.proto");
1655+
// Prepare NSJAIL
1656+
let _ = write_file(
1657+
job_dir,
1658+
&nsjail_proto,
1659+
&(if no_uv_install {
1660+
NSJAIL_CONFIG_DOWNLOAD_PY_CONTENT_FALLBACK
1661+
} else {
1662+
NSJAIL_CONFIG_DOWNLOAD_PY_CONTENT
1663+
})
1664+
.replace("{WORKER_DIR}", worker_dir)
1665+
.replace("{PY_INSTALL_DIR}", &PY_INSTALL_DIR)
1666+
.replace("{TARGET_DIR}", &venv_p)
1667+
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string()),
1668+
)?;
1669+
16521670
let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str());
16531671
nsjail_cmd
16541672
.current_dir(job_dir)
16551673
.env_clear()
16561674
.envs(vars)
16571675
.envs(PROXY_ENVS.clone())
1658-
.args(vec!["--config", "download.config.proto"])
1676+
.args(vec!["--config", &nsjail_proto])
16591677
.stdout(Stdio::piped())
16601678
.stderr(Stdio::piped());
16611679
start_child_process(nsjail_cmd, NSJAIL_PATH.as_str()).await
@@ -1841,6 +1859,8 @@ pub async fn handle_python_reqs(
18411859
// TODO: Remove (Deprecated)
18421860
mut no_uv_install: bool,
18431861
) -> error::Result<Vec<String>> {
1862+
let worker_dir = worker_dir.to_string();
1863+
18441864
let counter_arc = Arc::new(tokio::sync::Mutex::new(0));
18451865
// Append logs with line like this:
18461866
// [9/21] + requests==2.32.3 << (S3) | in 57ms
@@ -1924,22 +1944,6 @@ pub async fn handle_python_reqs(
19241944
.map(handle_ephemeral_token),
19251945
);
19261946

1927-
// Prepare NSJAIL
1928-
if !*DISABLE_NSJAIL {
1929-
let _ = write_file(
1930-
job_dir,
1931-
"download.config.proto",
1932-
&(if no_uv_install {
1933-
NSJAIL_CONFIG_DOWNLOAD_PY_CONTENT_FALLBACK
1934-
} else {
1935-
NSJAIL_CONFIG_DOWNLOAD_PY_CONTENT
1936-
})
1937-
.replace("{WORKER_DIR}", &worker_dir)
1938-
.replace("{PY_INSTALL_DIR}", &PY_INSTALL_DIR)
1939-
.replace("{CLONE_NEWUSER}", &(!*DISABLE_NUSER).to_string()),
1940-
)?;
1941-
};
1942-
19431947
// Cached paths
19441948
let mut req_with_penv: Vec<(String, String)> = vec![];
19451949
// Requirements to pull (not cached)
@@ -2176,7 +2180,7 @@ pub async fn handle_python_reqs(
21762180
let pip_indexes = pip_indexes.clone();
21772181
let py_path = py_path.clone();
21782182
let pids = pids.clone();
2179-
2183+
let worker_dir = worker_dir.clone();
21802184
handles.push(task::spawn(async move {
21812185
// permit will be dropped anyway if this thread exits at any point
21822186
// so we dont have to drop it manually
@@ -2244,7 +2248,8 @@ pub async fn handle_python_reqs(
22442248
&job_dir,
22452249
pip_indexes,
22462250
py_path,
2247-
no_uv_install
2251+
no_uv_install,
2252+
&worker_dir
22482253
).await {
22492254
Ok(r) => r,
22502255
Err(e) => {

0 commit comments

Comments
 (0)