From 2646629194f260d0be3a809be421bbab1307f927 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Thu, 12 Feb 2026 19:20:22 +0100 Subject: [PATCH] feat: add force_sandboxing global setting and #sandbox bash annotation (#7816) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add force_sandboxing global setting and #sandbox bash annotation Add a new global setting `force_sandboxing` to enable nsjail sandboxing for all jobs, overriding the DISABLE_NSJAIL environment variable. Also add a #sandbox annotation for bash scripts to enable sandboxing on a per-script basis. Co-Authored-By: Claude Opus 4.5 * fix: decouple nsjail probing from DISABLE_NSJAIL and apply force_sandboxing to all executors NSJAIL_AVAILABLE now always probes for the nsjail binary at startup regardless of the DISABLE_NSJAIL policy flag, fixing #sandbox annotation and force_sandboxing being unusable in default (DISABLE_NSJAIL=true) configuration. All language executors now use is_sandboxing_enabled() instead of checking DISABLE_NSJAIL directly, so force_sandboxing applies to all job types, not just bash. Co-Authored-By: Claude Opus 4.6 * fix: clarify force_sandboxing and DISABLE_NSJAIL relationship Neither setting overrides the other — sandboxing is enabled when either force_sandboxing=true OR DISABLE_NSJAIL=false. Updated frontend description and backend comments to reflect this. Co-Authored-By: Claude Opus 4.6 * all * all * revert typo * all * all --------- Co-authored-by: Claude Opus 4.5 --- ...001f29e58e81b3f782887db6e0a627dd8ad75.json | 3 +- ...82b33947c5a5c702ce586e6e6ea51430380bf.json | 3 +- ...1f7f387f5055c47f493271d26731336257384.json | 10 +- ...bc7e9ee85289ff5c52af43166928337c257e7.json | 3 +- ...7b23d6dcf2e5364852a5e85b3c41c417bace2.json | 3 +- ...9e8c0bb132b70668301b535872d1632753e30.json | 3 +- ...66f38ffe2f3a0958adea53e67757c6ac463ec.json | 3 +- ...243ad2e0aef485a780daea5d76b0be2bb2ea2.json | 3 +- ...adbb2860ce52d37a56b2861de1215260ecff8.json | 6 +- ...fbe7db4887c4ac5295052c796bd78a7edc50b.json | 3 +- ...f518b42f4cdb33e034441015494bd26c172d2.json | 3 +- ...f446d88c7bc671d5e90307febfd60bb235031.json | 3 +- ...e075c6ae51404037b0a7d4d33faf6a7d6a6d8.json | 3 +- ...a94ff708ce8e0b0b4fb59e5de7c9698c75c25.json | 3 +- ...823d8e54c96889e06895c57cafae9ca27bf8b.json | 3 +- ...748e0639c2f73cbc1d8be66420c70b14c96e1.json | 3 +- ...655ddf728cd3f21ee308db7393694ccc5c7b3.json | 3 +- ...72f20bb5a0aa921a614bd02898d3f162660c2.json | 6 +- ...cad6d8995242dc20a4e14c1a8fae4fc6a9fd2.json | 3 +- ...2f7175cc6f2e02d9c565bb5159cae3e0b6835.json | 3 +- ...08532a1020cabaf5e22325a1e05f0491d785c.json | 3 +- ...e35adf640d44d607e62a1fb296e38ac3fdd36.json | 6 +- ...2ab0f2348646d79f5306c6868e2c3a8f389ee.json | 3 +- ...c6c70f7f3958564a79bb0c6b3863b1ebb0cbf.json | 3 +- ...1a803e1bced2f8e1a12f8933b7598ee85a147.json | 3 +- ...4f412c57af931f80621aee5012e9cb3535626.json | 3 +- ...8d92a983470adcd3cc850734960c905e61e83.json | 3 +- ...ca846dd5e7fe7ceb1aa8b3fcd26a2bd30eb2c.json | 3 +- ...a22e4276c1da653475628889ce17dc904fbaa.json | 3 +- ...6eb9016207975af1e37042d81df8cb6ae2c53.json | 3 +- ...506bf08c28efe82b68b3d44bafbd3d0e91c29.json | 3 +- ...d98d365acec09f2f102b7de71dcc9d356900e.json | 3 +- ...d2393e297043e4e58555d872b5c4dd89c196a.json | 3 +- ...e3dc360b88429f03dd1e2b1b55cfabe208cb7.json | 3 +- ...3a960b89e02ec40b292f3b5198baf2a1d3dbf.json | 3 +- ...fbafe5dc3cdecc17a3d5a7476b160c1b6e7e1.json | 3 +- ...2d14755474cba82b3b388a47585a8bb325b1a.json | 17 -- ...2ede46b4471e21b11f607573a844013911abe.json | 3 +- ...e33244fe8ab9a803248fc23f334034d24aad4.json | 3 +- ...bb6a8f961c119516e4c33dc928cd3b4f4edbc.json | 3 +- ...9e637e9e156cd85b69126c87dfff89a47711d.json | 3 +- ...f892bf40e629ee11ee4845199481755f2789d.json | 6 +- ...9746147aa9b8d0a81642a7b7cb4738a0cad66.json | 3 +- ...d434f860922fbc021185beffb9827647feb8e.json | 3 +- ...384514987b6a4eb807ee375fb8b5cd4e92307.json | 3 +- ...13f1f882b695f896f94e5cf91d205633355a1.json | 3 +- ...d2ca5449dad0fe361bee1a9834989bfeabbae.json | 3 +- ...e1ea2fe96a1b94f5a92953fb1c1642d15c016.json | 3 +- ...1a8a9cc35f362197c0766a5787436af141106.json | 3 +- ...9352d4d1e3cb3a8a08f1c9c03055a1cab1235.json | 3 +- ...f03f72ef81db302d727e18e63a307ac902022.json | 3 +- ...c35c7342ac9a814c73f6290e1d6ebd3a55423.json | 3 +- ...26275203fc8ecddf83ca6d05c9fb77e46e7ee.json | 6 +- ...50d6a6935420fbedc83aa3ad1e9be7465c8dd.json | 3 +- ...7d42e7add6011c34d91761ba23e2c74c4032c.json | 6 +- backend/src/main.rs | 8 +- backend/src/monitor.rs | 47 ++++- .../windmill-common/src/global_settings.rs | 1 + backend/windmill-common/src/worker.rs | 1 + .../windmill-worker/src/ansible_executor.rs | 12 +- backend/windmill-worker/src/bash_executor.rs | 18 +- backend/windmill-worker/src/bun_executor.rs | 10 +- backend/windmill-worker/src/common.rs | 4 +- .../windmill-worker/src/csharp_executor.rs | 6 +- backend/windmill-worker/src/deno_executor.rs | 6 +- backend/windmill-worker/src/go_executor.rs | 6 +- backend/windmill-worker/src/java_executor.rs | 10 +- backend/windmill-worker/src/nu_executor.rs | 8 +- backend/windmill-worker/src/php_executor.rs | 6 +- backend/windmill-worker/src/pwsh_executor.rs | 6 +- .../windmill-worker/src/python_executor.rs | 24 +-- backend/windmill-worker/src/ruby_executor.rs | 12 +- backend/windmill-worker/src/rust_executor.rs | 12 +- .../src/universal_pkg_installer.rs | 6 +- backend/windmill-worker/src/worker.rs | 160 +++++++++++++----- backend/windmill-worker/src/worker_utils.rs | 9 +- frontend/src/lib/components/EEOnly.svelte | 2 +- .../src/lib/components/instanceSettings.ts | 35 +++- 78 files changed, 340 insertions(+), 273 deletions(-) delete mode 100644 backend/.sqlx/query-9f07510019ebe6f0c5fa17bf31c2d14755474cba82b3b388a47585a8bb325b1a.json diff --git a/backend/.sqlx/query-023cdbc77ea9e2c17a1aa92a5b9001f29e58e81b3f782887db6e0a627dd8ad75.json b/backend/.sqlx/query-023cdbc77ea9e2c17a1aa92a5b9001f29e58e81b3f782887db6e0a627dd8ad75.json index d3f1c39c7a..5b58cedc72 100644 --- a/backend/.sqlx/query-023cdbc77ea9e2c17a1aa92a5b9001f29e58e81b3f782887db6e0a627dd8ad75.json +++ b/backend/.sqlx/query-023cdbc77ea9e2c17a1aa92a5b9001f29e58e81b3f782887db6e0a627dd8ad75.json @@ -12,8 +12,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-06072cfe26abe58629623a8b38382b33947c5a5c702ce586e6e6ea51430380bf.json b/backend/.sqlx/query-06072cfe26abe58629623a8b38382b33947c5a5c702ce586e6e6ea51430380bf.json index 97e39aa0e5..8ecc409fc8 100644 --- a/backend/.sqlx/query-06072cfe26abe58629623a8b38382b33947c5a5c702ce586e6e6ea51430380bf.json +++ b/backend/.sqlx/query-06072cfe26abe58629623a8b38382b33947c5a5c702ce586e6e6ea51430380bf.json @@ -17,8 +17,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json index d29a18c691..e7ed0aee65 100644 --- a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json +++ b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json @@ -46,11 +46,11 @@ ] }, "nullable": [ - true, - true, - true, - true, - true, + false, + false, + false, + false, + false, true, true ] diff --git a/backend/.sqlx/query-089d7bc7acdbb97cf477159e111bc7e9ee85289ff5c52af43166928337c257e7.json b/backend/.sqlx/query-089d7bc7acdbb97cf477159e111bc7e9ee85289ff5c52af43166928337c257e7.json index b925141065..a032a87239 100644 --- a/backend/.sqlx/query-089d7bc7acdbb97cf477159e111bc7e9ee85289ff5c52af43166928337c257e7.json +++ b/backend/.sqlx/query-089d7bc7acdbb97cf477159e111bc7e9ee85289ff5c52af43166928337c257e7.json @@ -30,8 +30,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-0f7e01b613a94b29784aae6d7b17b23d6dcf2e5364852a5e85b3c41c417bace2.json b/backend/.sqlx/query-0f7e01b613a94b29784aae6d7b17b23d6dcf2e5364852a5e85b3c41c417bace2.json index de4dd4a7e3..1648882c1a 100644 --- a/backend/.sqlx/query-0f7e01b613a94b29784aae6d7b17b23d6dcf2e5364852a5e85b3c41c417bace2.json +++ b/backend/.sqlx/query-0f7e01b613a94b29784aae6d7b17b23d6dcf2e5364852a5e85b3c41c417bace2.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-14276a040cb4db88d71fccdc3579e8c0bb132b70668301b535872d1632753e30.json b/backend/.sqlx/query-14276a040cb4db88d71fccdc3579e8c0bb132b70668301b535872d1632753e30.json index bed99ef1b7..d4f7afa966 100644 --- a/backend/.sqlx/query-14276a040cb4db88d71fccdc3579e8c0bb132b70668301b535872d1632753e30.json +++ b/backend/.sqlx/query-14276a040cb4db88d71fccdc3579e8c0bb132b70668301b535872d1632753e30.json @@ -122,8 +122,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-16d438374b03a9c515f4c2d638366f38ffe2f3a0958adea53e67757c6ac463ec.json b/backend/.sqlx/query-16d438374b03a9c515f4c2d638366f38ffe2f3a0958adea53e67757c6ac463ec.json index 1fdc78c472..c091114374 100644 --- a/backend/.sqlx/query-16d438374b03a9c515f4c2d638366f38ffe2f3a0958adea53e67757c6ac463ec.json +++ b/backend/.sqlx/query-16d438374b03a9c515f4c2d638366f38ffe2f3a0958adea53e67757c6ac463ec.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-19b59c478744d029c6006b01f04243ad2e0aef485a780daea5d76b0be2bb2ea2.json b/backend/.sqlx/query-19b59c478744d029c6006b01f04243ad2e0aef485a780daea5d76b0be2bb2ea2.json index 30e071f8ce..43c68f8c5a 100644 --- a/backend/.sqlx/query-19b59c478744d029c6006b01f04243ad2e0aef485a780daea5d76b0be2bb2ea2.json +++ b/backend/.sqlx/query-19b59c478744d029c6006b01f04243ad2e0aef485a780daea5d76b0be2bb2ea2.json @@ -40,8 +40,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-212553c83e4dcdc6d045eb2fe2dadbb2860ce52d37a56b2861de1215260ecff8.json b/backend/.sqlx/query-212553c83e4dcdc6d045eb2fe2dadbb2860ce52d37a56b2861de1215260ecff8.json index b0354db034..7d8b2eba1e 100644 --- a/backend/.sqlx/query-212553c83e4dcdc6d045eb2fe2dadbb2860ce52d37a56b2861de1215260ecff8.json +++ b/backend/.sqlx/query-212553c83e4dcdc6d045eb2fe2dadbb2860ce52d37a56b2861de1215260ecff8.json @@ -34,8 +34,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } @@ -68,8 +67,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-22e0e8a1aa48f8b21763452bd36fbe7db4887c4ac5295052c796bd78a7edc50b.json b/backend/.sqlx/query-22e0e8a1aa48f8b21763452bd36fbe7db4887c4ac5295052c796bd78a7edc50b.json index 235f255dd1..66c9e6e96a 100644 --- a/backend/.sqlx/query-22e0e8a1aa48f8b21763452bd36fbe7db4887c4ac5295052c796bd78a7edc50b.json +++ b/backend/.sqlx/query-22e0e8a1aa48f8b21763452bd36fbe7db4887c4ac5295052c796bd78a7edc50b.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-23419adcd74c326d716527293eff518b42f4cdb33e034441015494bd26c172d2.json b/backend/.sqlx/query-23419adcd74c326d716527293eff518b42f4cdb33e034441015494bd26c172d2.json index 7bd7367d8d..242b358ff5 100644 --- a/backend/.sqlx/query-23419adcd74c326d716527293eff518b42f4cdb33e034441015494bd26c172d2.json +++ b/backend/.sqlx/query-23419adcd74c326d716527293eff518b42f4cdb33e034441015494bd26c172d2.json @@ -40,8 +40,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-256118bb9c87675d6a8db2d13c4f446d88c7bc671d5e90307febfd60bb235031.json b/backend/.sqlx/query-256118bb9c87675d6a8db2d13c4f446d88c7bc671d5e90307febfd60bb235031.json index c51175e921..4e48ae281c 100644 --- a/backend/.sqlx/query-256118bb9c87675d6a8db2d13c4f446d88c7bc671d5e90307febfd60bb235031.json +++ b/backend/.sqlx/query-256118bb9c87675d6a8db2d13c4f446d88c7bc671d5e90307febfd60bb235031.json @@ -16,8 +16,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-2602402bedcdbc45cdc0d64a76ce075c6ae51404037b0a7d4d33faf6a7d6a6d8.json b/backend/.sqlx/query-2602402bedcdbc45cdc0d64a76ce075c6ae51404037b0a7d4d33faf6a7d6a6d8.json index 5a4cd89224..128a435c8b 100644 --- a/backend/.sqlx/query-2602402bedcdbc45cdc0d64a76ce075c6ae51404037b0a7d4d33faf6a7d6a6d8.json +++ b/backend/.sqlx/query-2602402bedcdbc45cdc0d64a76ce075c6ae51404037b0a7d4d33faf6a7d6a6d8.json @@ -11,8 +11,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-26141a1c3c48184285d94a2e2aca94ff708ce8e0b0b4fb59e5de7c9698c75c25.json b/backend/.sqlx/query-26141a1c3c48184285d94a2e2aca94ff708ce8e0b0b4fb59e5de7c9698c75c25.json index 08c6c1cbc2..9abe8af9af 100644 --- a/backend/.sqlx/query-26141a1c3c48184285d94a2e2aca94ff708ce8e0b0b4fb59e5de7c9698c75c25.json +++ b/backend/.sqlx/query-26141a1c3c48184285d94a2e2aca94ff708ce8e0b0b4fb59e5de7c9698c75c25.json @@ -11,8 +11,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-27ada97cb533c8595f1d73987c7823d8e54c96889e06895c57cafae9ca27bf8b.json b/backend/.sqlx/query-27ada97cb533c8595f1d73987c7823d8e54c96889e06895c57cafae9ca27bf8b.json index 1199e9441f..5d7c0e2abc 100644 --- a/backend/.sqlx/query-27ada97cb533c8595f1d73987c7823d8e54c96889e06895c57cafae9ca27bf8b.json +++ b/backend/.sqlx/query-27ada97cb533c8595f1d73987c7823d8e54c96889e06895c57cafae9ca27bf8b.json @@ -15,8 +15,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-2fd22c4ffa2d222bb116260994a748e0639c2f73cbc1d8be66420c70b14c96e1.json b/backend/.sqlx/query-2fd22c4ffa2d222bb116260994a748e0639c2f73cbc1d8be66420c70b14c96e1.json index afd0f503bf..8f6c8edf25 100644 --- a/backend/.sqlx/query-2fd22c4ffa2d222bb116260994a748e0639c2f73cbc1d8be66420c70b14c96e1.json +++ b/backend/.sqlx/query-2fd22c4ffa2d222bb116260994a748e0639c2f73cbc1d8be66420c70b14c96e1.json @@ -12,8 +12,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-3b3f60623126626b52ca0a4a188655ddf728cd3f21ee308db7393694ccc5c7b3.json b/backend/.sqlx/query-3b3f60623126626b52ca0a4a188655ddf728cd3f21ee308db7393694ccc5c7b3.json index 0df550b57c..27b2503991 100644 --- a/backend/.sqlx/query-3b3f60623126626b52ca0a4a188655ddf728cd3f21ee308db7393694ccc5c7b3.json +++ b/backend/.sqlx/query-3b3f60623126626b52ca0a4a188655ddf728cd3f21ee308db7393694ccc5c7b3.json @@ -12,8 +12,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-3e5bdc2e071fc2f1e3c7971736272f20bb5a0aa921a614bd02898d3f162660c2.json b/backend/.sqlx/query-3e5bdc2e071fc2f1e3c7971736272f20bb5a0aa921a614bd02898d3f162660c2.json index fdcb10be1c..e6dc6ff08b 100644 --- a/backend/.sqlx/query-3e5bdc2e071fc2f1e3c7971736272f20bb5a0aa921a614bd02898d3f162660c2.json +++ b/backend/.sqlx/query-3e5bdc2e071fc2f1e3c7971736272f20bb5a0aa921a614bd02898d3f162660c2.json @@ -16,8 +16,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } @@ -52,8 +51,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-42b4b73e9d60348e2d90fcade9dcad6d8995242dc20a4e14c1a8fae4fc6a9fd2.json b/backend/.sqlx/query-42b4b73e9d60348e2d90fcade9dcad6d8995242dc20a4e14c1a8fae4fc6a9fd2.json index 537ecbeacf..e6d71f386f 100644 --- a/backend/.sqlx/query-42b4b73e9d60348e2d90fcade9dcad6d8995242dc20a4e14c1a8fae4fc6a9fd2.json +++ b/backend/.sqlx/query-42b4b73e9d60348e2d90fcade9dcad6d8995242dc20a4e14c1a8fae4fc6a9fd2.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-45024b932383199974616bba1fc2f7175cc6f2e02d9c565bb5159cae3e0b6835.json b/backend/.sqlx/query-45024b932383199974616bba1fc2f7175cc6f2e02d9c565bb5159cae3e0b6835.json index 30c5ff7a49..f215cf6147 100644 --- a/backend/.sqlx/query-45024b932383199974616bba1fc2f7175cc6f2e02d9c565bb5159cae3e0b6835.json +++ b/backend/.sqlx/query-45024b932383199974616bba1fc2f7175cc6f2e02d9c565bb5159cae3e0b6835.json @@ -30,8 +30,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-4d272cf4a77aab7007a5b35589e08532a1020cabaf5e22325a1e05f0491d785c.json b/backend/.sqlx/query-4d272cf4a77aab7007a5b35589e08532a1020cabaf5e22325a1e05f0491d785c.json index cfb975b838..896b21dc7f 100644 --- a/backend/.sqlx/query-4d272cf4a77aab7007a5b35589e08532a1020cabaf5e22325a1e05f0491d785c.json +++ b/backend/.sqlx/query-4d272cf4a77aab7007a5b35589e08532a1020cabaf5e22325a1e05f0491d785c.json @@ -37,8 +37,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-4f547c0fd54f3bc57212ce87810e35adf640d44d607e62a1fb296e38ac3fdd36.json b/backend/.sqlx/query-4f547c0fd54f3bc57212ce87810e35adf640d44d607e62a1fb296e38ac3fdd36.json index 4e8ec56d12..789c0334d7 100644 --- a/backend/.sqlx/query-4f547c0fd54f3bc57212ce87810e35adf640d44d607e62a1fb296e38ac3fdd36.json +++ b/backend/.sqlx/query-4f547c0fd54f3bc57212ce87810e35adf640d44d607e62a1fb296e38ac3fdd36.json @@ -32,8 +32,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } @@ -71,8 +70,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-5368683c19f8d6744d5dbc53e5b2ab0f2348646d79f5306c6868e2c3a8f389ee.json b/backend/.sqlx/query-5368683c19f8d6744d5dbc53e5b2ab0f2348646d79f5306c6868e2c3a8f389ee.json index ebf1df39a3..1058d78d8b 100644 --- a/backend/.sqlx/query-5368683c19f8d6744d5dbc53e5b2ab0f2348646d79f5306c6868e2c3a8f389ee.json +++ b/backend/.sqlx/query-5368683c19f8d6744d5dbc53e5b2ab0f2348646d79f5306c6868e2c3a8f389ee.json @@ -16,8 +16,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-5bf200f2c8db25ddf231b564503c6c70f7f3958564a79bb0c6b3863b1ebb0cbf.json b/backend/.sqlx/query-5bf200f2c8db25ddf231b564503c6c70f7f3958564a79bb0c6b3863b1ebb0cbf.json index 9422e3e8d0..6d3941ad69 100644 --- a/backend/.sqlx/query-5bf200f2c8db25ddf231b564503c6c70f7f3958564a79bb0c6b3863b1ebb0cbf.json +++ b/backend/.sqlx/query-5bf200f2c8db25ddf231b564503c6c70f7f3958564a79bb0c6b3863b1ebb0cbf.json @@ -245,8 +245,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-66a0e51cf149ba532463e29dd361a803e1bced2f8e1a12f8933b7598ee85a147.json b/backend/.sqlx/query-66a0e51cf149ba532463e29dd361a803e1bced2f8e1a12f8933b7598ee85a147.json index 5f9be1cba9..0d12be2448 100644 --- a/backend/.sqlx/query-66a0e51cf149ba532463e29dd361a803e1bced2f8e1a12f8933b7598ee85a147.json +++ b/backend/.sqlx/query-66a0e51cf149ba532463e29dd361a803e1bced2f8e1a12f8933b7598ee85a147.json @@ -35,8 +35,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-7065f23d04e26831664048f2cfc4f412c57af931f80621aee5012e9cb3535626.json b/backend/.sqlx/query-7065f23d04e26831664048f2cfc4f412c57af931f80621aee5012e9cb3535626.json index 48ea42f8a2..02823e8291 100644 --- a/backend/.sqlx/query-7065f23d04e26831664048f2cfc4f412c57af931f80621aee5012e9cb3535626.json +++ b/backend/.sqlx/query-7065f23d04e26831664048f2cfc4f412c57af931f80621aee5012e9cb3535626.json @@ -29,8 +29,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-73fdd01bad58b8be1a52f89faef8d92a983470adcd3cc850734960c905e61e83.json b/backend/.sqlx/query-73fdd01bad58b8be1a52f89faef8d92a983470adcd3cc850734960c905e61e83.json index 8aacd8a805..cba7ffdfef 100644 --- a/backend/.sqlx/query-73fdd01bad58b8be1a52f89faef8d92a983470adcd3cc850734960c905e61e83.json +++ b/backend/.sqlx/query-73fdd01bad58b8be1a52f89faef8d92a983470adcd3cc850734960c905e61e83.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-757ef6215d3d385cb3a69e26ee4ca846dd5e7fe7ceb1aa8b3fcd26a2bd30eb2c.json b/backend/.sqlx/query-757ef6215d3d385cb3a69e26ee4ca846dd5e7fe7ceb1aa8b3fcd26a2bd30eb2c.json index 59b56ceda7..cd795e6fec 100644 --- a/backend/.sqlx/query-757ef6215d3d385cb3a69e26ee4ca846dd5e7fe7ceb1aa8b3fcd26a2bd30eb2c.json +++ b/backend/.sqlx/query-757ef6215d3d385cb3a69e26ee4ca846dd5e7fe7ceb1aa8b3fcd26a2bd30eb2c.json @@ -40,8 +40,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-7fbf72d9059fcd77e4c1112fa4fa22e4276c1da653475628889ce17dc904fbaa.json b/backend/.sqlx/query-7fbf72d9059fcd77e4c1112fa4fa22e4276c1da653475628889ce17dc904fbaa.json index 8c380df861..393a920b7c 100644 --- a/backend/.sqlx/query-7fbf72d9059fcd77e4c1112fa4fa22e4276c1da653475628889ce17dc904fbaa.json +++ b/backend/.sqlx/query-7fbf72d9059fcd77e4c1112fa4fa22e4276c1da653475628889ce17dc904fbaa.json @@ -27,8 +27,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-836bac47d89113d90bd03a471446eb9016207975af1e37042d81df8cb6ae2c53.json b/backend/.sqlx/query-836bac47d89113d90bd03a471446eb9016207975af1e37042d81df8cb6ae2c53.json index 3012e9ef77..437d644eb2 100644 --- a/backend/.sqlx/query-836bac47d89113d90bd03a471446eb9016207975af1e37042d81df8cb6ae2c53.json +++ b/backend/.sqlx/query-836bac47d89113d90bd03a471446eb9016207975af1e37042d81df8cb6ae2c53.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-87564a196a1662f524407d853db506bf08c28efe82b68b3d44bafbd3d0e91c29.json b/backend/.sqlx/query-87564a196a1662f524407d853db506bf08c28efe82b68b3d44bafbd3d0e91c29.json index 5a61f82be3..9350442134 100644 --- a/backend/.sqlx/query-87564a196a1662f524407d853db506bf08c28efe82b68b3d44bafbd3d0e91c29.json +++ b/backend/.sqlx/query-87564a196a1662f524407d853db506bf08c28efe82b68b3d44bafbd3d0e91c29.json @@ -35,8 +35,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-9052b7cd438ff029a37bd489190d98d365acec09f2f102b7de71dcc9d356900e.json b/backend/.sqlx/query-9052b7cd438ff029a37bd489190d98d365acec09f2f102b7de71dcc9d356900e.json index 62f8d3100f..02cad7d11d 100644 --- a/backend/.sqlx/query-9052b7cd438ff029a37bd489190d98d365acec09f2f102b7de71dcc9d356900e.json +++ b/backend/.sqlx/query-9052b7cd438ff029a37bd489190d98d365acec09f2f102b7de71dcc9d356900e.json @@ -17,8 +17,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-940b6d78bab940a37a42492f030d2393e297043e4e58555d872b5c4dd89c196a.json b/backend/.sqlx/query-940b6d78bab940a37a42492f030d2393e297043e4e58555d872b5c4dd89c196a.json index 09aadbda1e..47554ad43e 100644 --- a/backend/.sqlx/query-940b6d78bab940a37a42492f030d2393e297043e4e58555d872b5c4dd89c196a.json +++ b/backend/.sqlx/query-940b6d78bab940a37a42492f030d2393e297043e4e58555d872b5c4dd89c196a.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-95c57fb921a2e3725b92cbafac6e3dc360b88429f03dd1e2b1b55cfabe208cb7.json b/backend/.sqlx/query-95c57fb921a2e3725b92cbafac6e3dc360b88429f03dd1e2b1b55cfabe208cb7.json index a189bc4da2..4b989c893b 100644 --- a/backend/.sqlx/query-95c57fb921a2e3725b92cbafac6e3dc360b88429f03dd1e2b1b55cfabe208cb7.json +++ b/backend/.sqlx/query-95c57fb921a2e3725b92cbafac6e3dc360b88429f03dd1e2b1b55cfabe208cb7.json @@ -17,8 +17,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-9c50e3a136a8ee3ec56e083f26d3a960b89e02ec40b292f3b5198baf2a1d3dbf.json b/backend/.sqlx/query-9c50e3a136a8ee3ec56e083f26d3a960b89e02ec40b292f3b5198baf2a1d3dbf.json index 66a487695f..9759bad4d4 100644 --- a/backend/.sqlx/query-9c50e3a136a8ee3ec56e083f26d3a960b89e02ec40b292f3b5198baf2a1d3dbf.json +++ b/backend/.sqlx/query-9c50e3a136a8ee3ec56e083f26d3a960b89e02ec40b292f3b5198baf2a1d3dbf.json @@ -32,8 +32,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-9ecb404e46a4eac55f977f05a3afbafe5dc3cdecc17a3d5a7476b160c1b6e7e1.json b/backend/.sqlx/query-9ecb404e46a4eac55f977f05a3afbafe5dc3cdecc17a3d5a7476b160c1b6e7e1.json index b6fe1b7fa0..79c8f0b45d 100644 --- a/backend/.sqlx/query-9ecb404e46a4eac55f977f05a3afbafe5dc3cdecc17a3d5a7476b160c1b6e7e1.json +++ b/backend/.sqlx/query-9ecb404e46a4eac55f977f05a3afbafe5dc3cdecc17a3d5a7476b160c1b6e7e1.json @@ -30,8 +30,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-9f07510019ebe6f0c5fa17bf31c2d14755474cba82b3b388a47585a8bb325b1a.json b/backend/.sqlx/query-9f07510019ebe6f0c5fa17bf31c2d14755474cba82b3b388a47585a8bb325b1a.json deleted file mode 100644 index 25a32e5338..0000000000 --- a/backend/.sqlx/query-9f07510019ebe6f0c5fa17bf31c2d14755474cba82b3b388a47585a8bb325b1a.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO deployment_metadata (workspace_id, path, script_hash, deployment_msg) VALUES ($1, $2, $3, $4) ON CONFLICT (workspace_id, script_hash) WHERE script_hash IS NOT NULL DO UPDATE SET deployment_msg = EXCLUDED.deployment_msg", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Varchar", - "Int8", - "Text" - ] - }, - "nullable": [] - }, - "hash": "9f07510019ebe6f0c5fa17bf31c2d14755474cba82b3b388a47585a8bb325b1a" -} diff --git a/backend/.sqlx/query-a1745a4f525b251d2f5a602ab2b2ede46b4471e21b11f607573a844013911abe.json b/backend/.sqlx/query-a1745a4f525b251d2f5a602ab2b2ede46b4471e21b11f607573a844013911abe.json index 33636da608..a25f845f91 100644 --- a/backend/.sqlx/query-a1745a4f525b251d2f5a602ab2b2ede46b4471e21b11f607573a844013911abe.json +++ b/backend/.sqlx/query-a1745a4f525b251d2f5a602ab2b2ede46b4471e21b11f607573a844013911abe.json @@ -155,8 +155,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-a4b6371d33206010b2f3ffd2b09e33244fe8ab9a803248fc23f334034d24aad4.json b/backend/.sqlx/query-a4b6371d33206010b2f3ffd2b09e33244fe8ab9a803248fc23f334034d24aad4.json index 03ee58ca3f..da6d213748 100644 --- a/backend/.sqlx/query-a4b6371d33206010b2f3ffd2b09e33244fe8ab9a803248fc23f334034d24aad4.json +++ b/backend/.sqlx/query-a4b6371d33206010b2f3ffd2b09e33244fe8ab9a803248fc23f334034d24aad4.json @@ -185,8 +185,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-b3771b690c5966272b1f42c9965bb6a8f961c119516e4c33dc928cd3b4f4edbc.json b/backend/.sqlx/query-b3771b690c5966272b1f42c9965bb6a8f961c119516e4c33dc928cd3b4f4edbc.json index 4fa7da00e0..d08af6ffdd 100644 --- a/backend/.sqlx/query-b3771b690c5966272b1f42c9965bb6a8f961c119516e4c33dc928cd3b4f4edbc.json +++ b/backend/.sqlx/query-b3771b690c5966272b1f42c9965bb6a8f961c119516e4c33dc928cd3b4f4edbc.json @@ -160,8 +160,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-b3f0595cacba194e08b9a3e244d9e637e9e156cd85b69126c87dfff89a47711d.json b/backend/.sqlx/query-b3f0595cacba194e08b9a3e244d9e637e9e156cd85b69126c87dfff89a47711d.json index 186822a000..54a4e3cd93 100644 --- a/backend/.sqlx/query-b3f0595cacba194e08b9a3e244d9e637e9e156cd85b69126c87dfff89a47711d.json +++ b/backend/.sqlx/query-b3f0595cacba194e08b9a3e244d9e637e9e156cd85b69126c87dfff89a47711d.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-b615d73ddb43e9d655b86a0cf98f892bf40e629ee11ee4845199481755f2789d.json b/backend/.sqlx/query-b615d73ddb43e9d655b86a0cf98f892bf40e629ee11ee4845199481755f2789d.json index e6ef13f492..96f59aab3f 100644 --- a/backend/.sqlx/query-b615d73ddb43e9d655b86a0cf98f892bf40e629ee11ee4845199481755f2789d.json +++ b/backend/.sqlx/query-b615d73ddb43e9d655b86a0cf98f892bf40e629ee11ee4845199481755f2789d.json @@ -21,8 +21,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } @@ -72,8 +71,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-be6d2c92a62b7b284651c45af809746147aa9b8d0a81642a7b7cb4738a0cad66.json b/backend/.sqlx/query-be6d2c92a62b7b284651c45af809746147aa9b8d0a81642a7b7cb4738a0cad66.json index 4118760af2..0688afebd3 100644 --- a/backend/.sqlx/query-be6d2c92a62b7b284651c45af809746147aa9b8d0a81642a7b7cb4738a0cad66.json +++ b/backend/.sqlx/query-be6d2c92a62b7b284651c45af809746147aa9b8d0a81642a7b7cb4738a0cad66.json @@ -105,8 +105,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-c3b1152b554812d65eb27f95b1fd434f860922fbc021185beffb9827647feb8e.json b/backend/.sqlx/query-c3b1152b554812d65eb27f95b1fd434f860922fbc021185beffb9827647feb8e.json index 07243717a0..0098e51ab2 100644 --- a/backend/.sqlx/query-c3b1152b554812d65eb27f95b1fd434f860922fbc021185beffb9827647feb8e.json +++ b/backend/.sqlx/query-c3b1152b554812d65eb27f95b1fd434f860922fbc021185beffb9827647feb8e.json @@ -31,8 +31,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-cc5919b087e3319045fc2242f22384514987b6a4eb807ee375fb8b5cd4e92307.json b/backend/.sqlx/query-cc5919b087e3319045fc2242f22384514987b6a4eb807ee375fb8b5cd4e92307.json index 8a0dacd864..0e338633fe 100644 --- a/backend/.sqlx/query-cc5919b087e3319045fc2242f22384514987b6a4eb807ee375fb8b5cd4e92307.json +++ b/backend/.sqlx/query-cc5919b087e3319045fc2242f22384514987b6a4eb807ee375fb8b5cd4e92307.json @@ -11,8 +11,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-ccef7a1bde5cac6c362c5fedb6c13f1f882b695f896f94e5cf91d205633355a1.json b/backend/.sqlx/query-ccef7a1bde5cac6c362c5fedb6c13f1f882b695f896f94e5cf91d205633355a1.json index 2b39145512..5091b2fc69 100644 --- a/backend/.sqlx/query-ccef7a1bde5cac6c362c5fedb6c13f1f882b695f896f94e5cf91d205633355a1.json +++ b/backend/.sqlx/query-ccef7a1bde5cac6c362c5fedb6c13f1f882b695f896f94e5cf91d205633355a1.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-d0b493da8ff5b3b78a9a0c6972cd2ca5449dad0fe361bee1a9834989bfeabbae.json b/backend/.sqlx/query-d0b493da8ff5b3b78a9a0c6972cd2ca5449dad0fe361bee1a9834989bfeabbae.json index b71bf15f85..b0cef08da3 100644 --- a/backend/.sqlx/query-d0b493da8ff5b3b78a9a0c6972cd2ca5449dad0fe361bee1a9834989bfeabbae.json +++ b/backend/.sqlx/query-d0b493da8ff5b3b78a9a0c6972cd2ca5449dad0fe361bee1a9834989bfeabbae.json @@ -12,8 +12,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-d41ea93fd58381b89e151c965eae1ea2fe96a1b94f5a92953fb1c1642d15c016.json b/backend/.sqlx/query-d41ea93fd58381b89e151c965eae1ea2fe96a1b94f5a92953fb1c1642d15c016.json index 9d2f8d9a9f..11271e94d8 100644 --- a/backend/.sqlx/query-d41ea93fd58381b89e151c965eae1ea2fe96a1b94f5a92953fb1c1642d15c016.json +++ b/backend/.sqlx/query-d41ea93fd58381b89e151c965eae1ea2fe96a1b94f5a92953fb1c1642d15c016.json @@ -105,8 +105,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-d495c94b580fd34d5ae90615ef21a8a9cc35f362197c0766a5787436af141106.json b/backend/.sqlx/query-d495c94b580fd34d5ae90615ef21a8a9cc35f362197c0766a5787436af141106.json index 67a38d1904..9cef6500d3 100644 --- a/backend/.sqlx/query-d495c94b580fd34d5ae90615ef21a8a9cc35f362197c0766a5787436af141106.json +++ b/backend/.sqlx/query-d495c94b580fd34d5ae90615ef21a8a9cc35f362197c0766a5787436af141106.json @@ -25,8 +25,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-e4d71278fb80126a7a9da73f1889352d4d1e3cb3a8a08f1c9c03055a1cab1235.json b/backend/.sqlx/query-e4d71278fb80126a7a9da73f1889352d4d1e3cb3a8a08f1c9c03055a1cab1235.json index 7309b03a02..5b07bcd9c9 100644 --- a/backend/.sqlx/query-e4d71278fb80126a7a9da73f1889352d4d1e3cb3a8a08f1c9c03055a1cab1235.json +++ b/backend/.sqlx/query-e4d71278fb80126a7a9da73f1889352d4d1e3cb3a8a08f1c9c03055a1cab1235.json @@ -185,8 +185,7 @@ "sqs", "gcp", "mqtt", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-e80177f3ffd4c1f52cdb4757483f03f72ef81db302d727e18e63a307ac902022.json b/backend/.sqlx/query-e80177f3ffd4c1f52cdb4757483f03f72ef81db302d727e18e63a307ac902022.json index dd65a586d1..1e38e57fb5 100644 --- a/backend/.sqlx/query-e80177f3ffd4c1f52cdb4757483f03f72ef81db302d727e18e63a307ac902022.json +++ b/backend/.sqlx/query-e80177f3ffd4c1f52cdb4757483f03f72ef81db302d727e18e63a307ac902022.json @@ -31,8 +31,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-eac595e19e5c8e70f1514ef29dec35c7342ac9a814c73f6290e1d6ebd3a55423.json b/backend/.sqlx/query-eac595e19e5c8e70f1514ef29dec35c7342ac9a814c73f6290e1d6ebd3a55423.json index 7c45c44b13..57607ae052 100644 --- a/backend/.sqlx/query-eac595e19e5c8e70f1514ef29dec35c7342ac9a814c73f6290e1d6ebd3a55423.json +++ b/backend/.sqlx/query-eac595e19e5c8e70f1514ef29dec35c7342ac9a814c73f6290e1d6ebd3a55423.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-ecab1af12a7afa685c056b9d0e526275203fc8ecddf83ca6d05c9fb77e46e7ee.json b/backend/.sqlx/query-ecab1af12a7afa685c056b9d0e526275203fc8ecddf83ca6d05c9fb77e46e7ee.json index 16ccdd10e9..f80b75b5ec 100644 --- a/backend/.sqlx/query-ecab1af12a7afa685c056b9d0e526275203fc8ecddf83ca6d05c9fb77e46e7ee.json +++ b/backend/.sqlx/query-ecab1af12a7afa685c056b9d0e526275203fc8ecddf83ca6d05c9fb77e46e7ee.json @@ -21,8 +21,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } @@ -72,8 +71,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-ed8facbf29ebb670d05fe8aa34b50d6a6935420fbedc83aa3ad1e9be7465c8dd.json b/backend/.sqlx/query-ed8facbf29ebb670d05fe8aa34b50d6a6935420fbedc83aa3ad1e9be7465c8dd.json index 1876db927e..43fd90abe5 100644 --- a/backend/.sqlx/query-ed8facbf29ebb670d05fe8aa34b50d6a6935420fbedc83aa3ad1e9be7465c8dd.json +++ b/backend/.sqlx/query-ed8facbf29ebb670d05fe8aa34b50d6a6935420fbedc83aa3ad1e9be7465c8dd.json @@ -24,8 +24,7 @@ "mqtt", "gcp", "default_email", - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/.sqlx/query-ee537def1ead8bee48bb9f5c1f57d42e7add6011c34d91761ba23e2c74c4032c.json b/backend/.sqlx/query-ee537def1ead8bee48bb9f5c1f57d42e7add6011c34d91761ba23e2c74c4032c.json index 536175599d..4ce08c9e1c 100644 --- a/backend/.sqlx/query-ee537def1ead8bee48bb9f5c1f57d42e7add6011c34d91761ba23e2c74c4032c.json +++ b/backend/.sqlx/query-ee537def1ead8bee48bb9f5c1f57d42e7add6011c34d91761ba23e2c74c4032c.json @@ -21,8 +21,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } @@ -72,8 +71,7 @@ "name": "native_trigger_service", "kind": { "Enum": [ - "nextcloud", - "google" + "nextcloud" ] } } diff --git a/backend/src/main.rs b/backend/src/main.rs index 083575e418..725d88c696 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -41,7 +41,7 @@ use windmill_common::{ CRITICAL_ERROR_CHANNELS_SETTING, CUSTOM_TAGS_SETTING, DEFAULT_TAGS_PER_WORKSPACE_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, EMAIL_DOMAIN_SETTING, ENV_SETTINGS, EXPOSE_DEBUG_METRICS_SETTING, EXPOSE_METRICS_SETTING, EXTRA_PIP_INDEX_URL_SETTING, - HUB_API_SECRET_SETTING, HUB_BASE_URL_SETTING, INDEXER_SETTING, + JOB_ISOLATION_SETTING, HUB_API_SECRET_SETTING, HUB_BASE_URL_SETTING, INDEXER_SETTING, INSTANCE_PYTHON_VERSION_SETTING, JOB_DEFAULT_TIMEOUT_SECS_SETTING, JWT_SECRET_SETTING, KEEP_JOB_DIR_SETTING, LICENSE_KEY_SETTING, MAVEN_REPOS_SETTING, MONITOR_LOGS_ON_OBJECT_STORE_SETTING, NO_DEFAULT_MAVEN_SETTING, @@ -99,8 +99,9 @@ use crate::monitor::{ reload_app_workspaced_route_setting, reload_base_url_setting, reload_bunfig_install_scopes_setting, reload_critical_alert_mute_ui_setting, reload_critical_error_channels_setting, reload_extra_pip_index_url_setting, - reload_hub_api_secret_setting, reload_hub_base_url_setting, reload_job_default_timeout_setting, - reload_jwt_secret_setting, reload_license_key, reload_npm_config_registry_setting, + reload_job_isolation_setting, reload_hub_api_secret_setting, reload_hub_base_url_setting, + reload_job_default_timeout_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_uv_index_strategy_setting, reload_worker_config, MonitorIteration, @@ -1555,6 +1556,7 @@ async fn process_notify_event( reload_delete_logs_periodically_setting(conn).await } JOB_DEFAULT_TIMEOUT_SECS_SETTING => reload_job_default_timeout_setting(conn).await, + JOB_ISOLATION_SETTING => reload_job_isolation_setting(conn).await, #[cfg(feature = "parquet")] OBJECT_STORE_CONFIG_SETTING => { if !disable_s3_store { diff --git a/backend/src/monitor.rs b/backend/src/monitor.rs index c936601624..e8bbe5c08b 100644 --- a/backend/src/monitor.rs +++ b/backend/src/monitor.rs @@ -54,10 +54,11 @@ use windmill_common::{ DEFAULT_TAGS_PER_WORKSPACE_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, EXPOSE_DEBUG_METRICS_SETTING, EXPOSE_METRICS_SETTING, EXTRA_PIP_INDEX_URL_SETTING, HUB_API_SECRET_SETTING, HUB_BASE_URL_SETTING, INSTANCE_PYTHON_VERSION_SETTING, - JOB_DEFAULT_TIMEOUT_SECS_SETTING, JWT_SECRET_SETTING, KEEP_JOB_DIR_SETTING, - LICENSE_KEY_SETTING, MONITOR_LOGS_ON_OBJECT_STORE_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, REQUEST_SIZE_LIMIT_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, + 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, REQUEST_SIZE_LIMIT_SETTING, REQUIRE_PREEXISTING_USER_FOR_OAUTH_SETTING, RETENTION_PERIOD_SECS_SETTING, SAML_METADATA_SETTING, SCIM_TOKEN_SETTING, TIMEOUT_WAIT_RESULT_SETTING, UV_INDEX_STRATEGY_SETTING, @@ -85,11 +86,12 @@ use windmill_common::{ use windmill_common::{client::AuthedClient, global_settings::APP_WORKSPACED_ROUTE_SETTING}; use windmill_queue::{cancel_job, get_queued_job_v2, SameWorkerPayload}; use windmill_worker::{ - result_processor::handle_job_error, JobCompletedSender, OtelTracingProxySettings, - SameWorkerSender, BUNFIG_INSTALL_SCOPES, CARGO_REGISTRIES, INSTANCE_PYTHON_VERSION, - JOB_DEFAULT_TIMEOUT, KEEP_JOB_DIR, MAVEN_REPOS, NO_DEFAULT_MAVEN, NPM_CONFIG_REGISTRY, - NUGET_CONFIG, OTEL_TRACING_PROXY_SETTINGS, PIP_EXTRA_INDEX_URL, PIP_INDEX_URL, - POWERSHELL_REPO_PAT, POWERSHELL_REPO_URL, UV_INDEX_STRATEGY, + result_processor::handle_job_error, JobCompletedSender, JobIsolationLevel, + OtelTracingProxySettings, SameWorkerSender, BUNFIG_INSTALL_SCOPES, CARGO_REGISTRIES, + INSTANCE_PYTHON_VERSION, JOB_DEFAULT_TIMEOUT, JOB_ISOLATION, KEEP_JOB_DIR, MAVEN_REPOS, + NO_DEFAULT_MAVEN, NPM_CONFIG_REGISTRY, NSJAIL_AVAILABLE, NUGET_CONFIG, + OTEL_TRACING_PROXY_SETTINGS, PIP_EXTRA_INDEX_URL, PIP_INDEX_URL, POWERSHELL_REPO_PAT, + POWERSHELL_REPO_URL, UV_INDEX_STRATEGY, }; #[cfg(feature = "parquet")] @@ -316,6 +318,7 @@ pub async fn initial_load( if worker_mode { reload_job_default_timeout_setting(&conn).await; + reload_job_isolation_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; @@ -1418,6 +1421,32 @@ pub async fn reload_job_default_timeout_setting(conn: &Connection) { .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 { + Ok(Some(v)) => JobIsolationLevel::from_str(v.as_str().unwrap_or("")), + Ok(None) => JobIsolationLevel::Undefined, + Err(e) => { + tracing::error!("Error reloading job_isolation setting: {:?}", e); + return; + } + }; + let old_value = JobIsolationLevel::from_u8(JOB_ISOLATION.swap(value as u8, Ordering::Relaxed)); + if old_value != value { + tracing::info!( + "job_isolation setting changed from {:?} to {:?}", + old_value, + value + ); + } + if value == JobIsolationLevel::NsjailSandboxing && NSJAIL_AVAILABLE.is_none() { + tracing::error!( + "job_isolation is set to nsjail_sandboxing but nsjail is not available on this worker. \ + All jobs will fail until nsjail is installed or the setting is changed." + ); + } +} + pub async fn reload_request_size(conn: &Connection) { if let Err(e) = reload_setting( conn, diff --git a/backend/windmill-common/src/global_settings.rs b/backend/windmill-common/src/global_settings.rs index 3581b6de4d..cfa0839214 100644 --- a/backend/windmill-common/src/global_settings.rs +++ b/backend/windmill-common/src/global_settings.rs @@ -35,6 +35,7 @@ pub const EXPOSE_METRICS_SETTING: &str = "expose_metrics"; 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 OBJECT_STORE_CONFIG_SETTING: &str = "object_store_cache_config"; pub const HUB_API_SECRET_SETTING: &str = "hub_api_secret"; diff --git a/backend/windmill-common/src/worker.rs b/backend/windmill-common/src/worker.rs index 6d392fa950..46f13d4444 100644 --- a/backend/windmill-common/src/worker.rs +++ b/backend/windmill-common/src/worker.rs @@ -688,6 +688,7 @@ pub struct SqlAnnotations { #[annotations("#")] pub struct BashAnnotations { pub docker: bool, + pub sandbox: bool, } #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/backend/windmill-worker/src/ansible_executor.rs b/backend/windmill-worker/src/ansible_executor.rs index d1e54f97ad..aa250de4ab 100644 --- a/backend/windmill-worker/src/ansible_executor.rs +++ b/backend/windmill-worker/src/ansible_executor.rs @@ -34,7 +34,7 @@ use crate::{ }, handle_child::handle_child, python_executor::{create_dependencies_dir, handle_python_reqs, uv_pip_compile}, - DISABLE_NSJAIL, DISABLE_NUSER, GIT_PATH, HOME_ENV, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, + is_sandboxing_enabled, DISABLE_NUSER, GIT_PATH, HOME_ENV, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, PY_INSTALL_DIR, TZ_ENV, }; use windmill_common::client::AuthedClient; @@ -466,7 +466,7 @@ pub async fn install_galaxy_collections( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, w_id, "ansible-galaxy role install", @@ -505,7 +505,7 @@ pub async fn install_galaxy_collections( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, w_id, "ansible-galaxy collection install", @@ -1164,7 +1164,7 @@ pub async fn handle_ansible_job( get_reserved_variables(job, &client.token, conn, parent_runnable_path).await?; let additional_python_paths_folders = additional_python_paths.join(":"); - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { let shared_deps = additional_python_paths .into_iter() .map(|pp| { @@ -1206,7 +1206,7 @@ mount {{ cmd_args.extend(inventories.iter().map(|s| s.as_str())); cmd_args.extend(cmd_options.iter().map(|s| s.as_str())); - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let wrapper = format!( r#"set -eou pipefail {0} "$@" @@ -1279,7 +1279,7 @@ fi mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "python run", diff --git a/backend/windmill-worker/src/bash_executor.rs b/backend/windmill-worker/src/bash_executor.rs index 76e5a92cf6..64270b4044 100644 --- a/backend/windmill-worker/src/bash_executor.rs +++ b/backend/windmill-worker/src/bash_executor.rs @@ -40,7 +40,8 @@ use crate::{ }, get_proxy_envs_for_lang, handle_child::handle_child, - DISABLE_NSJAIL, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, TRACING_PROXY_CA_CERT_PATH, + is_sandboxing_enabled, DISABLE_NUSER, HOME_ENV, NSJAIL_AVAILABLE, NSJAIL_PATH, PATH_ENV, + TRACING_PROXY_CA_CERT_PATH, }; use windmill_common::client::AuthedClient; use windmill_common::scripts::ScriptLang; @@ -77,10 +78,22 @@ pub async fn handle_bash_job( ) -> Result, Error> { let annotation = windmill_common::worker::BashAnnotations::parse(&content); + // Check if sandbox annotation is used but nsjail is not available + if annotation.sandbox && NSJAIL_AVAILABLE.is_none() { + return Err(Error::ExecutionErr( + "Script has #sandbox annotation but nsjail is not available on this worker. \ + Please ensure nsjail is installed or remove the #sandbox annotation." + .to_string(), + )); + } + let mut logs1 = "\n\n--- BASH CODE EXECUTION ---\n".to_string(); if annotation.docker { logs1.push_str("docker mode\n"); } + if annotation.sandbox { + logs1.push_str("sandbox mode (nsjail)\n"); + } append_logs(&job.id, &job.workspace_id, logs1, &conn).await; write_file(job_dir, "main.sh", &format!("set -e\n{content}"))?; @@ -171,7 +184,8 @@ exit $exit_status }) .unwrap_or(true); - let nsjail = !*DISABLE_NSJAIL && is_regular_job; + // Use nsjail if globally enabled OR if script has #sandbox annotation + let nsjail = (is_sandboxing_enabled() || annotation.sandbox) && is_regular_job; let child = if nsjail { let _ = write_file( job_dir, diff --git a/backend/windmill-worker/src/bun_executor.rs b/backend/windmill-worker/src/bun_executor.rs index e15aa09b46..61362a8e65 100644 --- a/backend/windmill-worker/src/bun_executor.rs +++ b/backend/windmill-worker/src/bun_executor.rs @@ -21,7 +21,7 @@ use crate::{ get_proxy_envs_for_lang, handle_child::handle_child, BUNFIG_INSTALL_SCOPES, BUN_BUNDLE_CACHE_DIR, BUN_CACHE_DIR, BUN_NO_CACHE, BUN_PATH, - DISABLE_NSJAIL, DISABLE_NUSER, HOME_ENV, NODE_BIN_PATH, NODE_PATH, NPM_CONFIG_REGISTRY, + is_sandboxing_enabled, DISABLE_NUSER, HOME_ENV, NODE_BIN_PATH, NODE_PATH, NPM_CONFIG_REGISTRY, NPM_PATH, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, }; use windmill_common::{ @@ -1022,7 +1022,7 @@ pub async fn handle_bun_job( } } MaybeLock::Unresolved { ref workspace_dependencies } => { - // if !*DISABLE_NSJAIL || !empty_trusted_deps || has_custom_config_registry { + // if is_sandboxing_enabled() || !empty_trusted_deps || has_custom_config_registry { let logs1 = "\n\n--- BUN INSTALL ---\n".to_string(); append_logs(&job.id, &job.workspace_id, logs1, conn).await; gen_bun_lockfile( @@ -1410,7 +1410,7 @@ try {{ append_logs(&job.id, &job.workspace_id, init_logs, conn).await; //do not cache local dependencies - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let _ = write_file( job_dir, "run.config.proto", @@ -1548,7 +1548,7 @@ try {{ mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "bun run", @@ -1733,7 +1733,7 @@ pub async fn start_worker( .await?; tracing::info!("dedicated worker requirements installed: {reqs}"); } - } else if !*DISABLE_NSJAIL { + } else if is_sandboxing_enabled() { logs.push_str("\n\n--- BUN INSTALL ---\n"); let _ = gen_bun_lockfile( &mut mem_peak, diff --git a/backend/windmill-worker/src/common.rs b/backend/windmill-worker/src/common.rs index 38183ed774..abcb2dbbdd 100644 --- a/backend/windmill-worker/src/common.rs +++ b/backend/windmill-worker/src/common.rs @@ -660,7 +660,7 @@ lazy_static! { pub fn build_command_with_isolation(program: &str, args: &[&str]) -> Command { use tokio::process::Command; - if *crate::ENABLE_UNSHARE_PID { + if crate::is_unshare_enabled() { if let Some(unshare_path) = crate::UNSHARE_PATH.as_ref() { let mut cmd = Command::new(unshare_path); @@ -687,7 +687,7 @@ pub fn build_command_with_isolation(program: &str, args: &[&str]) -> Command { cmd } else { panic!( - "BUG: ENABLE_UNSHARE_PID is true but UNSHARE_PATH is None. \ + "BUG: unshare isolation is enabled but UNSHARE_PATH is None. \ This should have been caught at worker startup." ); } diff --git a/backend/windmill-worker/src/csharp_executor.rs b/backend/windmill-worker/src/csharp_executor.rs index 8cc8d2c5dd..49cbd2af5a 100644 --- a/backend/windmill-worker/src/csharp_executor.rs +++ b/backend/windmill-worker/src/csharp_executor.rs @@ -32,7 +32,7 @@ use crate::{ }, get_proxy_envs_for_lang, handle_child::handle_child, - CSHARP_CACHE_DIR, DISABLE_NSJAIL, DISABLE_NUSER, DOTNET_PATH, HOME_ENV, NSJAIL_PATH, + CSHARP_CACHE_DIR, is_sandboxing_enabled, DISABLE_NUSER, DOTNET_PATH, HOME_ENV, NSJAIL_PATH, NUGET_CONFIG, PATH_ENV, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, }; #[cfg(feature = "csharp")] @@ -563,7 +563,7 @@ pub async fn handle_csharp_job( let reserved_variables = get_reserved_variables(job, &client.token, conn, parent_runnable_path).await?; - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { write_file( job_dir, "run.config.proto", @@ -661,7 +661,7 @@ pub async fn handle_csharp_job( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "csharp run", diff --git a/backend/windmill-worker/src/deno_executor.rs b/backend/windmill-worker/src/deno_executor.rs index 606ea4ec11..39ebbd6864 100644 --- a/backend/windmill-worker/src/deno_executor.rs +++ b/backend/windmill-worker/src/deno_executor.rs @@ -13,7 +13,7 @@ use crate::{ }, get_proxy_envs_for_lang, handle_child::handle_child, - DENO_CACHE_DIR, DENO_PATH, DISABLE_NSJAIL, HOME_ENV, NPM_CONFIG_REGISTRY, PATH_ENV, TZ_ENV, + is_sandboxing_enabled, DENO_CACHE_DIR, DENO_PATH, HOME_ENV, NPM_CONFIG_REGISTRY, PATH_ENV, TZ_ENV, }; use windmill_common::client::AuthedClient; @@ -364,7 +364,7 @@ try {{ let mut common_deno_proc_envs = get_common_deno_proc_envs(&client.token, base_internal_url).await; - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { common_deno_proc_envs.insert("HOME".to_string(), job_dir.to_string()); } @@ -405,7 +405,7 @@ try {{ for flag in deno_flags { args.push(flag); } - } else if !*DISABLE_NSJAIL { + } else if is_sandboxing_enabled() { args.push("--allow-net"); args.push("--allow-sys"); args.push(allow_read.as_str()); diff --git a/backend/windmill-worker/src/go_executor.rs b/backend/windmill-worker/src/go_executor.rs index d1b2bdff35..2bdc1ec17e 100644 --- a/backend/windmill-worker/src/go_executor.rs +++ b/backend/windmill-worker/src/go_executor.rs @@ -24,7 +24,7 @@ use crate::{ read_result, start_child_process, OccupancyMetrics, DEV_CONF_NSJAIL, }, handle_child::handle_child, - DISABLE_NSJAIL, DISABLE_NUSER, GOPRIVATE, GOPROXY, GO_BIN_CACHE_DIR, GO_CACHE_DIR, HOME_ENV, + is_sandboxing_enabled, DISABLE_NUSER, GOPRIVATE, GOPROXY, GO_BIN_CACHE_DIR, GO_CACHE_DIR, HOME_ENV, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, }; use windmill_common::client::AuthedClient; @@ -338,7 +338,7 @@ func Run(req Req) (interface{{}}, error){{ let reserved_variables = get_reserved_variables(job, &client.token, conn, parent_runnable_path).await?; - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let _ = write_file( job_dir, "run.config.proto", @@ -414,7 +414,7 @@ func Run(req Req) (interface{{}}, error){{ mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "go run", diff --git a/backend/windmill-worker/src/java_executor.rs b/backend/windmill-worker/src/java_executor.rs index 25ec1502ab..85019d3ac5 100644 --- a/backend/windmill-worker/src/java_executor.rs +++ b/backend/windmill-worker/src/java_executor.rs @@ -26,7 +26,7 @@ use crate::{ }, handle_child, universal_pkg_installer::{par_install_language_dependencies_all_at_once, RequiredDependency}, - COURSIER_CACHE_DIR, DISABLE_NSJAIL, DISABLE_NUSER, JAVA_CACHE_DIR, JAVA_HOME_DIR, + is_sandboxing_enabled, COURSIER_CACHE_DIR, DISABLE_NUSER, JAVA_CACHE_DIR, JAVA_HOME_DIR, JAVA_REPOSITORY_DIR, MAVEN_REPOS, NO_DEFAULT_MAVEN, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, }; use windmill_common::client::AuthedClient; @@ -420,7 +420,7 @@ async fn install<'a>( &job.id, &job.workspace_id, worker_name, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), conn, ) .await?; @@ -529,7 +529,7 @@ async fn compile<'a>( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "javac", @@ -585,7 +585,7 @@ async fn run<'a>( let reserved_variables = get_reserved_variables(job, &client.token, conn, parent_runnable_path.clone()).await?; - let child = if !cfg!(windows) && !*DISABLE_NSJAIL { + let child = if !cfg!(windows) && is_sandboxing_enabled() { append_logs( &job.id, &job.workspace_id, @@ -717,7 +717,7 @@ async fn run<'a>( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "java", diff --git a/backend/windmill-worker/src/nu_executor.rs b/backend/windmill-worker/src/nu_executor.rs index 9fc947fc70..a4320a3612 100644 --- a/backend/windmill-worker/src/nu_executor.rs +++ b/backend/windmill-worker/src/nu_executor.rs @@ -16,7 +16,7 @@ use crate::{ build_command_with_isolation, create_args_and_out_file, get_reserved_variables, read_result, start_child_process, OccupancyMetrics, DEV_CONF_NSJAIL, }, - get_proxy_envs_for_lang, handle_child, DISABLE_NSJAIL, DISABLE_NUSER, NSJAIL_PATH, PATH_ENV, + get_proxy_envs_for_lang, handle_child, is_sandboxing_enabled, DISABLE_NUSER, NSJAIL_PATH, PATH_ENV, TRACING_PROXY_CA_CERT_PATH, }; use windmill_common::client::AuthedClient; @@ -127,7 +127,7 @@ pub async fn handle_nu_job<'a>(mut args: JobHandlerInput<'a>) -> Result( ) -> Result<(), Error> { let reserved_variables = get_reserved_variables(job, &client.token, conn, parent_runnable_path.clone()).await?; - let child = if !cfg!(windows) && !*DISABLE_NSJAIL { + let child = if !cfg!(windows) && is_sandboxing_enabled() { append_logs( &job.id, &job.workspace_id, @@ -335,7 +335,7 @@ async fn run<'a>( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "nu", diff --git a/backend/windmill-worker/src/php_executor.rs b/backend/windmill-worker/src/php_executor.rs index dd6f3b202e..e98755e555 100644 --- a/backend/windmill-worker/src/php_executor.rs +++ b/backend/windmill-worker/src/php_executor.rs @@ -22,7 +22,7 @@ use crate::{ get_reserved_variables, read_result, start_child_process, MaybeLock, OccupancyMetrics, }, handle_child::handle_child, - COMPOSER_CACHE_DIR, COMPOSER_PATH, DISABLE_NSJAIL, DISABLE_NUSER, NSJAIL_PATH, PHP_PATH, + COMPOSER_CACHE_DIR, COMPOSER_PATH, is_sandboxing_enabled, DISABLE_NUSER, NSJAIL_PATH, PHP_PATH, }; use windmill_common::client::AuthedClient; @@ -293,7 +293,7 @@ try {{ let (reserved_variables, _) = tokio::try_join!(reserved_variables_args_out_f, write_wrapper_f)?; - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let _ = write_file( job_dir, "run.config.proto", @@ -347,7 +347,7 @@ try {{ mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "php run", diff --git a/backend/windmill-worker/src/pwsh_executor.rs b/backend/windmill-worker/src/pwsh_executor.rs index 0be37a7ac3..cd6ace71e5 100644 --- a/backend/windmill-worker/src/pwsh_executor.rs +++ b/backend/windmill-worker/src/pwsh_executor.rs @@ -27,7 +27,7 @@ use crate::{ read_file_content, start_child_process, OccupancyMetrics, }, handle_child::handle_child, - DISABLE_NSJAIL, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, POWERSHELL_CACHE_DIR, + is_sandboxing_enabled, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, POWERSHELL_CACHE_DIR, POWERSHELL_PATH, POWERSHELL_REPO_PAT, POWERSHELL_REPO_URL, PROXY_ENVS, TZ_ENV, }; @@ -501,7 +501,7 @@ $env:PSModulePath = \"{};$PSModulePathBackup\"", }) .unwrap_or(true); - let nsjail = !*DISABLE_NSJAIL && is_regular_job; + let nsjail = is_sandboxing_enabled() && is_regular_job; let child = if nsjail { let _ = write_file( job_dir, @@ -617,7 +617,7 @@ $env:PSModulePath = \"{};$PSModulePathBackup\"", mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "powershell run", diff --git a/backend/windmill-worker/src/python_executor.rs b/backend/windmill-worker/src/python_executor.rs index 8dc689a3c2..4d2bd1cb25 100644 --- a/backend/windmill-worker/src/python_executor.rs +++ b/backend/windmill-worker/src/python_executor.rs @@ -132,9 +132,10 @@ use crate::{ }, get_proxy_envs_for_lang, handle_child::handle_child, + is_sandboxing_enabled, worker_utils::ping_job_status, - PyV, DISABLE_NSJAIL, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, PIP_EXTRA_INDEX_URL, - PIP_INDEX_URL, PROXY_ENVS, PY_INSTALL_DIR, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, UV_CACHE_DIR, + PyV, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, PIP_EXTRA_INDEX_URL, PIP_INDEX_URL, + PROXY_ENVS, PY_INSTALL_DIR, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, UV_CACHE_DIR, UV_INDEX_STRATEGY, }; use windmill_common::client::AuthedClient; @@ -320,7 +321,6 @@ pub async fn uv_pip_compile( #[cfg(unix)] let uv_cmd = UV_PATH.as_str(); - let mut child_cmd = Command::new(uv_cmd); child_cmd .current_dir(job_dir) @@ -776,7 +776,7 @@ except BaseException as e: #[cfg(windows)] let additional_python_paths_folders = additional_python_paths_folders.replace(":", ";"); - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { let shared_deps = additional_python_paths .into_iter() .map(|pp| { @@ -820,7 +820,7 @@ mount {{ job.id ); - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let mut nsjail_cmd = Command::new(NSJAIL_PATH.as_str()); nsjail_cmd .current_dir(job_dir) @@ -885,7 +885,7 @@ mount {{ mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "python run", @@ -1355,9 +1355,11 @@ async fn spawn_uv_install( worker_dir: &str, ) -> Result, Error> { let uv_index_strategy_guard = UV_INDEX_STRATEGY.read().await.clone(); - let uv_index_strategy = uv_index_strategy_guard.as_deref().unwrap_or("unsafe-best-match"); + let uv_index_strategy = uv_index_strategy_guard + .as_deref() + .unwrap_or("unsafe-best-match"); - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { tracing::info!( workspace_id = %w_id, "starting nsjail" @@ -1707,7 +1709,7 @@ pub async fn handle_python_reqs( let mut local_mem_peak = 0; for pid_o in pids.lock().await.iter() { if pid_o.is_some(){ - let mem = crate::handle_child::get_mem_peak(*pid_o, !*DISABLE_NSJAIL).await; + let mem = crate::handle_child::get_mem_peak(*pid_o, is_sandboxing_enabled()).await; if mem < 0 { tracing::warn!( workspace_id = %w_id_2, @@ -1817,7 +1819,7 @@ pub async fn handle_python_reqs( } // Do we use Nsjail? - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { logs.push_str(&format!( "\nStarting isolated installation... ({} tasks in parallel) \n", parallel_limit @@ -2065,7 +2067,7 @@ pub async fn handle_python_reqs( #[cfg(not(all(feature = "enterprise", feature = "parquet", unix)))] let s3_push = false; - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { let _ = std::fs::remove_file(format!("{job_dir}/{req}.config.proto")); } diff --git a/backend/windmill-worker/src/ruby_executor.rs b/backend/windmill-worker/src/ruby_executor.rs index 9cd656f9e3..13f7815c12 100644 --- a/backend/windmill-worker/src/ruby_executor.rs +++ b/backend/windmill-worker/src/ruby_executor.rs @@ -29,7 +29,7 @@ use crate::{ get_proxy_envs_for_lang, handle_child::{self}, universal_pkg_installer::{par_install_language_dependencies_seq, RequiredDependency}, - DISABLE_NSJAIL, DISABLE_NUSER, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, RUBY_CACHE_DIR, RUBY_REPOS, + is_sandboxing_enabled, DISABLE_NUSER, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, RUBY_CACHE_DIR, RUBY_REPOS, TRACING_PROXY_CA_CERT_PATH, }; use windmill_common::scripts::ScriptLang; @@ -330,7 +330,7 @@ Your Gemfile syntax will continue to work as-is." ) .await; - let mut cmd = if !cfg!(windows) && !*DISABLE_NSJAIL { + let mut cmd = if !cfg!(windows) && is_sandboxing_enabled() { let nsjail_proto = format!("{}.lock.config.proto", Uuid::new_v4()); let _ = write_file( &job_dir, @@ -401,7 +401,7 @@ Your Gemfile syntax will continue to work as-is." mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, w_id, "bundle", @@ -589,7 +589,7 @@ async fn install<'a>( } let job_dir = job_dir.to_owned(); - let jailed = !cfg!(windows) && !*DISABLE_NSJAIL; + let jailed = !cfg!(windows) && is_sandboxing_enabled(); let RubyAnnotations { verbose } = RubyAnnotations::parse(&inner_content); let repos = RUBY_REPOS.read().await.clone().unwrap_or_default(); let (envs, reserved_variables) = ( @@ -751,7 +751,7 @@ async fn run<'a>( let reserved_variables = get_reserved_variables(job, &client.token, conn, parent_runnable_path.clone()).await?; - let child = if !cfg!(windows) && !*DISABLE_NSJAIL { + let child = if !cfg!(windows) && is_sandboxing_enabled() { append_logs( &job.id, &job.workspace_id, @@ -858,7 +858,7 @@ mount {{ mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "ruby", diff --git a/backend/windmill-worker/src/rust_executor.rs b/backend/windmill-worker/src/rust_executor.rs index 158e2d5c5c..3146fef200 100644 --- a/backend/windmill-worker/src/rust_executor.rs +++ b/backend/windmill-worker/src/rust_executor.rs @@ -25,8 +25,8 @@ use crate::{ }, get_proxy_envs_for_lang, handle_child::handle_child, - CARGO_REGISTRIES, DISABLE_NSJAIL, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, PROXY_ENVS, - RUST_CACHE_DIR, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, + is_sandboxing_enabled, CARGO_REGISTRIES, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV, + PROXY_ENVS, RUST_CACHE_DIR, TRACING_PROXY_CA_CERT_PATH, TZ_ENV, }; use windmill_common::client::AuthedClient; use windmill_common::scripts::ScriptLang; @@ -215,7 +215,7 @@ async fn get_build_dir( if !is_preview || *NO_SHARED_BUILD_DIR { None } else { - if *DISABLE_NSJAIL { + if !is_sandboxing_enabled() { // If nsjail is disabled then entire worker has shared build directory // It drastically improves cache hit-rate. Some((format!("{RUST_CACHE_DIR}/build/{worker_name}"), true)) @@ -332,7 +332,7 @@ pub async fn build_rust_crate( let build_dir = get_build_dir(job, job_dir, conn, worker_name, is_preview).await?; - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let _ = write_file( job_dir, "download.config.proto", @@ -541,7 +541,7 @@ pub async fn handle_rust_job( let logs2 = format!("{cache_logs}\n\n--- RUST CODE EXECUTION ---\n"); append_logs(&job.id, &job.workspace_id, logs2, conn).await; - let child = if !*DISABLE_NSJAIL { + let child = if is_sandboxing_enabled() { let _ = write_file( job_dir, "run.config.proto", @@ -599,7 +599,7 @@ pub async fn handle_rust_job( mem_peak, canceled_by, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), worker_name, &job.workspace_id, "rust run", diff --git a/backend/windmill-worker/src/universal_pkg_installer.rs b/backend/windmill-worker/src/universal_pkg_installer.rs index d4e33b4a72..c16583ff76 100644 --- a/backend/windmill-worker/src/universal_pkg_installer.rs +++ b/backend/windmill-worker/src/universal_pkg_installer.rs @@ -12,7 +12,7 @@ use tokio::{ use uuid::Uuid; use windmill_common::{error, worker::Connection}; -use crate::{common::start_child_process, DISABLE_NSJAIL}; +use crate::{common::start_child_process, is_sandboxing_enabled}; #[allow(dead_code)] #[derive(Clone, Debug)] @@ -151,7 +151,7 @@ pub async fn par_install_language_dependencies_all_at_once< // TODO: Return canceld_by_ref &mut None, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), &worker_name, &w_id, &installer_executable_name, @@ -580,7 +580,7 @@ async fn try_install_one_detached<'a, T: Clone + std::marker::Send + Sync + 'a + // TODO: Return canceld_by_ref &mut None, child, - !*DISABLE_NSJAIL, + is_sandboxing_enabled(), &worker_name, &w_id, &installer_executable_name, diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index 9221bfc590..00535dbd17 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -59,7 +59,7 @@ use std::{ collections::{HashMap, HashSet}, fmt::Display, sync::{ - atomic::{AtomicBool, AtomicU16, Ordering}, + atomic::{AtomicBool, AtomicU8, AtomicU16, Ordering}, Arc, }, time::Duration, @@ -325,11 +325,19 @@ lazy_static::lazy_static! { .and_then(|x| x.parse::().ok()) .unwrap_or(true); + /// Global setting for job isolation mode. 0=undefined (use env vars), 1=none, 2=unshare, 3=nsjail + pub static ref JOB_ISOLATION: AtomicU8 = AtomicU8::new(JobIsolationLevel::Undefined as u8); + pub static ref ENABLE_UNSHARE_PID: bool = std::env::var("ENABLE_UNSHARE_PID") .ok() .and_then(|x| x.parse::().ok()) .unwrap_or(false); + pub static ref FAVOR_UNSHARE_PID: bool = std::env::var("FAVOR_UNSHARE_PID") + .ok() + .and_then(|x| x.parse::().ok()) + .unwrap_or(false); + pub static ref UNSHARE_TINI_PATH: String = { std::env::var("UNSHARE_TINI_PATH").unwrap_or_else(|_| "tini".to_string()) }; @@ -467,47 +475,41 @@ lazy_static::lazy_static! { }; pub static ref NSJAIL_AVAILABLE: Option = { - if *DISABLE_NSJAIL { - None - } else { - let nsjail_path = NSJAIL_PATH.as_str(); + let nsjail_path = NSJAIL_PATH.as_str(); - let test_result = std::process::Command::new(nsjail_path) - .arg("--help") - .output(); + let test_result = std::process::Command::new(nsjail_path) + .arg("--help") + .output(); - match test_result { - Ok(output) if output.status.success() => { - tracing::info!("NSJAIL sandboxing available at: {}", nsjail_path); - Some(nsjail_path.to_string()) - }, - Ok(output) => { - let stderr = String::from_utf8_lossy(&output.stderr); - tracing::warn!( - "nsjail test failed: {}. Jobs will run without nsjail sandboxing. \ - nsjail should be included in all standard windmill images. \ - Check that the nsjail binary is installed and working correctly.", - stderr.trim() + match test_result { + Ok(output) if output.status.success() => { + tracing::info!("nsjail available at: {}", nsjail_path); + Some(nsjail_path.to_string()) + }, + Ok(output) => { + let stderr = String::from_utf8_lossy(&output.stderr); + tracing::warn!( + "nsjail test failed: {}. \ + nsjail should be included in all standard windmill images. \ + Check that the nsjail binary is installed and working correctly.", + stderr.trim() + ); + None + }, + Err(e) => { + if e.kind() == std::io::ErrorKind::NotFound { + tracing::info!( + "nsjail not found at '{}'. Sandboxing will not be available.", + nsjail_path + ); + } else { + tracing::warn!( + "Failed to test nsjail at '{}': {}.", + nsjail_path, + e ); - None - }, - Err(e) => { - if e.kind() == std::io::ErrorKind::NotFound { - tracing::warn!( - "nsjail not found at '{}'. Jobs will run without nsjail sandboxing. \ - nsjail should be included in all standard windmill images. \ - Check that the nsjail binary is installed at the expected path.", - nsjail_path - ); - } else { - tracing::warn!( - "Failed to test nsjail at '{}': {}. Jobs will run without nsjail sandboxing.", - nsjail_path, - e - ); - } - None } + None } } }; @@ -631,6 +633,69 @@ lazy_static::lazy_static! { type Envs = Vec<(String, String)>; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +pub enum JobIsolationLevel { + /// Not set via global setting; fall back to env vars (DISABLE_NSJAIL, FAVOR_UNSHARE_PID) + Undefined = 0, + /// No isolation + None = 1, + /// PID namespace isolation via unshare + Unshare = 2, + /// Full nsjail sandboxing + NsjailSandboxing = 3, +} + +impl JobIsolationLevel { + pub fn from_u8(v: u8) -> Self { + match v { + 1 => Self::None, + 2 => Self::Unshare, + 3 => Self::NsjailSandboxing, + _ => Self::Undefined, + } + } + + pub fn from_str(s: &str) -> Self { + match s { + "none" => Self::None, + "unshare" => Self::Unshare, + "nsjail_sandboxing" => Self::NsjailSandboxing, + _ => Self::Undefined, + } + } +} + +pub fn get_job_isolation() -> JobIsolationLevel { + JobIsolationLevel::from_u8(JOB_ISOLATION.load(Ordering::Relaxed)) +} + +/// Returns true if nsjail sandboxing should be used for job execution. +/// DISABLE_NSJAIL=false forces nsjail regardless of the global setting. +pub fn is_sandboxing_enabled() -> bool { + if !*DISABLE_NSJAIL { + return true; + } + match get_job_isolation() { + JobIsolationLevel::NsjailSandboxing => true, + _ => false, + } +} + +/// Returns true if unshare PID isolation should be used (when not using nsjail). +/// ENABLE_UNSHARE_PID forces unshare regardless of the global setting. +/// FAVOR_UNSHARE_PID uses unshare only when the global setting is not set. +pub fn is_unshare_enabled() -> bool { + if *ENABLE_UNSHARE_PID { + return true; + } + match get_job_isolation() { + JobIsolationLevel::Unshare => true, + JobIsolationLevel::Undefined => *FAVOR_UNSHARE_PID, + _ => false, + } +} + /// Check if OTEL tracing proxy is enabled for a specific language (EE only) pub async fn is_otel_tracing_proxy_enabled_for_lang(lang: &ScriptLang) -> bool { cfg!(all(feature = "private", feature = "enterprise")) && { @@ -1269,7 +1334,7 @@ pub async fn run_worker( base_internal_url: &str, ) { #[cfg(not(feature = "enterprise"))] - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { tracing::warn!( worker = %worker_name, hostname = %hostname, "NSJAIL to sandbox process in untrusted environments is an enterprise feature but allowed to be used for testing purposes" @@ -1278,8 +1343,7 @@ pub async fn run_worker( // Force UNSHARE_PATH initialization now to fail-fast if unshare doesn't work // This ensures we panic at startup rather than lazily when first accessed during job execution - if *ENABLE_UNSHARE_PID { - // Access UNSHARE_PATH to trigger lazy_static initialization and test + if is_unshare_enabled() || *ENABLE_UNSHARE_PID || *FAVOR_UNSHARE_PID { let _ = &*UNSHARE_PATH; } @@ -1330,7 +1394,7 @@ pub async fn run_worker( create_directory_async(&worker_dir).await; - if !*DISABLE_NSJAIL { + if is_sandboxing_enabled() { let _ = write_file( &worker_dir, "download_deps.py.sh", @@ -3105,9 +3169,17 @@ pub async fn handle_queued_job( let mut canceled_by: Option = None; // println!("handle queue {:?}", SystemTime::now()); + let isolation_label = if is_sandboxing_enabled() { + "nsjail" + } else if is_unshare_enabled() { + "unshare" + } else { + "none" + }; + logs.push_str(&format!( - "job={} {}={} worker={} hostname={}\n", - &job.id, *LOG_TAG_NAME, &job.tag, &worker_name, &hostname + "job={} {}={} worker={} hostname={} isolation={}\n", + &job.id, *LOG_TAG_NAME, &job.tag, &worker_name, &hostname, isolation_label )); if *NO_LOGS_AT_ALL { diff --git a/backend/windmill-worker/src/worker_utils.rs b/backend/windmill-worker/src/worker_utils.rs index 3a52f70094..396b9273ab 100644 --- a/backend/windmill-worker/src/worker_utils.rs +++ b/backend/windmill-worker/src/worker_utils.rs @@ -182,10 +182,9 @@ pub async fn insert_ping( let vcpus = get_vcpus(); let memory = get_memory(); - // Determine job isolation method - let job_isolation = if crate::NSJAIL_AVAILABLE.is_some() { + let job_isolation = if crate::is_sandboxing_enabled() { Some("nsjail".to_string()) - } else if *crate::ENABLE_UNSHARE_PID && crate::UNSHARE_PATH.is_some() { + } else if crate::is_unshare_enabled() { Some("unshare".to_string()) } else { Some("none".to_string()) @@ -256,9 +255,9 @@ pub async fn update_worker_ping_from_job( let occupancy_rate_5m = occupancy.as_ref().and_then(|x| x.occupancy_rate_5m); let occupancy_rate_30m = occupancy.as_ref().and_then(|x| x.occupancy_rate_30m); - let job_isolation = if crate::NSJAIL_AVAILABLE.is_some() { + let job_isolation = if crate::is_sandboxing_enabled() { Some("nsjail".to_string()) - } else if *crate::ENABLE_UNSHARE_PID && crate::UNSHARE_PATH.is_some() { + } else if crate::is_unshare_enabled() { Some("unshare".to_string()) } else { Some("none".to_string()) diff --git a/frontend/src/lib/components/EEOnly.svelte b/frontend/src/lib/components/EEOnly.svelte index c92377031c..d519d5e15b 100644 --- a/frontend/src/lib/components/EEOnly.svelte +++ b/frontend/src/lib/components/EEOnly.svelte @@ -10,7 +10,7 @@ - EE only + EE {#snippet text()} {#if children} {@render children()} diff --git a/frontend/src/lib/components/instanceSettings.ts b/frontend/src/lib/components/instanceSettings.ts index 82a39762d9..aad66331eb 100644 --- a/frontend/src/lib/components/instanceSettings.ts +++ b/frontend/src/lib/components/instanceSettings.ts @@ -193,6 +193,28 @@ export const settings: Record = { } ], Jobs: [ + { + label: 'Job Isolation', + key: 'job_isolation', + fieldType: 'select', + description: + 'Isolation mode for job execution. None: no isolation. Unshare: PID namespace isolation via unshare. Nsjail: full nsjail sandboxing. Learn more', + storage: 'setting', + select_items: [ + { + label: 'None', + value: 'none' + }, + { + label: 'Unshare', + value: 'unshare' + }, + { + label: 'Nsjail', + value: 'nsjail_sandboxing' + } + ] + }, { label: 'Default timeout', key: 'job_default_timeout', @@ -596,6 +618,7 @@ export const settingsKeys = Object.keys(settings) // --- Sidebar navigation for instance settings --- export const instanceSettingsNavigationGroups = [ { + title: 'Core', items: [ { id: 'users', @@ -608,6 +631,12 @@ export const instanceSettingsNavigationGroups = [ label: 'General', aiId: 'instance-settings-general', aiDescription: 'Instance general settings' + }, + { + id: 'jobs', + label: 'Jobs', + aiId: 'instance-settings-jobs', + aiDescription: 'Instance jobs settings' } ] }, @@ -688,12 +717,6 @@ export const instanceSettingsNavigationGroups = [ { title: 'Advanced', items: [ - { - id: 'jobs', - label: 'Jobs', - aiId: 'instance-settings-jobs', - aiDescription: 'Instance jobs settings' - }, { id: 'private_hub', label: 'Private Hub',