Add a Provision startup mode for non-interactive first-time setup - #17902
Open
cramt wants to merge 1 commit into
Open
Add a Provision startup mode for non-interactive first-time setup#17902cramt wants to merge 1 commit into
cramt wants to merge 1 commit into
Conversation
A fresh server stops at the startup wizard and needs a browser before it will serve anything, which makes it the one service in an otherwise fully declarative deployment that cannot come up on its own. The workaround is to script the /Startup/* endpoints, which are reachable unauthenticated while IsStartupWizardCompleted is false, so every automated deployment has a window where any caller could claim the administrator account. `--mode Provision --provision-file <path>` reads a JSON manifest, performs the same operations the startup wizard performs, marks the wizard complete and exits without ever starting the HTTP listener. The manifest is a file rather than flags so credentials stay out of ps and shell history. Every member except the administrator is optional, and an omitted member leaves the server default alone rather than resetting it. Running against a server that is already set up is a no-op, so configuration management can rerun it on every rebuild. The manifest is read before any of the migration and service startup work, and library paths are checked before anything is written, so a bad manifest fails fast and leaves nothing half-provisioned. Fixes jellyfin#17880
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Changes
Adds a
Provisionvalue toStartupModeplus--provision-file <path>. The server reads a JSON manifest, applies the same operationsStartupControllerperforms (server name and metadata locale, the initial administrator, remote access, and optionally libraries), marks the wizard complete, and exits without ever starting the HTTP listener. This lets a fresh server come up fully configured on a host that is deployed from configuration, instead of stopping at the wizard until someone opens a browser — and it avoids the window in which the unauthenticated/Startup/*routes can be used to claim the administrator account, which is what the existing third-party tooling relies on.Answering the three questions from #17880 with the shape I found easiest to defend, all of which are cheap to change if you'd rather go the other way:
psand shell history and the operator controls the permissions.JsonDefaultsso enums spell the same as in the API models, then loosened for a file a human maintains: comments, trailing commas, and either casing of property names are accepted.Every member except the administrator is optional, and an omitted member leaves the server default alone rather than resetting it to empty. Failures are ordered so nothing is left half-provisioned: the manifest is read and validated before any of the migration and service startup work, library paths are checked before anything is written, and a failure exits non-zero rather than only logging.
Two things worth a reviewer's attention:
LibraryManager.AddVirtualFolderthrows on those, so that isn't available without changing it — provisioning now checks every path up front and fails the run instead, which also keeps a not-yet-mounted media directory from leaving a half-configured server behind.SetupServerstill starts in this mode, so a provisioning run holds port 8096 for its duration, exactly asMigrateSystemdoes today. It only serves the startup splash, so no wizard API is exposed, but it will collide with an instance that is already running. Skipping the setup server for one-shot modes would changeMigrateSystemtoo, so I left it alone rather than decide that here.Server-only; no changes to clients, the web UI, or any API contract. Covered by 22 new tests in
tests/Jellyfin.Server.Tests/Provisioning/, and verified by hand against a real server: provisioning a fresh data directory, authenticating as the provisioned administrator over HTTP afterwards, confirming the libraries and configuration landed, and confirming a second run is a no-op.Code assistance
Claude Code (Opus) drafted the implementation and the tests from the design in #17880, and ran the end-to-end verification described above. It found the
AddVirtualFolderpath-validation behaviour that the issue's proposed warn-and-continue conflicted with, and the port 8096 observation. I reviewed the result before opening this.Issues
Fixes #17880