Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

menue thinks docker 20.10 is less than 18.2.0 #496

Closed
Magke opened this issue Feb 9, 2022 · 1 comment · Fixed by #498
Closed

menue thinks docker 20.10 is less than 18.2.0 #496

Magke opened this issue Feb 9, 2022 · 1 comment · Fixed by #498

Comments

@Magke
Copy link

Magke commented Feb 9, 2022

grafik

@Paraphraser
Copy link

I don't really understand why this happens but I do know how to cure it.

If we go back in time to gcgarner/IOTstack:

Thereafter, both docker and docker-compose were updated by apt.

That approach was inherited by SensorsIot/IOTstack.

The problem was that the docker-compose installed by apt was never actually updated during the evolution of Buster and became increasingly out-of-date. The workaround was to delete the apt version and use pip3 instead:

$ sudo apt -y remove docker-compose
$ sudo pip3 install -U docker-compose

Next came "modern" docker-compose which is installed by downloading a platform- and version-specific compiled binary from docker/compose/releases and copying it to the right places.

Depending on when you started with IOTstack and how long it has been since you last rebuilt your Raspberry Pi, you can have various versions and combinations of docker and docker-compose installed on your Pi.

The trigger conditions for getting a version number like "20.10.5+dfsg1" seem to be:

  1. Having a version of docker-compose installed by apt.
  2. That version of docker-compose recently being updated by apt, possibly as a side-effect of upgrading to Bullseye, or possibly the result of something that happened behind the scenes related to Bullseye that affected Buster.

How or why apt updating docker-compose affects the version number of docker is not clear. However, the menu does not expect version numbers with a "+" in the middle so the parsing algorithm gets it wrong and decides the installed version needs to be upgraded - which it can't be.

The solution is to get rid of both docker and docker compose, and then re-install them properly.

There is a wrinkle, though. If you're also running Supervised Home Assistant (also known as Home Assistant Core and hass.io) then removing docker causes Home Assistant to stop working. The way Supervised Home Assistant gets installed has also gone through a few changes and the IOTstack menu methods no longer work. In the case of "old menu", the HA script has disappeared. In the case of "new menu", an intermediate script (nothing to do with IOTstack) is broken and the author seems to have given up. There are some pull requests pending to remove Home Assistant from the IOTstack menu.

To be clear, this does not affect the standalone Home Assistant container. That still works just fine.

If you read the material here it explains how to uninstall Supervised Home Assistant (if you are running it), docker and docker-compose, and then re-install the components correctly.

To be clear, Supervised Home Assistant can be installed alongside IOTstack but the IOTstack menu can't do it any more.

Anyway, if you follow those instructions, everything will be reinstalled correctly, the menu will be happy and won't complain about "20.10.5+dfsg1", and the problem will just go away.

I hope this helps.

ukkopahis added a commit to ukkopahis/IOTstack that referenced this issue Feb 15, 2022
ukkopahis added a commit to ukkopahis/IOTstack that referenced this issue Feb 15, 2022
Debian apt installs docker version with a postfix. E.g. "20.10.5+dfsg1"
Ignore this when checking for version.

Fixes SensorsIot#496
Fixes SensorsIot#447
Paraphraser added a commit to Paraphraser/IOTstack that referenced this issue Oct 24, 2023
One of the most surprising things about SensorsIot#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 SensorsIot#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 SensorsIot#496. And SensorsIot#503.
And SensorsIot#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 SensorsIot#737 shortly.

Signed-off-by: Phill Kelley <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants