Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,15 @@ jobs:
DS64: ${{ github.workspace }}/ds64
run: scripts/package-linux-release.sh

- name: Verify Linux installer archive root
run: |
set -euo pipefail
roots="$(tar -tzf artifacts/linux/quasar-installer-linux.tar.gz | awk -F/ 'NF { print $1 }' | sort -u)"
if [ "$roots" != "Quasar" ]; then
echo "ERROR: expected quasar-installer-linux.tar.gz root directory to be Quasar; found: $roots" >&2
exit 1
fi

- name: Upload Linux archives
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -430,6 +439,27 @@ jobs:
DS64: ${{ github.workspace }}\ds64
run: scripts/package-windows-release.ps1

- name: Verify Windows installer archive root
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead((Resolve-Path 'artifacts/windows/quasar-installer-windows.zip').Path)
try {
$roots = @(
$zip.Entries |
Where-Object { -not [string]::IsNullOrWhiteSpace($_.FullName) } |
ForEach-Object { ($_.FullName -replace '\\', '/').Split('/')[0] } |
Sort-Object -Unique
)
}
finally {
$zip.Dispose()
}
if ($roots.Count -ne 1 -or $roots[0] -ne 'Quasar') {
throw "expected quasar-installer-windows.zip root directory to be Quasar; found: $($roots -join ', ')"
}

- name: Upload Windows archives
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -494,7 +524,7 @@ jobs:
| **Linux** (x64) | **`quasar-installer-linux.tar.gz`** |
| **Windows** (x64) | **`quasar-installer-windows.zip`** |

Download the archive with **installer** in its name. It contains one top-level folder with the Quasar **Bootstrap launcher**, the install/uninstall scripts, and a default `appsettings.json`. Follow the [Linux](https://github.com/CometWorks/quasar/blob/main/Docs/LinuxDeploymentAndUpdates.md) or [Windows](https://github.com/CometWorks/quasar/blob/main/Docs/WindowsDeploymentAndUpdates.md) deployment guide to install it. The web UI is available on http://127.0.0.1:8080 by default (the web server listens on all interfaces at 0.0.0.0:8080).
Download the archive with **installer** in its name. It contains one top-level `Quasar` folder with the Quasar **Bootstrap launcher**, the install/uninstall scripts, and a default `appsettings.json`. Follow the [Linux](https://github.com/CometWorks/quasar/blob/main/Docs/LinuxDeploymentAndUpdates.md) or [Windows](https://github.com/CometWorks/quasar/blob/main/Docs/WindowsDeploymentAndUpdates.md) deployment guide to install it. The web UI is available on http://127.0.0.1:8080 by default (the web server listens on all interfaces at 0.0.0.0:8080).

The other two archives (`quasar-web-linux-x64.tar.gz` and `quasar-web-win-x64.zip`) are updates that Quasar downloads and applies automatically — you never download them by hand.

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Quasar.Agent and Magnetar.Protocol disable generated version attributes
because SHA-256, not release metadata, is the deploy drift signal for
the in-server DLLs. -->
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>

Expand Down
13 changes: 8 additions & 5 deletions Docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ worker** read JSON config from these locations, later ones overriding earlier:
preserve this file during Bootstrap self-updates. UI-worker activation updates
it from the staged, resolved `appsettings.json` so Bootstrap and the managed
worker keep the same base settings.
2. The Quasar **data directory** `appsettings.json` — the recommended place for
persistent local overrides because it is never touched by updates:
- Windows: `%APPDATA%\Quasar\appsettings.json`
- Linux: `~/.config/Quasar/appsettings.json` by default for `install.sh`
systemd installs (or `$QUASAR_DATA_DIR/appsettings.json`)
2. The Quasar **data directory** `appsettings.json`. Bootstrap uses the install
root as the default data directory, so this is normally the same file as item
1. Set `QUASAR_DATA_DIR` (or `--data-dir <dir>` on Linux installs) to keep
persistent local overrides in a separate directory.

When Bootstrap starts without a custom `QUASAR_DATA_DIR`, it migrates legacy
default data roots (`~/.config/Quasar` on Linux/macOS,
`%APPDATA%\Quasar` on Windows) into the install root.

The shipped defaults are defined in [`Quasar/appsettings.json`](../Quasar/appsettings.json).

Expand Down
54 changes: 30 additions & 24 deletions Docs/LinuxDeploymentAndUpdates.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ web UI worker.
`scripts/package-linux-release.sh` produces:

- `quasar-installer-linux.tar.gz`
- top-level `quasar-installer-linux/` directory
- top-level `Quasar/` directory
- `Quasar` Bootstrap launcher
- `install.sh`
- `uninstall.sh`
Expand Down Expand Up @@ -63,19 +63,19 @@ metadata is normalized to `major.minor.build`.

## First Start

The default systemd user service runs Bootstrap from
`~/.local/share/Quasar/Quasar serve --quiet` and sets `QUASAR_DATA_DIR` to the
user's Quasar data directory. It also sets `QUASAR_SYSTEMD_SERVICE` and
`QUASAR_SYSTEMD_SCOPE` so the web UI's **Shutdown Quasar** action can request
`systemctl --user stop quasar.service` instead of only exiting the launcher.
A machine-wide service is still available with `install.sh --system`.
The default systemd user service runs Bootstrap from the extracted install root
and sets `QUASAR_DATA_DIR` to that same directory. It also sets
`QUASAR_SYSTEMD_SERVICE` and `QUASAR_SYSTEMD_SCOPE` so the web UI's **Shutdown
Quasar** action can request `systemctl --user stop quasar.service` instead of
only exiting the launcher. A machine-wide service is still available with
`install.sh --system`.

If Bootstrap has no usable `Updates/active-release.json` and no packaged
`WebService/Quasar`, it downloads the latest Linux web asset from GitHub,
extracts it under:

```text
~/.config/Quasar/ManagedRuntime/WebService/<version>
<install-root>/ManagedRuntime/WebService/<version>
```

Then it writes `Updates/active-release.json` pointing at the managed active
Expand All @@ -88,6 +88,9 @@ pointer that targets a random external build directory. Only packaged
configured `QUASAR_WEB_EXE` / `QUASAR_WEB_DLL` workers are trusted. If Bootstrap
finds an older active pointer that still targets `Updates/Staged/<version>`, it
migrates that release into `ManagedRuntime/WebService/<version>` before launch.
On startup, Bootstrap also migrates a legacy default data root at
`~/.config/Quasar` into the install root unless `QUASAR_DATA_DIR` points to a
custom directory.

## UI Worker Updates

Expand All @@ -103,7 +106,7 @@ a matching `SHA256SUMS` entry for the downloaded asset.
Staging also resolves `appsettings.json`. Quasar uses the stored release base in
the data directory (`$QUASAR_DATA_DIR/Updates/appsettings.base.json`) as the
merge base, applies local values from the install directory
(`~/.local/share/Quasar` by default), and writes the resolved file into the staged worker. If the merge
(`<install-root>` by default), and writes the resolved file into the staged worker. If the merge
conflicts, auto-staging stops with a warning and `/settings/updates` shows a
git-style conflict editor. Resolve and save the JSON there, or choose **Force
release defaults** to stage the release file without local appsettings values.
Expand Down Expand Up @@ -149,7 +152,7 @@ Bootstrap checks the primary Quasar release stream every 15 minutes by default.
When it finds an actually newer `quasar-installer-linux.tar.gz` asset (semver
core and prerelease compared against the running launcher's release identity), it
verifies the release's `SHA256SUMS` entry, extracts the archive, strips the
single top-level installer directory, replaces the installed launcher files,
single top-level `Quasar` directory, replaces the installed launcher files,
drains the UI worker, and exits with a failure code so systemd restarts the
updated launcher. Existing `appsettings.json` is preserved.
Bootstrap must not drain the worker for a release whose normalized version is
Expand Down Expand Up @@ -183,19 +186,22 @@ first adds Microsoft's Debian 13 package feed with
selected .NET package.

```bash
tar -xzf quasar-installer-linux.tar.gz -C /tmp
/tmp/quasar-installer-linux/install.sh # publish to ~/.local/share/Quasar and install user quasar.service
/tmp/quasar-installer-linux/install.sh --start # also start the user service immediately
mkdir -p ~/.local/share/Quasar
tar -xzf quasar-installer-linux.tar.gz -C ~/.local/share/Quasar --strip-components=1
~/.local/share/Quasar/install.sh # install user quasar.service
~/.local/share/Quasar/install.sh --start # also start the user service immediately
```

`install.sh` publishes Quasar to `~/.local/share/Quasar`, creates the Quasar
data directory at `~/.config/Quasar` by default, and installs a user
`quasar.service`. Use `--system` with `sudo` for a machine-wide service, or
`--data-dir <dir>` to place Quasar state elsewhere. The generated service sets
`HOME` and `QUASAR_DATA_DIR` explicitly so Bootstrap and the worker never fall
back to the install directory for update/runtime state. It also records the unit
name/scope in `QUASAR_SYSTEMD_SERVICE` and `QUASAR_SYSTEMD_SCOPE`; with those
set, the UI shutdown button asks systemd to stop the installed unit. The
For extracted release installers, `install.sh` uses the script directory as the
default install directory and the default Quasar data directory. Source installs
keep using `~/.local/share/Quasar` as the default install root, with state stored
there as well. Use `--system` with `sudo` for a machine-wide service,
`--install-dir <dir>` to copy Quasar elsewhere, or `--data-dir <dir>` to place
Quasar state elsewhere. The generated service sets `HOME` and `QUASAR_DATA_DIR`
explicitly so Bootstrap and the worker agree on the update/runtime state root.
It also records the unit name/scope in `QUASAR_SYSTEMD_SERVICE` and
`QUASAR_SYSTEMD_SCOPE`; with those set, the UI shutdown button asks systemd to
stop the installed unit. The
installer enables the service but does not start or restart it unless `--start`
is passed; start it later with `systemctl --user restart quasar.service`. When
installing from source instead of an extracted release archive, the installer
Expand All @@ -213,7 +219,7 @@ the whole Quasar service. The installer can build and install a narrow setuid
root helper when the feature is needed:

```bash
/tmp/quasar-installer-linux/install.sh --install-renice-helper --no-build --no-enable
/tmp/Quasar/install.sh --install-renice-helper --no-build --no-enable
```

The helper is installed as `/usr/local/bin/quasar-renice`, accepts only Quasar's
Expand All @@ -223,7 +229,7 @@ names before calling `setpriority`.

```bash
~/.local/share/Quasar/uninstall.sh # remove the user systemd service
~/.local/share/Quasar/uninstall.sh --purge # also remove ~/.local/share/Quasar
~/.local/share/Quasar/uninstall.sh --purge # also remove the install/data root
```

`uninstall.sh` runs `systemctl stop quasar.service` before disabling and removing
Expand All @@ -238,7 +244,7 @@ For the web UI host/port (including how to change the listening port, default

Update defaults live in `Quasar:Updates`. Packaged defaults come from the install
directory, and operator overrides can live in the Quasar data directory
(`~/.config/Quasar/appsettings.json` by default for Linux systemd installs, or
(`<install-root>/appsettings.json` by default for Linux systemd installs, or
`QUASAR_DATA_DIR/appsettings.json` when overridden). The worker and Bootstrap
both read that data-directory file on startup.

Expand Down
Loading
Loading