# camp_sysinfo installer (v3.8.0)

This directory contains the install and uninstall tooling for the v3.8.0 sysinfo client layout.

## Paths

Debian and Devuan use bindir `/opt/camp/sysinfo_client` and confdir `/etc/camp/sysinfo_client`.

FreeBSD and OPNsense use bindir `/usr/local/opt/camp/sysinfo_client` and confdir `/usr/local/etc/camp/sysinfo_client`.

The config file is always `<confdir>/sysinfo_client.yaml`.

## Fresh install from tarball

The URLs below are the stable channel; a permanent beta host uses `https://example.org/sysinfo_client/testing/` instead (see "Release channels" in the top-level `README.md`). `example.org` stands for your own release server.

```sh
fetch -o /tmp/sysinfo-client.tgz https://example.org/sysinfo_client/sysinfo-client.tgz
mkdir -p /tmp/sysinfo_install
cd /tmp/sysinfo_install
tar -xzf /tmp/sysinfo-client.tgz
./sysinfo_client/installer/setup --quiet
```

Linux bootstrap fetch alternative:

```sh
wget -O /tmp/sysinfo-client.tgz https://example.org/sysinfo_client/sysinfo-client.tgz
```

## Fresh install from svn

```sh
svn checkout http://svn.dailydata.net/svn/camp_sysinfo_client_3/tags/v3.8.1/unix /opt/camp/sysinfo_client
/opt/camp/sysinfo_client/installer/setup --quiet
```

## Optional: server.info (before the install)

`/etc/server.info` (or `/usr/local/etc/server.info`) identifies this host: `Owner` (the client name), `Location`, `Hostname`, `UUID`, `Serial`, `OS_Type` and `Tags`. Its values override the config file at every run, and a fresh install takes the client name from it when the seed has none. Create it before running `setup`; if the release location also publishes a copy (the same file as `installer/server.info.sample`), fetch it and edit it:

```sh
fetch -o /etc/server.info https://example.org/sysinfo_client/server.info
# Linux: wget -O /etc/server.info https://example.org/sysinfo_client/server.info
vi /etc/server.info
```

In that file each key is listed with no value (`Owner    :`), with the meaning of each in comments above. Type the value after the colon for each one you want (`Owner    : Acme Corp`) and leave the others blank: a key with no value is ignored, so that setting comes from the config file or autodetection as if the line were absent. Keys are case insensitive, blank values are ignored, and if a key appears twice the first one wins.

## Upgrade on hosts that already run v3.8+

```sh
/opt/camp/sysinfo_client/sysinfo_update --quiet
```

Examples:

```sh
/opt/camp/sysinfo_client/sysinfo_update --method tarball --url https://example.org/sysinfo_client/sysinfo-client.tgz --sha256-url https://example.org/sysinfo_client/sysinfo-client.tgz.sha256 --quiet
```

```sh
/opt/camp/sysinfo_client/sysinfo_update --method svn --version v3.8.1 --quiet
```

All updater options (`sysinfo_update --help`): `--method auto|tarball|svn` (auto uses svn when the install directory is a working copy and `svn` exists, otherwise the tarball), `--url`, `--sha256-url`, `--svn-url`, `--version` (a tag, for svn), `--force` (update even when the version is unchanged), `--require-checksum` (fail when no checksum file is published), `--os`, `--workdir`, `--quiet`.

With the tarball method the updater first fetches the small `.sha256` file and compares it with the checksum recorded in the config directory (`update_installed.sha256`) when the last release was installed; if they are equal it stops with `nochange` without downloading the tarball, so a daily check on many hosts costs about 85 bytes each. Otherwise it downloads the tarball, verifies its checksum (a mismatch aborts before anything is unpacked; a missing checksum file is logged as a warning), unpacks it, and, only when no checksum was recorded, compares its version with the installed one. A recorded checksum that differs means the content changed, so it installs even when the version string is the same. If no checksum was recorded and the versions are equal it stops with `nochange`, records the published checksum, unless `--force` is given; otherwise it runs the new tree's `installer/setup --quiet --upgrade`. The install is swapped in place: the old tree is kept as `<bindir>.previous` (one generation), and if the final smoke check fails the previous tree is restored. `reports/` is kept. `server.info` is never touched. URLs come from the command line, then the `update` block of the config file, then built-in defaults; the install seed is not used when updating.

The updater appends progress and failures to `/var/log/sysinfo_client_update.log` (or `sysinfo_update.log` in the install directory when `/var/log` is not writable) and prints to STDOUT. It is not scheduled by default. To run it from cron, add a line such as:

```sh
# 17 3 * * 0 root /opt/camp/sysinfo_client/sysinfo_update --quiet
```

## Setup options and result

`installer/setup --help` lists them: `--os`, `--quiet` (never reads STDIN; a fresh install with no client name from the seed or `server.info` fails), `--dryrun` (changes nothing), `--upgrade`, `--seed <path|URL>`, `--force` (when both a legacy and a new config exist, keeps the new one and leaves the legacy directory alone), `--root <path>` (test prefix).

On a fresh install the config file is created from the seed (with `--seed`, a path or URL), or from `sysinfo_client.conf.template.yaml` when no seed is given or it cannot be fetched. The seed is where the site's `update:` URLs (`url`, `sha256_url`) come from; there are no built-in ones, and `sysinfo_update` stops with a message naming the missing key if they are absent. Blank values are then filled from `server.info` and the machine's own identity. A seed is used only when no config file exists.

Exit status is 0 for installed or upgraded, 1 for nothing to do, and 2 or more for failure. The last output line is always `RESULT: <ok|nochange|fail> <version> <message>`, for scripting across a fleet.

## Bootstrap from legacy v3.7.1 hosts

Run this once per host to move from dash-layout installs to underscore-layout installs:

```sh
fetch -o /tmp/s.tgz https://example.org/sysinfo_client/sysinfo-client.tgz && tar -xzf /tmp/s.tgz -C /tmp && /tmp/sysinfo_client/installer/setup --quiet
```

`setup` detects and migrates legacy paths such as `/opt/camp/sysinfo-client` and `/etc/camp/sysinfo-client`: the config directory is moved, local `modules/` and `scripts/` directories are renamed `sensors/` and `transports/`, the old config is kept as `sysinfo-client.yaml.v3.7.1.bak`, and every value in it is preserved (only the directory paths are rewritten and an `update` block is added). The old schedule entry and then the old install directory (with its `reports/` moved across) are removed only after the new install passes its smoke check, and this works even when `setup` is run from inside the old install directory (e.g. after an `svn switch` there; `cd` to the new directory afterwards); if anything fails before that, the legacy layout is put back as it was.

## OPNsense scheduling

`setup` rewrites `/usr/local/opnsense/service/conf/actions.d/actions_sysinfo.conf` and runs `service configd restart`.

After install, enable one cron job in the web UI at System > Settings > Cron using the action that shows message `Collecting Systems Information` and description `Collects Systems Info and sends to CAMP`.

## Uninstall

```sh
/opt/camp/sysinfo_client/installer/uninstall
```

Keep config while removing binaries and schedule entries:

```sh
/opt/camp/sysinfo_client/installer/uninstall --keep-config
```

## Script inventory

- `setup`: install, upgrade swap/rollback, legacy migration, scheduling, smoke check.
- `validateDependencies`: required dependency validation/install (`perl` and `YAML::Tiny`) and optional tool reporting. A missing `YAML::Tiny` is installed with the package manager (`apt-get` or `pkg`) if there is one, then with `cpanm`, then with `cpan` (run with `PERL_MM_USE_DEFAULT=1`) if the earlier ones are missing or fail; `setup` loads `YAML::Tiny` only after this step. `LWP::UserAgent` and `LWP::Protocol::https`, needed only by the `upload_http` transport, are installed the same way, but a failure there is just a warning.
- `mergeconfig`: run by `setup` (`--quiet`, which it accepts but never needs, since it asks no questions) to merge `server.info` and defaults into the config file (was `configure` before v3.8.1; `configure` now edits the config with dsEdit).
- `permissions`: owner/mode enforcement for install tree.
- `determineOS`: returns one token (`debian`, `freebsd`, `opnsense`).
- `uninstall`: removes install tree, `.previous`, schedule entries, and optionally config.
- `installer_shared.pm`: functions shared by `setup`, `sysinfo_update` and the other scripts (command running, file handling, downloads).
- `installer_config.pl`: the per-OS paths and the built-in release URLs, in one table.
- `sysinfo_client.conf.template.yaml`: the config file a fresh install starts from.
- `sysinfo_client.seed.example.yaml`: an example install seed with site defaults.
- `actions_sysinfo.conf`: the OPNsense action file `setup` installs.
- `server.info.sample`: a sample of the optional `server.info` file.

## Install log

`setup` copies everything it prints, including the output of the package manager, `cpanm` and `cpan` run by `validateDependencies`, to `/tmp/sysinfo_client_install.log`. The file is appended to on each run (each run starts with a `==== setup <version> <time> args: ... ====` line), is readable only by the user who ran the installer, and is under `/tmp` so it is not kept across a reboot on most systems. When a dependency install fails, look there for the failing command and the line saying which method is tried next.
