Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2023-10-24 replacement for install.sh script - master branch
One of the most surprising things about #729 (at least to me) was how it implied that someone had actually used the `install.sh` script. I say this with the utmost respect for the original author and subsequent contributors (who did all the work while I just sat on my hands) but, after studying the existing script, I reached the conclusion that the wisest course of action was to start from scratch. There were seemed to be so many issues in the existing `install.sh` that it was difficult to know how much could be salvaged: * It creates `.new_install` in the current working directory (typically `~`) **before** cloning IOTstack. The menu, of course, expects that file to be in `~/IOTstack` so the menu thinks no installation work has been done. * It (correctly) uses the "convenience script" to install `docker` but then uses `apt` to install `docker-compose` (which is wrong). The result is the Python version of `docker-compose` being installed and, as a side effect, `docker` is unconditionally downgraded to a compatible version (which is where the problematic `+dfsg1` version suffix comes from - see #496). The long-term effect is that both `docker` and `docker-compose` become pinned and are never subsequently upgraded by `apt`. Another side-effect is the version of `docker-compose-plugin` installed by the convenience script becomes inaccessible. * The `usermod` commands for `bluetooth` appear twice; those for the `docker` group three times. This probably doesn't actually harm anything but it certainly doesn't lend itself to clarity of intention. * The version-checking is brute force and makes assumptions that won't always necessarily hold, such as that there are always three SEMVER components and that suffixes like `+dfsg1` won't result in a mess, like they did in similar code in the menu (again I refer to #496. And #503. And #585). Indeed, it's really only luck which means the `+dfsg1` doesn't appear until after `install.sh` has finished its work. What this replacement script attempts to do is: 1. Use absolute paths throughout so there is no ambiguity about where files/folders are located. Although this replacement script defaults to `~/IOTstack` the default can be overridden by prepending the correct path, as in: ``` $ IOTSTACK="$HOME/TestIOTstack" ./install.sh ``` 2. Use a **rational** method of version checking (specifically `dpkg --compare-versions`) which can actually handle the cases of one, two, three or more SEMVER fields correctly and which isn't fazed by weird suffixes. 3. Install the minimum set of dependencies needed by IOTstack. This is on the assumption that `install.sh` may be being used on either a green-fields system or an existing system. PiBuilder excels at green-fields but could prove problematic were it to be used on an already-highly-customised working system. My own view is that a clean slate plus PiBuilder produces a better outcome but there is definitely a case to be made for supporting adding IOTstack to an existing system. 4. Install `docker` and `docker-compose-plugin` correctly so both `docker-compose` (with hyphen) and `docker compose` (without hyphen) are the same binary and produce the same result. One side effect of correct installation is that both `docker` and `docker-compose-plugin` are updated by `apt`. 5. Adds the user to the required groups (once!). 6. Installs Python dependencies in a Bookworm-friendly manner. And, yes, I do realise using `--break-system-packages` is suboptimal but that's something that can be addressed by people with Python expertise (and, given no PRs have been submitted to attend to this, those people are probably a bit thin on the ground). In my view a dash of *sub-optimal* is better than not working at all on Bookworm. 7. Sets Raspberry Pi cmdline options on a per-option basis, rather than assuming the options will always appear in the same order. This replacement script is also specifically designed to be run multiple times without doing any harm. It is also designed so that it can be run safely *after* a PiBuilder run. This serves four purposes: 1. If the script is being run on an existing system where, say, an obsolete version of `docker` is installed, the script will explain how to remove `docker`, after which the script should be re-run. This basic approach of check, explain how to recover, re-try, continues until the script completes normally. 2. Ultimately, my intention is to propose another PR to remove **all** "installation" and version-checking tasks from the menu. To that end, this replacement script writes its exit status to `~/IOTstack/.new_install`. Eventually, I see the menu behaving like this: - if `.new_install` is not present or is present and contains a non-zero exit code, the menu will prompt the user to run the (replacement) `install.sh`. 3. As a guided-migration tool. Once the menu has been changed as above, the mostly likely situation a user will encounter after the subsequent pull from GitHub is the menu recommending that (the new) `install.sh` should be run. If the script finds the user's environment is obsolete (eg ancient pinned versions of `docker` or `docker-compose`) the script will guide the user through the upgrade. Rinse, repeat and eventually the script will complete normally, after which the user's system will be fully up-to-date and the menu will just get on with the job of being the menu. 4. As a general-purpose "fixup" tool. Anyone reporting problems with IOTstack which implicate anything this replacement script is designed to handle can be instructed to run `install.sh` and see what happens. This replacement script updates minimum version numbers to something more recent: * docker version 24 or later (previously 18.2.0 or later) * docker-compose version 2.20 or later (previously not checked) * Python version 3.9 or later (previously 3.6.9 or later) I have tested this script on: 1. Raspberry Pi 4B running Bullseye and Bookworm. 2. Debian on Proxmox, running Bullseye and Bookworm. 3. Multiple runs of this script on each of the above (to ensure second or subsequent runs do no harm). 4. After running PiBuilder on clean installs of all four test platforms (ie 1+2 above), also to ensure a run does no harm. 5. After running the **existing** `install.sh` on all four test platforms, to ensure any damage (eg pinned obsolete versions) is discovered and reported, and that by following the repair instructions and re-running the **new** `install.sh` ultimately gives the platform a clean bill of health. Documentation will be added to #737 shortly. Signed-off-by: Phill Kelley <[email protected]>
- Loading branch information