Target manual importer from UI controls #31
This commit is contained in:
@@ -43,7 +43,7 @@ sudo -n sh /opt/importarr/repo-upgrade.sh
|
||||
|
||||
The helper refuses to run when the checkout has uncommitted changes, then performs `git pull --ff-only`, reinstalls the package from the repo, restarts `importarr.service`, and prints service status. Use it after changes have been committed and pushed to `main`.
|
||||
|
||||
Installed deployments can expose the same operation through the authenticated API. `GET /api/control/update-check` queries the latest release from `IMPORTARR_UPDATE_RELEASE_URL` (default: this repository's Gitea latest-release API) and compares it with the running `IMPORTARR_VERSION`. `POST /api/control/update` performs the same check and only runs the update command when a newer release tag exists. Configure `IMPORTARR_UPDATE_COMMAND` when the default `sh deploy/repo-upgrade.sh` is not correct for the service working directory, and configure `IMPORTARR_RESTART_COMMAND` when the default `systemctl restart importarr.service` needs a wrapper such as sudo.
|
||||
Installed deployments can expose the same operation through the authenticated API. `GET /api/control/update-check` queries the latest release from `IMPORTARR_UPDATE_RELEASE_URL` (default: this repository's Gitea latest-release API) and compares it with the running `IMPORTARR_VERSION`. `POST /api/control/update` performs the same check and only runs the update command when a newer release tag exists. Configure `IMPORTARR_UPDATE_COMMAND` when the default `sh deploy/repo-upgrade.sh` is not correct for the service working directory. The web UI Start, Stop, and Restart controls target `manual-media-import.service` by default; configure `IMPORTARR_START_COMMAND`, `IMPORTARR_STOP_COMMAND`, or `IMPORTARR_RESTART_COMMAND` when those defaults need a wrapper such as sudo.
|
||||
|
||||
Release-worthy changes should be committed, tagged with SemVer (`v0.1.1`, `v0.2.0`, ...), pushed with tags, then installed from the tagged checkout or artifact.
|
||||
|
||||
|
||||
+6
-2
@@ -22,7 +22,9 @@ class Settings(BaseModel):
|
||||
sonarr_url: str | None = None
|
||||
sonarr_api_key: str | None = None
|
||||
auth_token: str | None = None
|
||||
restart_command: list[str] = Field(default_factory=lambda: ["systemctl", "restart", "importarr.service"])
|
||||
start_command: list[str] = Field(default_factory=lambda: ["systemctl", "start", "manual-media-import.service"])
|
||||
stop_command: list[str] = Field(default_factory=lambda: ["systemctl", "stop", "manual-media-import.service"])
|
||||
restart_command: list[str] = Field(default_factory=lambda: ["systemctl", "restart", "manual-media-import.service"])
|
||||
update_command: list[str] = Field(default_factory=lambda: ["sh", "deploy/repo-upgrade.sh"])
|
||||
update_release_url: str = "https://gitea.delphas.dk/api/v1/repos/daniels/importarr/releases/latest"
|
||||
update_check_timeout_seconds: int = Field(default=15, ge=1)
|
||||
@@ -48,7 +50,9 @@ class Settings(BaseModel):
|
||||
sonarr_url=os.getenv("IMPORTARR_SONARR_URL"),
|
||||
sonarr_api_key=_env_secret("IMPORTARR_SONARR_API_KEY"),
|
||||
auth_token=_env_secret("IMPORTARR_AUTH_TOKEN"),
|
||||
restart_command=_env_command("IMPORTARR_RESTART_COMMAND", ["systemctl", "restart", "importarr.service"]),
|
||||
start_command=_env_command("IMPORTARR_START_COMMAND", ["systemctl", "start", "manual-media-import.service"]),
|
||||
stop_command=_env_command("IMPORTARR_STOP_COMMAND", ["systemctl", "stop", "manual-media-import.service"]),
|
||||
restart_command=_env_command("IMPORTARR_RESTART_COMMAND", ["systemctl", "restart", "manual-media-import.service"]),
|
||||
update_command=_env_command("IMPORTARR_UPDATE_COMMAND", ["sh", "deploy/repo-upgrade.sh"]),
|
||||
update_release_url=os.getenv("IMPORTARR_UPDATE_RELEASE_URL", "https://gitea.delphas.dk/api/v1/repos/daniels/importarr/releases/latest"),
|
||||
update_check_timeout_seconds=int(os.getenv("IMPORTARR_UPDATE_CHECK_TIMEOUT_SECONDS", "15")),
|
||||
|
||||
+3
-2
@@ -258,7 +258,7 @@ def set_queue_control(payload: QueueControlRequest, _: None = Depends(require_wr
|
||||
def start_queue(_: None = Depends(require_write_auth)) -> dict[str, object]:
|
||||
state.set_app_state("queue_mode", "running")
|
||||
state.set_app_state("cancel_requested", "false")
|
||||
return control_status()
|
||||
return {"control": control_status(), "command_result": _run_control_command(settings.start_command)}
|
||||
|
||||
|
||||
@app.post("/api/control/pause")
|
||||
@@ -270,7 +270,8 @@ def pause_queue(_: None = Depends(require_write_auth)) -> dict[str, object]:
|
||||
@app.post("/api/control/stop")
|
||||
def stop_queue(_: None = Depends(require_write_auth)) -> dict[str, object]:
|
||||
state.set_app_state("queue_mode", "stopped")
|
||||
return control_status()
|
||||
state.set_app_state("cancel_requested", "true")
|
||||
return {"control": control_status(), "command_result": _run_control_command(settings.stop_command)}
|
||||
|
||||
|
||||
@app.post("/api/control/cancel-current")
|
||||
|
||||
@@ -42,6 +42,57 @@ def test_start_reenables_manual_queue_sync(tmp_path, monkeypatch):
|
||||
assert len(main.state.list_queue_items()) == 1
|
||||
|
||||
|
||||
def test_default_control_commands_target_manual_import_service(monkeypatch):
|
||||
monkeypatch.delenv("IMPORTARR_START_COMMAND", raising=False)
|
||||
monkeypatch.delenv("IMPORTARR_STOP_COMMAND", raising=False)
|
||||
monkeypatch.delenv("IMPORTARR_RESTART_COMMAND", raising=False)
|
||||
|
||||
settings = Settings.from_env()
|
||||
|
||||
assert settings.start_command == ["systemctl", "start", "manual-media-import.service"]
|
||||
assert settings.stop_command == ["systemctl", "stop", "manual-media-import.service"]
|
||||
assert settings.restart_command == ["systemctl", "restart", "manual-media-import.service"]
|
||||
|
||||
|
||||
def test_start_control_starts_manual_import_service(tmp_path, monkeypatch):
|
||||
main, _download, _movies, _tv = configure_main(tmp_path, monkeypatch)
|
||||
main.settings.start_command = ["systemctl", "start", "manual-media-import.service"]
|
||||
|
||||
calls = []
|
||||
|
||||
def fake_run(command, **kwargs):
|
||||
calls.append(command)
|
||||
return main.subprocess.CompletedProcess(command, 0, stdout="started", stderr="")
|
||||
|
||||
monkeypatch.setattr(main.subprocess, "run", fake_run)
|
||||
|
||||
result = main.start_queue()
|
||||
|
||||
assert result["control"]["queue_mode"] == "running"
|
||||
assert result["command_result"]["command"] == ["systemctl", "start", "manual-media-import.service"]
|
||||
assert calls == [["systemctl", "start", "manual-media-import.service"]]
|
||||
|
||||
|
||||
def test_stop_control_stops_manual_import_service(tmp_path, monkeypatch):
|
||||
main, _download, _movies, _tv = configure_main(tmp_path, monkeypatch)
|
||||
main.settings.stop_command = ["systemctl", "stop", "manual-media-import.service"]
|
||||
|
||||
calls = []
|
||||
|
||||
def fake_run(command, **kwargs):
|
||||
calls.append(command)
|
||||
return main.subprocess.CompletedProcess(command, 0, stdout="stopped", stderr="")
|
||||
|
||||
monkeypatch.setattr(main.subprocess, "run", fake_run)
|
||||
|
||||
result = main.stop_queue()
|
||||
|
||||
assert result["control"]["queue_mode"] == "stopped"
|
||||
assert result["control"]["cancel_requested"] is True
|
||||
assert result["command_result"]["command"] == ["systemctl", "stop", "manual-media-import.service"]
|
||||
assert calls == [["systemctl", "stop", "manual-media-import.service"]]
|
||||
|
||||
|
||||
def test_queue_jobs_include_groups_and_manual_context(tmp_path, monkeypatch):
|
||||
main, download, _movies, _tv = configure_main(tmp_path, monkeypatch)
|
||||
batch = download / "Release" / "Season 1"
|
||||
|
||||
Reference in New Issue
Block a user