PiOS Bullseye killed Octoprint

Accidentally upgraded the wrong pi to Bullseye and now Octoprint is giving me an initialization error. When I try to hit the web page is actually goes to nginx webpage.

Is there a way to fix this or do I need to re-setup from scratch and then apply a backup?

I was running the latest Octoprint on a Pi3B.

Jay McDonald

Upgrading Buster to Bullseye will upgrade Python, which means that any virtual environments created with the old version will also need re-creating with the new version - I don't think there's a way to update them across minor (python) versions - I would happily be corrected by someone on this.

To do this with OctoPrint's virtual environment, I would do these three commands. The first is just backing up the old virtual environment in case you need to put it back, if successful you can remove it.

This does assume you're using an OctoPi image.

mv ~/oprint ~/oprint.backup
python3 -m venv ~/oprint
~/oprint/bin/pip install octoprint

All the configuration will remain, but plugins will need to be reinstalled - their config will be preserved as well. Restoring a backup would automatically reinstall plugins.

3 Likes

There are also some haproxy configuration changes required with the version included with Bullseye if you are using that too. I believe they are documented here.

1 Like

Thank you so much guys! I upgraded mine too and thought I'd destroyed it. Your collective solutions saved me much grief!

1 Like

Upgraded RPi OS to bullseye (python 3.7 -> 3.9).
Afterwards OctoPrint startup failed.
I tried python3 -m venv venv --upgrade, but it did not work. Also tried to manually adjust paths to 3.9.
Had to recreate and reinstall all plugins :frowning: Why? Does the setup differ? Can't it just reinstall/rebuild itself like npm?
I'm always a bit shocked whenever I have to touch python tooling.
Wanted to move the venv afterwards, but all scripts had absolute shebangs, so had to sed those.

It's working now, but I'd like to avoid reinstalling manually in the future.
I could pip freeze the venv, but that's the transitive hull of deps (which may shrink) - I just want a list of the top-level packages that I installed.
.octoprint/config.yaml has a list of plugins, but those names may be different from the package names :roll_eyes:
Can't OctoPrint offer to install plugins listed in the config if they're missing?
(Sorry for venting :grinning_face_with_smiling_eyes:)

Because the virtual environment keeps a copy of parts of the actual Python interpreter, it doesn't work like npm does just installing the dependencies, and so when your OS level interpreter breaks you are left with conflicting versions.

As I think I mentioned above - restoring a backup from OctoPrint will also reinstall all the plugins as well. So if you've created a backup first (which you should) then you can just restore it inside OctoPrint.

Why didn't it just work then after the upgrade?
Instead of npm, compare it to opam where the compiler is also just another installed package - never had problems there upgrading.
(Don't want to offend anyone, just curious what's the problem.)

Ok, thanks. IMO a backup of .octoprint should be enough, then you can use standard tools and don't have to fiddle around in the browser.

I just looked at pluginmanager/export which gives me a plug_list.json, however the names there are also not identifying...

For example it contains

  {
    "key": "bedlevelvisualizer",
    "name": "Bed Visualizer",
    "url": "https://github.com/jneilliii/OctoPrint-BedLevelVisualizer"
  },

but the pip package is called Bed-Visualizer.

Constraints are often not a bad idea...

I explained this already. It keeps copies of parts and references to other parts of the Python interpreter. When you upgrade it, you no longer have a Python 3.7 for it to reference, instead having Python 3.9, which is not compatible with the virtual environment.

The export from the plugin manager was intended to be coupled with an import function, but I never got round to writing that part of the code to expose it to the UI - it would be the same thing that the backup/restore feature works with.

A backup of just .octoprint is not enough, since that doesn't contain the plugins code. It has to be generated by OctoPrint from the list of plugins it has loaded. The individual package names will not help you either, as they aren't hosted on PyPi.

The way the backup/restore feature works is by matching up the identifiers in the plugin export with those available from https://plugins.octoprint.org/plugins.json which has the up-to-date information and an install URL. That's the only way you can figure out an install URL programmatically is from the plugin repository since that data is not stored in the Python package. The standardisation is in the plugin ID, which is the key field in your snippet. That matches the settings in config.yaml, the entry on the plugin mananger and when running the plugin internally in the code.

So it combines the disadvantages of both approaches?
Actually it's even worse since it would not have happened if it just didn't care about the system python.
After reinstalling it all worked again.

Thanks for the explanation.
This script will give the commands to install all plugins from the config - no need to start OctoPrint:

# list install commands for plugins in config
import yaml
from os.path import expanduser
ids = []
with open(expanduser('~/.octoprint/config.yaml'), "r") as stream:
    config = yaml.safe_load(stream)
    plugins = config['plugins']
    ids = [k for k in plugins.keys() if k not in plugins['_disabled'] + ['_disabled']]

import urllib.request, json 
with urllib.request.urlopen("https://plugins.octoprint.org/plugins.json") as url:
    plugins = json.loads(url.read().decode())
    for plugin in plugins:
        if plugin['id'] in ids:
            print('pip install', plugin['archive'])

Thanks Mate, this helped me fix this issue for me.

For others who have run into this issue, you will also need to upgrade your haproxy file as @jneilliii has mentioned. edit /etc/haproxy/haproxy.cfg to the following and then restart haproxy service:

global
        maxconn 4096
        user haproxy
        group haproxy
        log /dev/log local1 debug
        tune.ssl.default-dh-param 2048

defaults
        log     global
        mode    http
        compression algo gzip
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor
        maxconn 2000
        timeout connect 5s
        timeout client  15m
        timeout server  15m

frontend public
        bind :::80 v4v6
        bind :::443 v4v6 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam if { path_beg /webcam/ }
        use_backend webcam_hls if { path_beg /hls/ }
        use_backend webcam_hls if { path_beg /jpeg/ }
        default_backend octoprint

backend octoprint
        acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

        http-request replace-path ^([^\ :]*)\ /(.*) \1\ /\2
        http-request add-header X-Scheme https if needs_scheme { ssl_fc }
        http-request add-header X-Scheme http if needs_scheme !{ ssl_fc }
        option forwardfor
        server octoprint1 127.0.0.1:5000
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend webcam
        http-request replace-path /webcam/(.*) /\1
        server webcam1  127.0.0.1:8080
        errorfile 503 /etc/haproxy/errors/503-no-webcam.http

backend webcam_hls
        server webcam_hls_1 127.0.0.1:28126
        errorfile 503 /etc/haproxy/errors/503-no-webcam-hls.http

If you only fixed that issue, you'd still have a number of errors in octoprint.log. some of the other errors I ran into (so hopefully other searching for the issues find this thread):

CRITICAL - Could not initialize plugin manager: cannot import name 'dist' from 'distutils' (/home/pi/oprint/lib/python3.7/distutils/__init__.py)
Could not find platform independent libraries <prefix>
"ImportError: No module named encodings"

And a few others

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.