Replace placeholder #[ignore] tests with real integration tests:
- overlay_integration: test overlayfs read/write semantics via unshare
(no root required), and overlayfs rootfs as nsjail sandbox root
- crane_integration: test crane export of alpine image → tar/gz
roundtrip, and running the extracted rootfs in nsjail
Also fix tar_gz to preserve symlinks (follow_symlinks=false) instead
of following them to absolute paths that may not exist on the host.
All tests skip gracefully when tools (nsjail, crane, unshare) are
unavailable, so they won't break CI.
Total: 32 passing (with parquet), 14 parser tests = 46 tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 6 nsjail integration tests that verify actual sandbox execution:
- basic bash execution
- volume read (bind-mount data into sandbox)
- volume write-back (sandbox writes to bind-mounted volume)
- overlay root (snapshot rootfs as sandbox root)
- overlay root + volume mount combined
- result.json output from sandbox
Fix a bug in finalize_nsjail_config where the overlay root mount
(dst: "/") was placed last in the config (via {SHARED_MOUNT}). nsjail
applies mounts in order, so a root bind mount after tmpfs/bind mounts
would overwrite them. The root mount is now moved to be the first mount
block, ensuring subsequent mounts layer correctly on top.
Also add 2 #[ignore] tests for mount_overlay (needs root) and
build_snapshot (needs crane CLI).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add support for custom rootfs snapshots and persistent volumes in nsjail
sandboxes, enabling users to run scripts with pre-built environments and
shared persistent storage.
- DB migration: sandbox_snapshot + sandbox_volume tables
- API: CRUD endpoints under /api/w/{ws}/sandbox/
- Common: annotation parser for # sandbox: and # volume: directives
- Worker: S3-backed snapshot cache, overlayfs mount, volume sync
- Executors: nsjail config post-processing to swap rootfs when overlay active
- Tests: 28 tests covering parsing, config generation, and end-to-end flows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(frontend): preserve flow settings when updating summary/path from detail page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(frontend): type builders prop with ReturnType<typeof createDropdownMenu>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(frontend): extract shared updateItemPathAndSummary utility to deduplicate move/rename logic
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(frontend): enable inline summary/path editing on script detail page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* improve layout
* feat(frontend): add dirty tracking to MoveDrawer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* nit move drawer
* fix(frontend): drop on_behalf_of_email from move/rename and warn user about redeployment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(frontend): hide on_behalf_of warning in MoveDrawer when user is not owner
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(frontend): only reload script when path unchanged in onSaved callback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Show custom_instance_pg_databases, ducklake_settings, ducklake_user_pg_pwd
and rsa_keys in frontend YAML editor (remove from excludedKeys)
- Redact sensitive values: add ducklake_user_pg_pwd and rsa_keys to
sensitiveKeys, add custom_instance_pg_databases.user_pwd to
nestedSensitiveFields
- Remove rsa_keys from HIDDEN_SETTINGS so it appears in YAML export
- Hide automate_username_creation from export (add to HIDDEN_SETTINGS)
- Add ducklake_user_pg_pwd and rsa_keys to SENSITIVE_SETTINGS for log
redaction
- Generalize empty/null protection for all PROTECTED_SETTINGS: operator
diff skips empty values when DB has existing data, direct API rejects
delete/empty for protected settings
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: improve operator ConfigMap settings handling
- Protect jwt_secret and min_keep_alive_version from deletion (add to
PROTECTED_SETTINGS)
- Expose jwt_secret in config exports (remove from HIDDEN_SETTINGS)
- Reject empty/null jwt_secret values with warning
- Clamp retention_period_secs to 30 days max on CE builds
- Improve apply_settings_diff logging: distinguish Created/Updated/Deleted
with from/to values and unchanged count summary
- Add sensitive value masking in logs with partial redaction (prefix/suffix)
for top-level secrets and nested sub-field masking for oauths, smtp,
object_store_cache_config, custom_instance_pg_databases
- Sort global_settings keys alphabetically in YAML export
- Order worker_configs with "default" and "native" first in YAML export
- Add tests for sorted YAML serializer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review feedback
- Fix redact_string panic on multi-byte UTF-8 by using chars() instead
of byte-length slicing
- Protect jwt_secret from deletion via direct API
(set_global_setting_internal rejects empty/null with BadRequest)
- Add code comment documenting jwt_secret visibility trade-off
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* allow editing flow/script summary
* feat(frontend): wire up edit summary/path on flow detail page
- Fix on:click → onclick (Svelte 5) and add title on Save button
- Make can_write reactive ($state) so onEdit prop updates correctly
- Wire onEdit in flow detail page to call FlowService.updateFlow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(frontend): use Path component for path editing in detail page header
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(frontend): extract SummaryPathDisplay component with edit popover
Consolidate the summary+path display and edit popover into a reusable
SummaryPathDisplay component, used in both the detail page header and
the flow editor toolbar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(frontend): add size prop to Path/FolderPicker, compact popover
Add size prop ('sm' | 'md') to Path and FolderPicker components,
passed through to ToggleButton, TextInput, and Button children.
Use hideFullPath and size="sm" in the SummaryPathDisplay popover
for a compact inline path editor. Widen popover to 480px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix add folder in path editor
* fix(frontend): disable focus trap on edit popover for drawer access
Disable melt-ui's focus trap on the SummaryPathDisplay popover so
that inputs inside drawers (e.g. New Folder) can receive focus.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* nit
* feat(frontend): auto-create folder and render drawer above popover
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(frontend): show placeholder and hover-reveal pencil in SummaryPathDisplay
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(frontend): click-to-edit SummaryPathDisplay with inline layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(frontend): move undo/redo and tutorials into dropdown submenu with notification dot
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(frontend): stack path above summary in SummaryPathDisplay
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(frontend): bind summary/path directly in flow builder popover
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* nit
* chore: add PR screenshots (to be removed before merge)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove PR screenshots (moved to release assets)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: switch operator from CRD to ConfigMap
Replace the WindmillInstance CRD with a plain ConfigMap for the K8s
operator. This simplifies deployment (no CRD to install/manage, no
ClusterRole for custom API groups) while keeping the same config schema.
- Replace crd_ee.rs with configmap_ee.rs (parses data.spec YAML key)
- Rewrite reconciler_ee.rs: ConfigMap watcher + Event recorder instead
of CRD Controller + status subresource
- Add license_key preservation: if absent/empty in ConfigMap but present
in DB, the DB value is kept
- Remove print_crd_yaml() and "operator crd" subcommand
- Drop schemars, chrono, instance_config_schema dependencies
- Delete manifests/crd.yaml
- Update K8s example and README for ConfigMap approach
- RBAC now only needs a namespace-scoped Role (not ClusterRole)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add superadmin YAML export endpoint and remove cache_clear from operator config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: mark base_url as unsaved when using browser fallback in instance settings
When base_url is not set in the database, the frontend silently fills in
window.location.origin but also snapshots it as the initial value. This
makes the dirty-check see no change, so the Save button stays disabled
and the user cannot persist the auto-detected value.
Fix by snapshotting initialValues before applying the fallback, and show
a yellow warning indicating the value is auto-detected and unsaved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: render base_url fallback warning inside the setting card
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: allow adding workspace scripts and flows as AI chat context
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleaning
* cleaning
* cleaning
* better
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When using infrastructure-as-code to update settings, if the desired
license key matches the current one (same client ID and signature) but
differs only in the expiration date, only apply the update if the new
key has a later expiry. This prevents accidental downgrades when an
older license key is present in the IaC configuration.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add CRD configuration hints to instance settings and workers pages
Add subtle text notes with doc links to help K8s users discover that
instance settings and worker group configs can be managed via the
WindmillInstance CRD.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: IaC hints, YAML editor for worker configs, and EE badges
- Move IaC hint from form view to YAML mode in Instance Settings
- Add YAML editor drawer for worker group configs with diff review
- Add EE-only badges to gated fields in worker config drawer
- Make init_bash available in CE (frontend + backend gate)
- Promote Init/Periodic scripts to top-level sections
- Add "YAML editor" button to worker config drawer action bar
- Strip cache_clear and empty fields from YAML output
- Sort default/native groups first in YAML editor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review feedback on worker YAML editor
- Extract serializeWorkerGroupsAsYaml() shared helper (dedup)
- Fix name:undefined leak using proper destructuring
- Protect default/native groups from accidental deletion
- Add loading indicator during YAML save
- Add restart warning for periodic script changes
- Use consistent on:click event syntax in YAML drawer actions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: use onClick prop instead of on:click for Button components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Move K8s operator source code (crd, db_sync, reconciler, resolve) to
windmill-ee-private and gate behind feature = "private". OSS stubs
provide error messages when the feature is disabled.
Add an info Alert banner in the Registries settings section when no
enterprise license is active.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: gate private registry configuration behind enterprise feature
Add read_ee_registry<T> helper that returns None and emits a job log
in CE builds when a private registry is configured. Applied to all
language executors: pip, npm/bun, deno, cargo, go, maven, nuget,
powershell, and ruby. Maven settings.xml file write in monitor.rs
is also gated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: open-source worker group configuration UI
Allow CE users to create worker group configs and edit worker_tags.
EE-only features (dedicated workers, custom env vars, init/periodic
scripts, autoscaling, priority tags, etc.) remain gated behind the
enterprise license in the UI. Backend now filters CE config updates
to only allow worker_tags and cache_clear fields instead of rejecting
the entire request.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add read_ee_registry<T> helper that returns None and emits a job log
in CE builds when a private registry is configured. Applied to all
language executors: pip, npm/bun, deno, cargo, go, maven, nuget,
powershell, and ruby. Maven settings.xml file write in monitor.rs
is also gated.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>