From 2edba180384560b749e461e096e6f8ab3904fa7e Mon Sep 17 00:00:00 2001 From: Guillaume Bouvignies Date: Sat, 13 Jan 2024 00:06:54 +0100 Subject: [PATCH] feat: Tag override for scheduled scripts (#2998) * feat: Tag override for scheduled scripts * Refactor WorkerTagPicker to component * Fix test --- ...be4da5447020e39398deedbcca9121492834a.json | 6 ++ ...468af2364f5d2075aab48787b93e5774336d.json} | 15 +++- ...b558db50f5f96b1e8eff0b10e4398566f325.json} | 13 +++- ...020e680c45043b0736ad0153ee261a151dd90.json | 8 +- ...54dc03f93e261d25969d66aa48e9d0502960f.json | 8 +- ...29d94c546fe531e7edd3e91da4978af5442fb.json | 8 +- ...35db9906617eb9c98aaf58a55d9681ffb85e3.json | 8 +- ...076c11a78d0206af2af20685c691d4d9520bb.json | 8 +- ...b22373603c9d01f77047b3553bde125bf71e8.json | 8 +- ...4a4874e6d7807d43fa6ea7b8408cad9e97480.json | 8 +- ...0240112162019_schedule_custom_tag.down.sql | 2 + .../20240112162019_schedule_custom_tag.up.sql | 2 + backend/tests/worker.rs | 9 ++- backend/windmill-api/openapi-deref.yaml | 6 ++ backend/windmill-api/openapi.yaml | 6 ++ backend/windmill-api/src/flows.rs | 8 +- backend/windmill-api/src/schedule.rs | 14 +++- backend/windmill-common/src/flows.rs | 1 + backend/windmill-common/src/jobs.rs | 1 + backend/windmill-common/src/schedule.rs | 1 + backend/windmill-queue/src/jobs.rs | 3 + backend/windmill-queue/src/schedule.rs | 3 +- backend/windmill-worker/src/worker_flow.rs | 14 ++-- .../aws-ecs-terraform/windmill_server.tf | 2 +- .../windmill_worker_basic.tf | 2 +- .../windmill_worker_high_performance.tf | 2 +- .../windmill_worker_native.tf | 2 +- .../src/lib/components/AssignableTags.svelte | 3 +- .../lib/components/ScheduleEditorInner.svelte | 19 ++++- .../src/lib/components/ScriptBuilder.svelte | 78 +------------------ .../src/lib/components/WorkerTagPicker.svelte | 70 +++++++++++++++++ .../flows/content/FlowSettings.svelte | 61 +-------------- 32 files changed, 231 insertions(+), 168 deletions(-) rename backend/.sqlx/{query-6bb9e6cab7034bf28ef2597445dc617b60c49b42568fdb975cf2d2dc8702167e.json => query-597335a4a1eda7799303e0d930b5468af2364f5d2075aab48787b93e5774336d.json} (89%) rename backend/.sqlx/{query-b7ed211ec7611c994a49565e46e5893788bcf49b2c9357fbc45a8353a7c84f48.json => query-90435687152ccd37db7e0a6a5baeb558db50f5f96b1e8eff0b10e4398566f325.json} (90%) create mode 100644 backend/migrations/20240112162019_schedule_custom_tag.down.sql create mode 100644 backend/migrations/20240112162019_schedule_custom_tag.up.sql create mode 100644 frontend/src/lib/components/WorkerTagPicker.svelte diff --git a/backend/.sqlx/query-4422b7183ede17a9cbde4afae41be4da5447020e39398deedbcca9121492834a.json b/backend/.sqlx/query-4422b7183ede17a9cbde4afae41be4da5447020e39398deedbcca9121492834a.json index f89c4d0491..f69342b346 100644 --- a/backend/.sqlx/query-4422b7183ede17a9cbde4afae41be4da5447020e39398deedbcca9121492834a.json +++ b/backend/.sqlx/query-4422b7183ede17a9cbde4afae41be4da5447020e39398deedbcca9121492834a.json @@ -125,6 +125,11 @@ }, { "ordinal": 24, + "name": "tag", + "type_info": "Varchar" + }, + { + "ordinal": 25, "name": "jobs", "type_info": "JsonArray" } @@ -161,6 +166,7 @@ true, true, false, + true, null ] }, diff --git a/backend/.sqlx/query-6bb9e6cab7034bf28ef2597445dc617b60c49b42568fdb975cf2d2dc8702167e.json b/backend/.sqlx/query-597335a4a1eda7799303e0d930b5468af2364f5d2075aab48787b93e5774336d.json similarity index 89% rename from backend/.sqlx/query-6bb9e6cab7034bf28ef2597445dc617b60c49b42568fdb975cf2d2dc8702167e.json rename to backend/.sqlx/query-597335a4a1eda7799303e0d930b5468af2364f5d2075aab48787b93e5774336d.json index 64d6e6b88a..bfb297e1fd 100644 --- a/backend/.sqlx/query-6bb9e6cab7034bf28ef2597445dc617b60c49b42568fdb975cf2d2dc8702167e.json +++ b/backend/.sqlx/query-597335a4a1eda7799303e0d930b5468af2364f5d2075aab48787b93e5774336d.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO schedule (workspace_id, path, schedule, timezone, edited_by, script_path, is_flow, args, enabled, email, on_failure, on_failure_times, on_failure_exact, on_failure_extra_args, on_recovery, on_recovery_times, on_recovery_extra_args, ws_error_handler_muted, retry, summary, no_flow_overlap ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21 ) RETURNING *", + "query": "INSERT INTO schedule (workspace_id, path, schedule, timezone, edited_by, script_path, is_flow, args, enabled, email, on_failure, on_failure_times, on_failure_exact, on_failure_extra_args, on_recovery, on_recovery_times, on_recovery_extra_args, ws_error_handler_muted, retry, summary, no_flow_overlap, tag ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22 ) RETURNING *", "describe": { "columns": [ { @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -146,7 +151,8 @@ "Bool", "Jsonb", "Varchar", - "Bool" + "Bool", + "Varchar" ] }, "nullable": [ @@ -173,8 +179,9 @@ false, true, true, - false + false, + true ] }, - "hash": "6bb9e6cab7034bf28ef2597445dc617b60c49b42568fdb975cf2d2dc8702167e" + "hash": "597335a4a1eda7799303e0d930b5468af2364f5d2075aab48787b93e5774336d" } diff --git a/backend/.sqlx/query-b7ed211ec7611c994a49565e46e5893788bcf49b2c9357fbc45a8353a7c84f48.json b/backend/.sqlx/query-90435687152ccd37db7e0a6a5baeb558db50f5f96b1e8eff0b10e4398566f325.json similarity index 90% rename from backend/.sqlx/query-b7ed211ec7611c994a49565e46e5893788bcf49b2c9357fbc45a8353a7c84f48.json rename to backend/.sqlx/query-90435687152ccd37db7e0a6a5baeb558db50f5f96b1e8eff0b10e4398566f325.json index 9d82879533..a707e0d89e 100644 --- a/backend/.sqlx/query-b7ed211ec7611c994a49565e46e5893788bcf49b2c9357fbc45a8353a7c84f48.json +++ b/backend/.sqlx/query-90435687152ccd37db7e0a6a5baeb558db50f5f96b1e8eff0b10e4398566f325.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "UPDATE schedule SET schedule = $1, timezone = $2, args = $3, on_failure = $4, on_failure_times = $5, on_failure_exact = $6, on_failure_extra_args = $7, on_recovery = $8, on_recovery_times = $9, on_recovery_extra_args = $10, ws_error_handler_muted = $11, retry = $12, summary = $13, no_flow_overlap = $14 WHERE path = $15 AND workspace_id = $16 RETURNING *", + "query": "UPDATE schedule SET schedule = $1, timezone = $2, args = $3, on_failure = $4, on_failure_times = $5, on_failure_exact = $6, on_failure_extra_args = $7, on_recovery = $8, on_recovery_times = $9, on_recovery_extra_args = $10, ws_error_handler_muted = $11, retry = $12, summary = $13, no_flow_overlap = $14, tag = $15\n WHERE path = $16 AND workspace_id = $17 RETURNING *", "describe": { "columns": [ { @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -140,6 +145,7 @@ "Jsonb", "Varchar", "Bool", + "Varchar", "Text", "Text" ] @@ -168,8 +174,9 @@ false, true, true, - false + false, + true ] }, - "hash": "b7ed211ec7611c994a49565e46e5893788bcf49b2c9357fbc45a8353a7c84f48" + "hash": "90435687152ccd37db7e0a6a5baeb558db50f5f96b1e8eff0b10e4398566f325" } diff --git a/backend/.sqlx/query-911b1e1f2a5ba6d5159916e5598020e680c45043b0736ad0153ee261a151dd90.json b/backend/.sqlx/query-911b1e1f2a5ba6d5159916e5598020e680c45043b0736ad0153ee261a151dd90.json index eba555aa49..1447148a44 100644 --- a/backend/.sqlx/query-911b1e1f2a5ba6d5159916e5598020e680c45043b0736ad0153ee261a151dd90.json +++ b/backend/.sqlx/query-911b1e1f2a5ba6d5159916e5598020e680c45043b0736ad0153ee261a151dd90.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -155,7 +160,8 @@ false, true, true, - false + false, + true ] }, "hash": "911b1e1f2a5ba6d5159916e5598020e680c45043b0736ad0153ee261a151dd90" diff --git a/backend/.sqlx/query-96dc1cd308f3c21cfb50b88048054dc03f93e261d25969d66aa48e9d0502960f.json b/backend/.sqlx/query-96dc1cd308f3c21cfb50b88048054dc03f93e261d25969d66aa48e9d0502960f.json index d0d95c1094..71548662e2 100644 --- a/backend/.sqlx/query-96dc1cd308f3c21cfb50b88048054dc03f93e261d25969d66aa48e9d0502960f.json +++ b/backend/.sqlx/query-96dc1cd308f3c21cfb50b88048054dc03f93e261d25969d66aa48e9d0502960f.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -156,7 +161,8 @@ false, true, true, - false + false, + true ] }, "hash": "96dc1cd308f3c21cfb50b88048054dc03f93e261d25969d66aa48e9d0502960f" diff --git a/backend/.sqlx/query-aa2800113a8a8805f47cdc1dd0f29d94c546fe531e7edd3e91da4978af5442fb.json b/backend/.sqlx/query-aa2800113a8a8805f47cdc1dd0f29d94c546fe531e7edd3e91da4978af5442fb.json index b0a50e53df..da3f5abd58 100644 --- a/backend/.sqlx/query-aa2800113a8a8805f47cdc1dd0f29d94c546fe531e7edd3e91da4978af5442fb.json +++ b/backend/.sqlx/query-aa2800113a8a8805f47cdc1dd0f29d94c546fe531e7edd3e91da4978af5442fb.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -154,7 +159,8 @@ false, true, true, - false + false, + true ] }, "hash": "aa2800113a8a8805f47cdc1dd0f29d94c546fe531e7edd3e91da4978af5442fb" diff --git a/backend/.sqlx/query-c10348d26e3e3dc9e345d9044db35db9906617eb9c98aaf58a55d9681ffb85e3.json b/backend/.sqlx/query-c10348d26e3e3dc9e345d9044db35db9906617eb9c98aaf58a55d9681ffb85e3.json index 45d8398802..8f1405fb77 100644 --- a/backend/.sqlx/query-c10348d26e3e3dc9e345d9044db35db9906617eb9c98aaf58a55d9681ffb85e3.json +++ b/backend/.sqlx/query-c10348d26e3e3dc9e345d9044db35db9906617eb9c98aaf58a55d9681ffb85e3.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -155,7 +160,8 @@ false, true, true, - false + false, + true ] }, "hash": "c10348d26e3e3dc9e345d9044db35db9906617eb9c98aaf58a55d9681ffb85e3" diff --git a/backend/.sqlx/query-dd74fa9468b5fe8c8ad657ded06076c11a78d0206af2af20685c691d4d9520bb.json b/backend/.sqlx/query-dd74fa9468b5fe8c8ad657ded06076c11a78d0206af2af20685c691d4d9520bb.json index fb290de9fa..4b08680ee7 100644 --- a/backend/.sqlx/query-dd74fa9468b5fe8c8ad657ded06076c11a78d0206af2af20685c691d4d9520bb.json +++ b/backend/.sqlx/query-dd74fa9468b5fe8c8ad657ded06076c11a78d0206af2af20685c691d4d9520bb.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -155,7 +160,8 @@ false, true, true, - false + false, + true ] }, "hash": "dd74fa9468b5fe8c8ad657ded06076c11a78d0206af2af20685c691d4d9520bb" diff --git a/backend/.sqlx/query-eced0a09ba547ce1dccb54a5419b22373603c9d01f77047b3553bde125bf71e8.json b/backend/.sqlx/query-eced0a09ba547ce1dccb54a5419b22373603c9d01f77047b3553bde125bf71e8.json index be594f4b98..25632eefec 100644 --- a/backend/.sqlx/query-eced0a09ba547ce1dccb54a5419b22373603c9d01f77047b3553bde125bf71e8.json +++ b/backend/.sqlx/query-eced0a09ba547ce1dccb54a5419b22373603c9d01f77047b3553bde125bf71e8.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -155,7 +160,8 @@ false, true, true, - false + false, + true ] }, "hash": "eced0a09ba547ce1dccb54a5419b22373603c9d01f77047b3553bde125bf71e8" diff --git a/backend/.sqlx/query-fdd3710a381dac33ef5ee5ec5564a4874e6d7807d43fa6ea7b8408cad9e97480.json b/backend/.sqlx/query-fdd3710a381dac33ef5ee5ec5564a4874e6d7807d43fa6ea7b8408cad9e97480.json index b0dafb0da1..bd5ed64a3d 100644 --- a/backend/.sqlx/query-fdd3710a381dac33ef5ee5ec5564a4874e6d7807d43fa6ea7b8408cad9e97480.json +++ b/backend/.sqlx/query-fdd3710a381dac33ef5ee5ec5564a4874e6d7807d43fa6ea7b8408cad9e97480.json @@ -122,6 +122,11 @@ "ordinal": 23, "name": "no_flow_overlap", "type_info": "Bool" + }, + { + "ordinal": 24, + "name": "tag", + "type_info": "Varchar" } ], "parameters": { @@ -153,7 +158,8 @@ false, true, true, - false + false, + true ] }, "hash": "fdd3710a381dac33ef5ee5ec5564a4874e6d7807d43fa6ea7b8408cad9e97480" diff --git a/backend/migrations/20240112162019_schedule_custom_tag.down.sql b/backend/migrations/20240112162019_schedule_custom_tag.down.sql new file mode 100644 index 0000000000..a6ee0134c5 --- /dev/null +++ b/backend/migrations/20240112162019_schedule_custom_tag.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +ALTER TABLE schedule DROP COLUMN tag; diff --git a/backend/migrations/20240112162019_schedule_custom_tag.up.sql b/backend/migrations/20240112162019_schedule_custom_tag.up.sql new file mode 100644 index 0000000000..1aa2d8382b --- /dev/null +++ b/backend/migrations/20240112162019_schedule_custom_tag.up.sql @@ -0,0 +1,2 @@ +-- Add up migration script here +ALTER TABLE schedule ADD COLUMN tag VARCHAR(50); diff --git a/backend/tests/worker.rs b/backend/tests/worker.rs index ee77635d9f..7a4448d4ad 100644 --- a/backend/tests/worker.rs +++ b/backend/tests/worker.rs @@ -2873,7 +2873,7 @@ async fn test_script_schedule_handlers(db: Pool) { retry: None, no_flow_overlap: None, summary: None, - + tag: None, }; let _ = client.create_schedule("test-workspace", &schedule).await; @@ -2936,7 +2936,8 @@ async fn test_script_schedule_handlers(db: Pool) { ws_error_handler_muted: None, retry: None, summary: None, - no_flow_overlap: None + no_flow_overlap: None, + tag: None, }, ) .await @@ -3016,6 +3017,7 @@ async fn test_flow_schedule_handlers(db: Pool) { retry: None, no_flow_overlap: None, summary: None, + tag: None, }; let _ = client.create_schedule("test-workspace", &schedule).await; @@ -3079,7 +3081,8 @@ async fn test_flow_schedule_handlers(db: Pool) { ws_error_handler_muted: None, retry: None, summary: None, - no_flow_overlap: None + no_flow_overlap: None, + tag: None, }, ) .await diff --git a/backend/windmill-api/openapi-deref.yaml b/backend/windmill-api/openapi-deref.yaml index cf4f74ce8e..af1cf46a31 100644 --- a/backend/windmill-api/openapi-deref.yaml +++ b/backend/windmill-api/openapi-deref.yaml @@ -8250,6 +8250,8 @@ paths: type: boolean summary: type: string + tag: + type: string required: &ref_148 - path - schedule @@ -8319,6 +8321,8 @@ paths: type: boolean summary: type: string + tag: + type: string required: &ref_150 - schedule - timezone @@ -8464,6 +8468,8 @@ paths: type: string no_flow_overlap: type: boolean + tag: + type: string required: &ref_80 - path - edited_by diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 53fef4922e..3a3f39a7be 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -8587,6 +8587,8 @@ components: type: string no_flow_overlap: type: boolean + tag: + type: string required: - path - edited_by @@ -8660,6 +8662,8 @@ components: type: boolean summary: type: string + tag: + type: string required: - path - schedule @@ -8700,6 +8704,8 @@ components: type: boolean summary: type: string + tag: + type: string required: - schedule - timezone diff --git a/backend/windmill-api/src/flows.rs b/backend/windmill-api/src/flows.rs index 465b489a12..766d070517 100644 --- a/backend/windmill-api/src/flows.rs +++ b/backend/windmill-api/src/flows.rs @@ -880,6 +880,7 @@ mod tests { )] .into(), hash: None, + tag_override: None, }, stop_after_if: None, summary: None, @@ -948,6 +949,7 @@ mod tests { path: "test".to_string(), input_transforms: HashMap::new(), hash: None, + tag_override: None, }, stop_after_if: Some(StopAfterIf { expr: "previous.isEmpty()".to_string(), @@ -983,7 +985,8 @@ mod tests { } }, "type": "script", - "path": "test" + "path": "test", + "tag_override": Option::::None, }, }, { @@ -1026,7 +1029,8 @@ mod tests { "value": { "input_transforms": {}, "type": "script", - "path": "test" + "path": "test", + "tag_override": Option::::None, }, "stop_after_if": { "expr": "previous.isEmpty()", diff --git a/backend/windmill-api/src/schedule.rs b/backend/windmill-api/src/schedule.rs index 57428e0d03..74704a639e 100644 --- a/backend/windmill-api/src/schedule.rs +++ b/backend/windmill-api/src/schedule.rs @@ -69,6 +69,7 @@ pub struct NewSchedule { pub on_recovery_extra_args: Option, pub ws_error_handler_muted: Option, pub retry: Option, + pub tag: Option, } #[derive(Serialize, Deserialize)] @@ -155,9 +156,9 @@ async fn create_schedule( "INSERT INTO schedule (workspace_id, path, schedule, timezone, edited_by, script_path, \ is_flow, args, enabled, email, on_failure, on_failure_times, on_failure_exact, \ on_failure_extra_args, on_recovery, on_recovery_times, on_recovery_extra_args, \ - ws_error_handler_muted, retry, summary, no_flow_overlap \ + ws_error_handler_muted, retry, summary, no_flow_overlap, tag \ ) VALUES ( \ - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21 \ + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22 \ ) RETURNING *", w_id, ns.path, @@ -180,6 +181,7 @@ async fn create_schedule( ns.retry, ns.summary, ns.no_flow_overlap.unwrap_or(false), + ns.tag, ) .fetch_one(&mut tx) .await @@ -233,8 +235,9 @@ async fn edit_schedule( Schedule, "UPDATE schedule SET schedule = $1, timezone = $2, args = $3, on_failure = $4, on_failure_times = $5, \ on_failure_exact = $6, on_failure_extra_args = $7, on_recovery = $8, on_recovery_times = $9, \ - on_recovery_extra_args = $10, ws_error_handler_muted = $11, retry = $12, summary = $13, no_flow_overlap = $14 \ - WHERE path = $15 AND workspace_id = $16 RETURNING *", + on_recovery_extra_args = $10, ws_error_handler_muted = $11, retry = $12, summary = $13, \ + no_flow_overlap = $14, tag = $15 + WHERE path = $16 AND workspace_id = $17 RETURNING *", es.schedule, es.timezone, es.args, @@ -249,6 +252,7 @@ async fn edit_schedule( es.retry, es.summary, es.no_flow_overlap.unwrap_or(false), + es.tag, path, w_id, ) @@ -344,6 +348,7 @@ pub struct ScheduleWJobs { pub jobs: Option>, pub summary: Option, pub no_flow_overlap: bool, + pub tag: Option, } async fn list_schedule_with_jobs( @@ -692,6 +697,7 @@ pub struct EditSchedule { pub ws_error_handler_muted: Option, pub retry: Option, pub no_flow_overlap: Option, + pub tag: Option, } pub async fn clear_schedule<'c>( diff --git a/backend/windmill-common/src/flows.rs b/backend/windmill-common/src/flows.rs index 96cc7b892a..ac830a3226 100644 --- a/backend/windmill-common/src/flows.rs +++ b/backend/windmill-common/src/flows.rs @@ -292,6 +292,7 @@ pub enum FlowModuleValue { path: String, #[serde(skip_serializing_if = "Option::is_none")] hash: Option, + tag_override: Option, }, Flow { #[serde(default)] diff --git a/backend/windmill-common/src/jobs.rs b/backend/windmill-common/src/jobs.rs index ec9dec9c2c..77bf119fea 100644 --- a/backend/windmill-common/src/jobs.rs +++ b/backend/windmill-common/src/jobs.rs @@ -317,6 +317,7 @@ pub enum JobPayload { concurrency_time_window_s: Option, cache_ttl: Option, priority: Option, + tag_override: Option, }, DeploymentCallback { path: String, diff --git a/backend/windmill-common/src/schedule.rs b/backend/windmill-common/src/schedule.rs index 30823ef94f..362f7ad493 100644 --- a/backend/windmill-common/src/schedule.rs +++ b/backend/windmill-common/src/schedule.rs @@ -39,6 +39,7 @@ pub struct Schedule { pub retry: Option, pub no_flow_overlap: bool, pub summary: Option, + pub tag: Option, } impl Schedule { diff --git a/backend/windmill-queue/src/jobs.rs b/backend/windmill-queue/src/jobs.rs index 6017ce39e2..952442fb56 100644 --- a/backend/windmill-queue/src/jobs.rs +++ b/backend/windmill-queue/src/jobs.rs @@ -1005,6 +1005,7 @@ pub async fn handle_maybe_scheduled_job<'c, R: rsmq_async::RsmqConnection + Clon retry: schedule.retry, summary: schedule.summary, no_flow_overlap: schedule.no_flow_overlap, + tag: schedule.tag, }, ) .await; @@ -2616,6 +2617,7 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection concurrency_time_window_s, cache_ttl, priority, + tag_override, } => { let mut input_transforms = HashMap::::new(); for (arg_name, arg_value) in args { @@ -2628,6 +2630,7 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection input_transforms: input_transforms, path: path.clone(), hash: Some(hash), + tag_override: tag_override, }, stop_after_if: None, summary: None, diff --git a/backend/windmill-queue/src/schedule.rs b/backend/windmill-queue/src/schedule.rs index 57098295f0..847faac83b 100644 --- a/backend/windmill-queue/src/schedule.rs +++ b/backend/windmill-queue/src/schedule.rs @@ -130,6 +130,7 @@ pub async fn push_scheduled_job<'c, R: rsmq_async::RsmqConnection + Send + 'c>( concurrency_time_window_s: concurrency_time_window_s, cache_ttl: cache_ttl, priority: priority, + tag_override: schedule.tag.clone(), }, Some("flow".to_string()), timeout, @@ -146,7 +147,7 @@ pub async fn push_scheduled_job<'c, R: rsmq_async::RsmqConnection + Send + 'c>( language, priority, }, - tag, + schedule.tag.or(tag), timeout, ) } diff --git a/backend/windmill-worker/src/worker_flow.rs b/backend/windmill-worker/src/worker_flow.rs index 6efc66ea71..7eada141b4 100644 --- a/backend/windmill-worker/src/worker_flow.rs +++ b/backend/windmill-worker/src/worker_flow.rs @@ -2310,8 +2310,10 @@ async fn compute_next_flow_transform( NextStatus::NextStep, )) } - FlowModuleValue::Script { path: script_path, hash: script_hash, .. } => { - let payload = script_to_payload(script_hash, script_path, db, flow_job, module).await?; + FlowModuleValue::Script { path: script_path, hash: script_hash, tag_override, .. } => { + let payload = + script_to_payload(script_hash, script_path, db, flow_job, module, tag_override) + .await?; Ok(NextFlowTransform::Continue( ContinuePayload::SingleJob(payload), NextStatus::NextStep, @@ -2809,8 +2811,8 @@ async fn payload_from_simple_module( let delete_after_use = module.delete_after_use.unwrap_or(false); Ok(match value { FlowModuleValue::Flow { path, .. } => flow_to_payload(path, &delete_after_use), - FlowModuleValue::Script { path: script_path, hash: script_hash, .. } => { - script_to_payload(script_hash, script_path, db, flow_job, module).await? + FlowModuleValue::Script { path: script_path, hash: script_hash, tag_override, .. } => { + script_to_payload(script_hash, script_path, db, flow_job, module, tag_override).await? } FlowModuleValue::RawScript { path, @@ -2875,7 +2877,9 @@ async fn script_to_payload( db: &sqlx::Pool, flow_job: &QueuedJob, module: &FlowModule, + tag_override: &Option, ) -> Result { + tracing::warn!("Script tag override: {:?}", tag_override); let (payload, tag, delete_after_use, script_timeout) = if script_hash.is_none() { script_path_to_payload(script_path, &db, &flow_job.workspace_id).await? } else { @@ -2903,7 +2907,7 @@ async fn script_to_payload( dedicated_worker, priority, }, - tag, + tag_override.to_owned().or(tag), delete_after_use, script_timeout, ) diff --git a/examples/deploy/aws-ecs-terraform/windmill_server.tf b/examples/deploy/aws-ecs-terraform/windmill_server.tf index d2b4e2553f..aefd13f1e7 100644 --- a/examples/deploy/aws-ecs-terraform/windmill_server.tf +++ b/examples/deploy/aws-ecs-terraform/windmill_server.tf @@ -35,7 +35,7 @@ resource "aws_ecs_task_definition" "windmill_cluster_windmill_server_td" { value = "true" }, { name = "DATABASE_URL" - value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}" + value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}?sslmode=disable" }, { name = "MODE" value = "server" diff --git a/examples/deploy/aws-ecs-terraform/windmill_worker_basic.tf b/examples/deploy/aws-ecs-terraform/windmill_worker_basic.tf index 3932485e8b..75e9828348 100644 --- a/examples/deploy/aws-ecs-terraform/windmill_worker_basic.tf +++ b/examples/deploy/aws-ecs-terraform/windmill_worker_basic.tf @@ -26,7 +26,7 @@ resource "aws_ecs_task_definition" "windmill_cluster_windmill_worker_td" { value = "true" }, { name = "DATABASE_URL" - value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}" + value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}?sslmode=disable" }, { name = "MODE" value = "worker" diff --git a/examples/deploy/aws-ecs-terraform/windmill_worker_high_performance.tf b/examples/deploy/aws-ecs-terraform/windmill_worker_high_performance.tf index 7f9ddd8ef3..c45b78bd2c 100644 --- a/examples/deploy/aws-ecs-terraform/windmill_worker_high_performance.tf +++ b/examples/deploy/aws-ecs-terraform/windmill_worker_high_performance.tf @@ -101,7 +101,7 @@ resource "aws_ecs_task_definition" "windmill_cluster_windmill_high_performance_w value = "true" }, { name = "DATABASE_URL" - value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}" + value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}?sslmode=disable" }, { name = "MODE" value = "worker" diff --git a/examples/deploy/aws-ecs-terraform/windmill_worker_native.tf b/examples/deploy/aws-ecs-terraform/windmill_worker_native.tf index 75e9c3080d..593de7ed7d 100644 --- a/examples/deploy/aws-ecs-terraform/windmill_worker_native.tf +++ b/examples/deploy/aws-ecs-terraform/windmill_worker_native.tf @@ -26,7 +26,7 @@ resource "aws_ecs_task_definition" "windmill_cluster_windmill_native_worker_td" value = "true" }, { name = "DATABASE_URL" - value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}" + value = "postgres://${aws_db_instance.windmill_cluster_rds.username}:${aws_db_instance.windmill_cluster_rds.password}@${aws_db_instance.windmill_cluster_rds.endpoint}/${aws_db_instance.windmill_cluster_rds.db_name}?sslmode=disable" }, { name = "MODE" value = "worker" diff --git a/frontend/src/lib/components/AssignableTags.svelte b/frontend/src/lib/components/AssignableTags.svelte index d0d86ffbc7..cedf44e32d 100644 --- a/frontend/src/lib/components/AssignableTags.svelte +++ b/frontend/src/lib/components/AssignableTags.svelte @@ -11,6 +11,7 @@ let newTag: string = '' export let customTags: string[] | undefined = undefined + export let placement: 'bottom-end' | 'top-end' = 'bottom-end' async function loadCustomTags() { try { @@ -26,7 +27,7 @@ diff --git a/frontend/src/lib/components/ScheduleEditorInner.svelte b/frontend/src/lib/components/ScheduleEditorInner.svelte index 3dab3b4e69..c4823445c7 100644 --- a/frontend/src/lib/components/ScheduleEditorInner.svelte +++ b/frontend/src/lib/components/ScheduleEditorInner.svelte @@ -26,6 +26,7 @@ import Section from '$lib/components/Section.svelte' import { List, Save } from 'lucide-svelte' import FlowRetries from './flows/content/FlowRetries.svelte' + import WorkerTagPicker from './WorkerTagPicker.svelte' let optionTabSelected: 'error_handler' | 'recovery_handler' | 'retries' = 'error_handler' @@ -144,6 +145,7 @@ let pathError = '' let summary = '' let no_flow_overlap = false + let tag: string | undefined = undefined let validCRON = true $: allowSchedule = isValid && validCRON && script_path != '' @@ -271,6 +273,7 @@ } args = s.args ?? {} can_write = canWrite(s.path, s.extra_perms, $userStore) + tag = s.tag } catch (err) { sendUserToast(`Could not load schedule: ${err}`, true) } @@ -303,7 +306,8 @@ ws_error_handler_muted: wsErrorHandlerMuted, retry: retry, summary: summary != '' ? summary : undefined, - no_flow_overlap: no_flow_overlap + no_flow_overlap: no_flow_overlap, + tag: tag } }) sendUserToast(`Schedule ${path} updated`) @@ -330,7 +334,8 @@ ws_error_handler_muted: wsErrorHandlerMuted, retry: retry, summary: summary != '' ? summary : undefined, - no_flow_overlap: no_flow_overlap + no_flow_overlap: no_flow_overlap, + tag: tag } }) sendUserToast(`Schedule ${path} created`) @@ -533,12 +538,15 @@ + {#if !is_flow}{/if} +
Error Handler Recovery Handler {#if itemKind === 'script'} Retries + Custom tag {/if}
@@ -744,6 +752,13 @@ + {:else if optionTabSelected === 'tag'} +
+ +
{/if}
diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 9b08936824..017ba35a83 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -1,17 +1,10 @@ + +
+
+ {#if workerTags} + {#if $workerTags?.length ?? 0 > 0} + + {:else} +
+ No custom worker group tag defined on this instance in "Workers {'->'} Assignable Tags" + +
+ See documentation + +
+
+
+ {/if} + {:else} + + {/if} +
+ +
diff --git a/frontend/src/lib/components/flows/content/FlowSettings.svelte b/frontend/src/lib/components/flows/content/FlowSettings.svelte index e24397b613..089a4bad0b 100644 --- a/frontend/src/lib/components/flows/content/FlowSettings.svelte +++ b/frontend/src/lib/components/flows/content/FlowSettings.svelte @@ -17,34 +17,26 @@ import { isCloudHosted } from '$lib/cloud' import { copyToClipboard } from '$lib/utils' import Tooltip from '$lib/components/Tooltip.svelte' - import { WorkerService } from '$lib/gen' - import { AlertTriangle, Clipboard, Loader2, RotateCw } from 'lucide-svelte' + import { AlertTriangle, Clipboard } from 'lucide-svelte' import SimpleEditor from '$lib/components/SimpleEditor.svelte' import { schemaToObject } from '$lib/schema' import type { Schema } from '$lib/common' import Section from '$lib/components/Section.svelte' import Label from '$lib/components/Label.svelte' import ErrorHandlerToggleButton from '$lib/components/details/ErrorHandlerToggleButton.svelte' - import AssignableTags from '$lib/components/AssignableTags.svelte' + import WorkerTagPicker from '$lib/components/WorkerTagPicker.svelte' export let noEditor: boolean const { selectedId, flowStore, initialPath, previewArgs, pathStore } = getContext('FlowEditorContext') - async function loadWorkerGroups() { - if (!$workerTags) { - $workerTags = await WorkerService.getCustomTags() - } - } - let hostname = BROWSER ? window.location.protocol + '//' + window.location.host : 'SSR' $: url = `${hostname}/api/w/${$workspaceStore}/jobs/run/f/${$pathStore}` $: syncedUrl = `${hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/f/${$pathStore}` $: if ($selectedId == 'settings-worker-group') { $workerTags = undefined - loadWorkerGroups() } function asSchema(x: any) { @@ -327,54 +319,7 @@ 'flow' and the steps will be executed with their respective tag Worker Group Tag (Queue) -
- {#if $workerTags} - {#if $workerTags?.length > 0} -
- -
- {:else} -
- No custom worker group tag defined on this instance in "Workers {'->'} Assignable - Tags". See - documentation -
- {/if} - {:else} - - {/if} - -
+