# Upgrade and uninstall

Upgrade the agent to a new release, what to do when coming from an older one, remove everything an install created from the router, and remove the dashboards and stored data.

Source: https://jmrplens.github.io/mikroscope/install/upgrade/

`upgrade` replaces the container with a new image and keeps the rest of the install. `uninstall`
removes everything the install created, and checks that nothing is left. Both read how the install
was made from its manifest on the router, whichever method made it.

## Upgrade

```sh
mikroscope upgrade --router admin@192.168.88.1 --remote-image jmrplens/mikroscope-agent:1.6.1
```

`upgrade` takes the image from its own flags only: pass `--remote-image` with the new version,
`--agent-tar` with the new tar, or run it from an updated checkout. Everything else about the
install's shape comes from the router.

1. **Reads the install.** From its manifest, or, for an install made without one, from the objects
   that carry its tag. `nothing to upgrade: run install first` when there is none. With
   `--remote-image` the same connect reads the registry settings and prints `doctor`'s
   registry-credential check; `upgrade` runs no other check, so run `doctor` first when you change
   registries.
2. **Prints its plan.** The line
   `keeps:   veth interface veth-mikroscope, router address 172.30.10.1, interface-list membership LAN, address-list membership LANs: not touched`,
   then the manifest, the container's removal and the new container, and any step of the install
   the router no longer holds. `--dry-run` stops here and connects to nothing: it skips step 1, so
   its plan comes from the flags alone, the architecture included (`arm64` unless `--arch` says
   otherwise).
3. **Asks**, unless `--yes`.
4. **Writes the manifest, replaces the container and probes the agent:**

   ```text
     wrote install manifest mikroscope/mikroscope.manifest.txt
     gone  container mikroscope
     pull  the router pulls registry-1.docker.io/jmrplens/mikroscope-agent:1.6.1 itself
     new   container mikroscope
   probing http://172.30.10.2:9123/healthz from this host …
     direct transport ok: agent 1.6.1 (<commit>) built <time>, 10 Hz, seq 8, 0 slipped, 2ms round trip
   ```

**What `upgrade` replaces**

- the install manifest, written first every time, so an install made before there was one gets it
- a new image and the container
- the envlist, rewritten from the flags `upgrade` is given; it refuses an install with a token when no `--token` is given
- any other object of the install the router no longer holds, created again before the container
- network objects stay

Every object carries the comment `mikroscope:<name> (managed by mikroscope)`

`mikroscope plan` prints every command before anything is written.

The envlist belongs to the container step, so `upgrade` writes it again from its own flags. Pass
the agent settings you installed with, or they return to their defaults: `--rate`, `--buffer`,
`--mem-limit-mb`, `--capture-mb`, `--triggers`, `--floor-hz`, `--memory-max`, `--privileged`,
`--restart-max-count` and `--restart-interval`. That is also how to change them without touching
the network objects. The shape (`--veth`, `--subnet`, the lists, `--disk` or `--ephemeral`,
`--port`, `--expose` with `--lan-address`, `--container-name`, `--start-on-boot`) comes from the
manifest; a flag that contradicts it is refused. An install with a token needs `--token` (or
`MIKROSCOPE_TOKEN`) again: `upgrade` refuses to rewrite its envlist without one.

An install made by a RouterOS script, the generator or by hand upgrades the same way from a computer
with the CLI. Without the CLI, remove it ([Uninstall](https://jmrplens.github.io/mikroscope/install/upgrade/#uninstall)) and run the new release's script.

### CLI and dashboards

`upgrade` replaces the agent only. The CLI upgrades by running its [install
script](https://jmrplens.github.io/mikroscope/install/cli/#one-command) again, and the collector image by pulling it again.
The dashboards are built into the CLI and the collector image, so publish them again after either
changes: restart the collector run with `--grafana`, or run `dashboards publish` or
`dashboards import` again ([Update and remove](https://jmrplens.github.io/mikroscope/dashboards/import-and-check/#update-and-remove)).

## Upgrade notes

When the install or your setup comes from an older release:

- **An install made by 1.3.1 or earlier has no manifest.** `status`, `upgrade` and `uninstall` read
  its shape from its tagged objects: `status` and `uninstall` print
  `no manifest at mikroscope/<name>.manifest.txt`, and `upgrade` prints
  `install on the router (its tagged objects, no manifest)`. The first `upgrade` writes one;
  `uninstall` removes such an install completely, the `mikroscope/` directory those releases left
  behind included.
- **Shape variables in `.env`.** A `.env` copied from an older `.env.example` may set
  `MIKROSCOPE_ARCH`, the lists or other shape variables. `status`, `upgrade` and `uninstall` refuse
  a value that contradicts the install; comment those lines out and let the router's manifest
  decide.
- **An exposed agent upgraded without a token.** An older `upgrade` without `--token` re-created an
  `--expose` agent with none while the LAN rules stayed. `doctor` warns
  `the installed agent published on the LAN asks for a token`; run `upgrade` with `--token`.
- **A registry mirror named in `registry-url`.** mikroscope 1.2.2 and earlier sent the image
  reference without its registry host and left the registry to `registry-url`. Now the host travels
  in the reference, and a reference with none goes to `registry-1.docker.io` directly. To keep
  pulling through a mirror or a pull-through cache, name its host:
  `--remote-image <mirror-host>/jmrplens/mikroscope-agent:1.6.1`.
- **A Prometheus job that scrapes the agent.** The agent serves no `/metrics`: an agent of 1.0.4 or
  earlier did. Point the job at the collector's `--prom` address
  ([Prometheus](https://jmrplens.github.io/mikroscope/sinks/prometheus/)).
- **Dashboards imported from 1.3.0 or earlier.** Publish or import them again ([CLI and
  dashboards](https://jmrplens.github.io/mikroscope/install/upgrade/#dashboards-after-an-upgrade)): the "Not available on this
  device" row shows `table … not found` badges on InfluxDB, the Elasticsearch dashboard opens with
  an empty Host and six red badges, and one imported with a probe into Grafana 12.3.0 shows
  `No SQL statements were provided in the query string` badges in that row.
- **A PostgreSQL alert file provisioned from 1.2.0** carries a `mikroscope-bridge-port-dark` rule
  that cannot run on the SQL schema: regenerate the rules and provision them again
  ([Alert rules](https://jmrplens.github.io/mikroscope/dashboards/alerts/)).
- **A whole InfluxDB write URL in `MIKROSCOPE_INFLUX_URL`** from a 1.0.x deployment keeps working;
  nothing to do.

## Uninstall

```sh
mikroscope uninstall --router admin@192.168.88.1          # lists what it would remove
mikroscope uninstall --router admin@192.168.88.1 --yes    # removes it, then verifies
```

It needs no other flag: the shape comes from the manifest, and a flag that contradicts it is
refused. Pass `--name` for an install with a name other than `mikroscope`. Without `--yes` it only
lists:

```text
router objects (add --yes to remove them):
  5 router object(s) tagged "mikroscope:mikroscope (managed by mikroscope)":
    container mikroscope
    address-list membership LANs
    interface-list membership LAN
    router address 172.30.10.1
    veth interface veth-mikroscope
  then any other object tagged "mikroscope:mikroscope (managed by mikroscope)", in /ip/firewall/address-list, /interface/list/member, /ip/firewall/nat, /ip/firewall/filter, /ip/firewall/raw, /ip/firewall/mangle, /ip/route, /container/mounts, /ip/address, /interface/veth, /interface/list, /disk
  and last the install manifest mikroscope/mikroscope.manifest.txt with mikroscope/mikroscope, and mikroscope when nothing else is in it
  (the manifest on the router, when there is one, says which objects the plan holds)
```

With `--yes` it removes, newest first, every object the manifest lists; stops the container and
waits while it runs or stops, up to 30 s, before removing it and its root; removes any other object
that carries the install's exact tag in those menus; and removes the manifest and the `mikroscope/`
directory last, when nothing else is in it. A removal that fails or prints anything shows as `skip`
with what RouterOS said, and the rest go on. Then it counts what is left:

```text
  0     install manifest mikroscope/mikroscope.manifest.txt
  0     veth interface veth-mikroscope
  0     router address 172.30.10.1
  0     interface-list membership LAN
  0     address-list membership LANs
  0     container mikroscope
verified: nothing mikroscope created remains on the router
```

When something remains it fails with `uninstall left objects behind`, naming the steps.

**What `uninstall` removes**

- every object in the install's manifest, and any other object that carries its tag
- the container root `mikroscope/<name>`, with the container, or on the manifest's word when a root is left
- the manifest, last, and then the `mikroscope` directory when nothing else is in it
- never device-mode, the `container` package, `/container/config`, or a list, disk or rule the router had before

Every object carries the comment `mikroscope:<name> (managed by mikroscope)`

`mikroscope plan` prints every command before anything is written.

`uninstall` removes by exact tag plus identity, never by pattern, and fails naming the step if anything remains.

### Never removed

- device mode, the `container` package and `/container/config` (`registry-url`, the registry
  username);
- a list, a disk, a firewall rule, or a file under `mikroscope/`, that was there before the install;
- a path the manifest lists beyond what its install creates: `uninstall` leaves it and reports it as
  left behind (`uninstall left objects behind: … which the manifest lists`).

The one exception is an empty `mikroscope/` directory: it goes even when it was there before, since
nothing says whose it is.

Without the CLI, run the removal commands by hand:
[Manual install: terminal](https://jmrplens.github.io/mikroscope/install/manual-cli/#remove).

## Remove dashboards and data

`--targets` widens `uninstall` past the router:

| Target      | What goes                                                                             |
| ----------- | ------------------------------------------------------------------------------------- |
| `router`    | everything the install created on the router, the default                             |
| `dashboard` | per store the sink flags name: the dashboard `mikroscope-<store>`, however it was imported, and the datasource `mikroscope-<store>`. Not the folder, an adopted datasource or provisioned alert rules |
| `data`      | the tables and indices the sinks wrote, and the files the file sinks wrote             |
| `all`       | the three above                                                                       |

```sh
export GRAFANA_TOKEN=…
mikroscope uninstall --targets all --influx "$MIKROSCOPE_INFLUX_URL" --influx-db mikroscope --grafana http://grafana:3000
mikroscope uninstall --targets all --influx "$MIKROSCOPE_INFLUX_URL" --influx-db mikroscope --grafana http://grafana:3000 --yes
```

Pass the same sink flags as `forward`. With `--targets dashboard` or `data` and no sink flag it finds
no store and prints `nothing of this is here to remove`; `all` then acts on the router objects
alone. Nothing goes without `--yes`. A datasource adopted with
`--grafana-datasource-uid` is never removed, and `--prom`, `--graphite` and `--sql` store nothing
this can remove, each saying why: [`uninstall --targets`](https://jmrplens.github.io/mikroscope/reference/cli/#uninstall---targets).

`--targets dashboard` also needs `--grafana` (or `MIKROSCOPE_GRAFANA_URL`, then `GRAFANA_URL`) and
`GRAFANA_TOKEN`, from a service account that may delete datasources ([Grafana
token](https://jmrplens.github.io/mikroscope/dashboards/import-and-check/#grafana-token)). The Grafana and the stores are
asked before the router is touched: a Grafana it cannot read, unreachable or refusing the token,
stops it with `asking Grafana whether dashboard mikroscope-<store> is there: …` before anything is
removed, the router objects included.

## See also

- [Install with the CLI](https://jmrplens.github.io/mikroscope/install/): what `install` writes, in order.
- [Installer safeguards](https://jmrplens.github.io/mikroscope/security/installer/#how-uninstall-proves-it-is-done): how
  `uninstall` proves it is done.
- [Offline install](https://jmrplens.github.io/mikroscope/install/offline/): upgrading from a new image tar.
- [CLI](https://jmrplens.github.io/mikroscope/reference/cli/#pass-the-same-shape-to-status-upgrade-and-uninstall): which flags
  the router's shape fills in.
