# Remote Updates

The tracker can check an HTTPS web server for a versioned ZIP file at startup.
Configuration, databases, logs and runtime data are preserved during updates.

## First-Time Device Setup

Copy the updater-enabled code to the Pi, then make sure the service user owns it:

```bash
sudo chown -R admin:admin /home/admin/its-a-plane-python
```

The existing service should continue to start:

```bash
sudo systemctl restart its-a-plane
sudo systemctl status its-a-plane
```

Open the tracker configuration page and find **Software Updates**:

1. Enter the HTTPS URL to `manifest.json`.
2. Enable **Remote Updates**.
3. Enable **Check When Device Starts**.
4. Choose whether new versions should install automatically.
5. Click **Save & Apply**.

## Building A Release

Run this from the project directory on the computer containing the finished code:

```bash
python tools/build_update.py \
  --version 1.0.1 \
  --base-url https://updates.example.com/plane-tracker \
  --notes "Tracked-flight display improvements"
```

This creates:

```text
dist/
  manifest.json
  plane-tracker-1.0.1.zip
```

Upload both files to the HTTPS folder specified by `--base-url`.
Upload the ZIP first and `manifest.json` last. This prevents devices seeing a
manifest before its ZIP is available.

## Versioning

Use increasing semantic versions:

```text
1.0.0
1.0.1
1.1.0
2.0.0
```

The device only installs a version greater than its installed version.
The installed version is stored in `VERSION` and `.updates/state.json`.

## Safety Behaviour

- Only HTTPS manifest and ZIP URLs are accepted.
- The downloaded ZIP must match the manifest SHA-256 checksum.
- Unsafe ZIP paths are rejected.
- Only one update operation can run at a time.
- User configuration, secrets, databases and logs are preserved.
- The previous code version is kept as a rollback ZIP.
- If the updated application fails before the display initializes, the next
  service start automatically restores the previous code.
- If the update server is offline, the installed application starts normally.

## Manual Controls

The configuration page provides:

- **Check Now**
- **Install Update**
- **Roll Back**

Manual installation and rollback restart `its-a-plane.service` when complete.
The existing service user therefore needs permission to run the restart command.
If the current **Restart App** button already works, this is already configured.

## Example Manifest

```json
{
  "version": "1.0.1",
  "url": "https://updates.example.com/plane-tracker/plane-tracker-1.0.1.zip",
  "sha256": "generated-by-build_update.py",
  "release_notes": "Tracked-flight display improvements"
}
```
