Skip to content

Conversation

@phillxnet
Copy link
Member

@phillxnet phillxnet commented Jun 1, 2023

As part of our move to Python 3 we must first establish our new python 3 dependencies via Poetry. And resolve all issues re dependencies from there on.

In this Draft work-in-progress the base OS used in Leap 15.4.

See issue #2564 for context

Deleting poetry.lock and recreating via:

cd /opt/rockstor
poetry lock

with the changes within this draft PR for discussion.

And then we see our first failure during the subsequent install/build of our stated dependencies:

rm -rf .venv/
poetry install

Creating virtualenv rockstor in /opt/rockstor/.venv
Installing dependencies from lock file

Package operations: 30 installs, 0 updates, 0 removals

  • Installing certifi (2021.10.8)
  • Installing charset-normalizer (2.0.12)
  • Installing greenlet (2.0.2)
  • Installing idna (2.10)
  • Installing pytz (2022.6)
  • Installing six (1.16.0)
  • Installing urllib3 (1.26.12)
  • Installing django (1.11.29)
  • Installing gevent (1.1.2): Failed

  EnvCommandError

  Command ['/opt/rockstor/.venv/bin/pip', 'install', '--no-deps', '/root/.cache/pypoetry/artifacts/2b/9a/65/69c2b29d8ba2348465126687493d4827d5553e8e1465e4d3cb94bc1043/gevent-1.1.2.tar.gz'] errored with the following return code 1, and output: 
  Processing /root/.cache/pypoetry/artifacts/2b/9a/65/69c2b29d8ba2348465126687493d4827d5553e8e1465e4d3cb94bc1043/gevent-1.1.2.tar.gz
    Preparing metadata (setup.py): started
    Preparing metadata (setup.py): finished with status 'done'
  Building wheels for collected packages: gevent
    Building wheel for gevent (setup.py): started
    Building wheel for gevent (setup.py): finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /opt/rockstor/.venv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-2hw6qcwc/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-2hw6qcwc/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-utjon_l2
         cwd: /tmp/pip-req-build-2hw6qcwc/
    Complete output (62 lines):
    running bdist_wheel
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.6
    creating build/lib.linux-x86_64-3.6/gevent
    copying gevent/__init__.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_corecffi_build.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_fileobjectcommon.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_fileobjectposix.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_semaphore.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_socket2.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_socket3.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_socketcommon.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_ssl2.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_ssl3.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_sslgte279.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_tblib.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_threading.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/_util_py2.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/backdoor.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/baseserver.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/builtins.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/core.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/corecffi.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/coros.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/event.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/fileobject.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/greenlet.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/hub.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/local.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/lock.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/monkey.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/os.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/pool.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/pywsgi.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/queue.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/resolver_ares.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/resolver_thread.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/select.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/server.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/signal.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/socket.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/ssl.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/subprocess.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/thread.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/threading.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/threadpool.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/timeout.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/util.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/win32util.py -> build/lib.linux-x86_64-3.6/gevent
    copying gevent/wsgi.py -> build/lib.linux-x86_64-3.6/gevent
    running build_ext
    Running '(cd  "/tmp/pip-req-build-2hw6qcwc/libev"  && /bin/sh ./configure   && cp config.h "$OLDPWD" ) > configure-output.txt' in /tmp/pip-req-build-2hw6qcwc/build/temp.linux-x86_64-3.6/libev
    building 'gevent.corecext' extension
    creating build/temp.linux-x86_64-3.6/gevent
    gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -DOPENSSL_LOAD_CONF -fwrapv -fno-semantic-interposition -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -DLIBEV_EMBED=1 -DEV_COMMON= -DEV_CLEANUP_ENABLE=0 -DEV_EMBED_ENABLE=0 -DEV_PERIODIC_ENABLE=0 -Ibuild/temp.linux-x86_64-3.6/libev -Ilibev -I/opt/rockstor/.venv/include -I/usr/include/python3.6m -c gevent/gevent.corecext.c -o build/temp.linux-x86_64-3.6/gevent/gevent.corecext.o
    gevent/gevent.corecext.c:5:10: fatal error: Python.h: No such file or directory
     #include "Python.h"
              ^~~~~~~~~~
    compilation terminated.
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
    ERROR: Failed building wheel for gevent
    Running setup.py clean for gevent
  Failed to build gevent
  Installing collected packages: gevent
      Running setup.py install for gevent: started
      Running setup.py install for gevent: finished with status 'error'
      ERROR: Command errored out with exit status 1:
       command: /opt/rockstor/.venv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-2hw6qcwc/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-2hw6qcwc/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-139zzw30/install-record.txt --single-version-externally-managed --compile --install-headers /opt/rockstor/.venv/include/site/python3.6/gevent
           cwd: /tmp/pip-req-build-2hw6qcwc/
      Complete output (15 lines):
      running install
      /opt/rockstor/.venv/lib/python3.6/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        setuptools.SetuptoolsDeprecationWarning,
      running build
      running build_py
      running build_ext
      Running '(cd  "/tmp/pip-req-build-2hw6qcwc/libev"  && /bin/sh ./configure   && cp config.h "$OLDPWD" ) > configure-output.txt' in /tmp/pip-req-build-2hw6qcwc/build/temp.linux-x86_64-3.6/libev
      building 'gevent.corecext' extension
      creating build/temp.linux-x86_64-3.6/gevent
      gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -DOPENSSL_LOAD_CONF -fwrapv -fno-semantic-interposition -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -DLIBEV_EMBED=1 -DEV_COMMON= -DEV_CLEANUP_ENABLE=0 -DEV_EMBED_ENABLE=0 -DEV_PERIODIC_ENABLE=0 -Ibuild/temp.linux-x86_64-3.6/libev -Ilibev -I/opt/rockstor/.venv/include -I/usr/include/python3.6m -c gevent/gevent.corecext.c -o build/temp.linux-x86_64-3.6/gevent/gevent.corecext.o
      gevent/gevent.corecext.c:5:10: fatal error: Python.h: No such file or directory
       #include "Python.h"
                ^~~~~~~~~~
      compilation terminated.
      error: command 'gcc' failed with exit status 1
      ----------------------------------------
  ERROR: Command errored out with exit status 1: /opt/rockstor/.venv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-2hw6qcwc/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-2hw6qcwc/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-139zzw30/install-record.txt --single-version-externally-managed --compile --install-headers /opt/rockstor/.venv/include/site/python3.6/gevent Check the logs for full command output.
  

  at ~/.local/share/pypoetry/venv/lib64/python3.6/site-packages/poetry/utils/env.py:1195 in _run
      1191│                 output = subprocess.check_output(
      1192│                     cmd, stderr=subprocess.STDOUT, **kwargs
      1193│                 )
      1194│         except CalledProcessError as e:
    → 1195│             raise EnvCommandError(e, input=input_)
      1196│ 
      1197│         return decode(output)
      1198│ 
      1199│     def execute(self, bin, *args, **kwargs):

  • Installing oauthlib (3.1.0)
  • Installing python-engineio (2.3.2)
  • Installing requests (2.27.1)

As expected and detailed in our ongoing issue #1877
comment: #1877 (comment)

We have a blocker of gevent!

As part of our move to Python 3 we must first establish our
new python 3 dependencies via Poetry. And resolve all issues
re dependencies from there on.
@phillxnet
Copy link
Member Author

From the following:

gevent/gevent.corecext.c:5:10: fatal error: Python.h: No such file or directory
     #include "Python.h"
              ^~~~~~~~~~
    compilation terminated.
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
    ERROR: Failed building wheel for gevent

we may just have an incomplete dev install for our new Python 3.6.

@phillxnet
Copy link
Member Author

zypper in python3-devel

and re-running the poetry install

buildvm:/opt/rockstor # poetry install
Installing dependencies from lock file

Package operations: 19 installs, 0 updates, 0 removals

  • Installing gevent (1.1.2)
  • Installing chardet (4.0.0)
  • Installing dbus-python (1.2.18)
  • Installing distro (1.6.0)
  • Installing django-braces (1.13.0)
  • Installing django-oauth-toolkit (1.1.2)
  • Installing django-pipeline (1.6.9)
  • Installing djangorestframework (3.9.3)
  • Installing gevent-websocket (0.9.5)
  • Installing gunicorn (19.10.0)
  • Installing huey (2.3.0)
  • Installing mock (1.0.1)
  • Installing psutil (5.9.4)
  • Installing psycogreen (1.0)
  • Installing psycopg2 (2.8.6)
  • Installing python-socketio (1.6.0)
  • Installing pyzmq (19.0.2)
  • Installing supervisor (4.2.4)
  • Installing urlobject (2.1.1)

Installing the current project: rockstor (4.6.0)

@phillxnet
Copy link
Member Author

phillxnet commented Jun 1, 2023

A subsequent build.sh attempt using the new Python 3.6 .venv indicates an issue with Django settings:

buildvm:/opt/rockstor # ./build.sh 
Retrieving Poetry metadata

The latest version (1.1.15) is already installed.

Traceback (most recent call last):
  File "/opt/rockstor/.venv/bin/django-admin", line 8, in <module>
    sys.exit(execute_from_command_line())
  File "/opt/rockstor/.venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/opt/rockstor/.venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 308, in execute
    settings.INSTALLED_APPS
  File "/opt/rockstor/.venv/lib/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/opt/rockstor/.venv/lib/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/opt/rockstor/.venv/lib/python3.6/site-packages/django/conf/__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/rockstor/src/rockstor/settings.py", line 320
    MAX_SHARE_SIZE = 18014398509481984L
                                      ^
SyntaxError: invalid syntax

Porting P2 to P3 reference: https://portingguide.readthedocs.io/en/latest/numbers.html#the-l-suffix-not-allowed-in-numeric-literals

Python 3 no longer uses the "L" suffix:
@phillxnet
Copy link
Member Author

subsequent ./build.sh:

...
File "/opt/rockstor/src/rockstor/storageadmin/models/__init__.py", line 19, in <module>
    from pool import Pool  # noqa E501
ModuleNotFoundError: No module named 'pool'

@phillxnet
Copy link
Member Author

I am currently chasing down all our old-style imports where we now need to include the current directory name.

Python 3 has more stringent import path requirements.
@phillxnet
Copy link
Member Author

Post the last commit re full paths in imports for Python 3 compatibility we have our initial build.sh execution.

buildvm:/opt/rockstor # ./build.sh
...
ROCKSTOR BUILD SCRIPT COMPLETED

If installing from source, from scratch, for development:
1. Run 'cd /opt/rockstor'.
2. Run 'systemctl start postgresql'.
3. Run 'export DJANGO_SETTINGS_MODULE=settings'.
4. Run 'poetry run initrock' as root (equivalent to rockstor-pre.service).
5. Run 'systemctl enable --now rockstor-bootstrap'.

@phillxnet
Copy link
Member Author

Embarking on initial string conversion now as Python 3 does things differently.
Nice blog reference: https://blog.feabhas.com/2019/02/python-3-unicode-and-byte-strings/

Byte strings support most of the methods provided with Unicode strings (data type str). If your code uses string methods, subscripts and slices it is quite likely to continue working with byte strings.

  • Python 3 string class (str) stores Unicode strings (previously u"unicode-string" in Python 2).
  • String literals (quoted strings) are Unicode unless prefixed with a lower case b (e.g. b"literal-string")
  • There is a new byte string (bytes) class.
  • Conversion to Unicode requires knowledge of the underlying character set: usually (default in Linux and OSX) UTF-8.
  • bytes.decode() for byte-string_to_unicode, or str.encode() to convert unicode_to_a_byte-string.
  • If one opens a file in binary mode - byte strings result.

On formatting enhancements in this area we also now have f stings in 3.6 and onwards:

  • Enhances "value is {}".format(var) to f"value is {var}".

phillxnet added 3 commits June 2, 2023 13:29
Python 3 has more stringent import path requirements.
md5.update(l)
TypeError: Unicode-objects must be encoded before hashing
@Hooverdan96
Copy link
Member

This is great progress @phillxnet!

@phillxnet
Copy link
Member Author

@Hooverdan96 Cheers, just wanted to get some leg-work done on this so we can start spinning off more focused issues.
Plus getting to grips with what this move will actually entail.

@Hooverdan96
Copy link
Member

I am actually really surprised that you got away with not changing any of the other package versions (chardet, gevent, etc.) since some of these have not even had an official release in a couple of years (like django-braces, gevent-websocket or urlobject and our current version is still below the last "old" one). That seems encouraging, so you can break this into smaller changes at a time.

@phillxnet
Copy link
Member Author

@Hooverdan96 Re:

I am actually really surprised that you got away with not changing any of the other package versions (chardet, gevent, etc.)

We are not actually there yet thought: We may yet have issues down the way, but fingers cross we may yet pull this off with our existing pinned versions. "gevent-websocket" yes that one is a worry.

Currently I'm battling with a simple file open not working as expected. But given some more patience we may yet find out more about how we have to change our existing code. Lots of suttle changes. If I get really stuck I'll post and we can sort out what obvious thing I'm missing. But currently just familiarising myself with some of the changes we may need here code wise. Still quite a way from much working as-is.

There was a subtle file pointer behaviour change
between 2.7 and 3.6 which broke this mechanism.
Address TODO re custom opener re Python 3.
@phillxnet
Copy link
Member Author

OK, that set of bits (commit) took ages but I had to track down a 'strangeness' that was not there in 2.7. Ended up doing a tidy and prior TODO of mine to address and we now have a working initrock.py script (rockstor-pre.service):

buildvm:/opt/rockstor # systemctl start rockstor-pre
buildvm:/opt/rockstor # systemctl status rockstor-pre
● rockstor-pre.service - Tasks required prior to starting Rockstor
     Loaded: loaded (/usr/lib/systemd/system/rockstor-pre.service; disabled; vendor preset: disabled)
     Active: active (exited) since Fri 2023-06-02 20:26:25 WEST; 10s ago
    Process: 5586 ExecStart=/root/.local/bin/poetry run initrock (code=exited, status=0/SUCCESS)
   Main PID: 5586 (code=exited, status=0/SUCCESS)

Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,069: /etc/systemd/system/nginx.service.d/30-rockstor-nginx-override.conf up-to-date.
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,069: /usr/lib/systemd/system/rockstor-pre.service up-to-date.
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,069: /usr/lib/systemd/system/rockstor.service up-to-date.
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,070: /usr/lib/systemd/system/rockstor-bootstrap.service up-to-date.
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,070: ### BEGIN Establishing poetry path to binaries in local files...
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,070: samba_config already looks good.
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,071: rockstor_crontab already looks good.
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,071: The replication_crontab (/etc/cron.d/replicationtab) could not be found
Jun 02 20:26:25 buildvm poetry[5586]: 2023-06-02 20:26:25,071: ### DONE establishing poetry path to binaries in local files.
Jun 02 20:26:25 buildvm systemd[1]: Finished Tasks required prior to starting Rockstor.

with our new-shiny .venv (for Leap 15.4):

buildvm:/opt/rockstor # poetry env info

Virtualenv
Python:         3.6.15
Implementation: CPython
Path:           /opt/rockstor/.venv
Valid:          True

System
Platform: linux
OS:       posix
Python:   /usr

@phillxnet
Copy link
Member Author

And we have a working rockstor.service as well apparently !!

buildvm:/opt/rockstor # systemctl start rockstor
buildvm:/opt/rockstor # systemctl status rockstor
● rockstor.service - Rockstor startup script
     Loaded: loaded (/usr/lib/systemd/system/rockstor.service; disabled; vendor preset: disabled)
     Active: active (running) since Fri 2023-06-02 20:33:49 WEST; 18s ago
   Main PID: 6013 (supervisord)
      Tasks: 10
     CGroup: /system.slice/rockstor.service
             ├─ 6013 /opt/rockstor/.venv/bin/python /opt/rockstor/.venv/bin/supervisord -c /opt/rockstor/etc/supervisord.conf
             ├─ 6020 /opt/rockstor/.venv/bin/python /opt/rockstor/.venv/bin/gunicorn --bind=127.0.0.1:8000 --pid=/run/gunicorn.pid --workers=2 --log-file=/opt/rockstor/var/log/gunicorn.log --pythonpath=/opt/rockstor/src/rockstor --timeout=120 -->
             ├─ 6021 /opt/rockstor/.venv/bin/python /opt/rockstor/.venv/bin/data-collector
             ├─ 6022 /opt/rockstor/.venv/bin/python /opt/rockstor/.venv/bin/django-admin run_huey --workers 2 --worker-type thread --logfile /opt/rockstor/var/log/huey.log
             ├─ 6035 /opt/rockstor/.venv/bin/python /opt/rockstor/.venv/bin/gunicorn --bind=127.0.0.1:8000 --pid=/run/gunicorn.pid --workers=2 --log-file=/opt/rockstor/var/log/gunicorn.log --pythonpath=/opt/rockstor/src/rockstor --timeout=120 -->
             └─ 6036 /opt/rockstor/.venv/bin/python /opt/rockstor/.venv/bin/gunicorn --bind=127.0.0.1:8000 --pid=/run/gunicorn.pid --workers=2 --log-file=/opt/rockstor/var/log/gunicorn.log --pythonpath=/opt/rockstor/src/rockstor --timeout=120 -->

Jun 02 20:33:49 buildvm systemd[1]: Started Rockstor startup script.
Jun 02 20:33:50 buildvm poetry[6013]: 2023-06-02 20:33:50,690 INFO Set uid to user 0 succeeded
Jun 02 20:33:50 buildvm poetry[6013]: 2023-06-02 20:33:50,697 INFO RPC interface 'supervisor' initialized
Jun 02 20:33:50 buildvm poetry[6013]: 2023-06-02 20:33:50,697 INFO supervisord started with pid 6013
Jun 02 20:33:51 buildvm poetry[6013]: 2023-06-02 20:33:51,702 INFO spawned: 'gunicorn' with pid 6020
Jun 02 20:33:51 buildvm poetry[6013]: 2023-06-02 20:33:51,705 INFO spawned: 'data-collector' with pid 6021
Jun 02 20:33:51 buildvm poetry[6013]: 2023-06-02 20:33:51,708 INFO spawned: 'ztask-daemon' with pid 6022
Jun 02 20:33:53 buildvm poetry[6013]: 2023-06-02 20:33:53,711 INFO success: data-collector entered RUNNING state, process has stayed up for > than 2 seconds (startsecs)
Jun 02 20:33:56 buildvm poetry[6013]: 2023-06-02 20:33:56,715 INFO success: gunicorn entered RUNNING state, process has stayed up for > than 5 seconds (startsecs)
Jun 02 20:34:01 buildvm poetry[6013]: 2023-06-02 20:34:01,723 INFO success: ztask-daemon entered RUNNING state, process has stayed up for > than 10 seconds (startsecs)

Not sure I believe that one just yet actually.

@phillxnet
Copy link
Member Author

rockstor-bootstrap.service !!!

buildvm:/opt/rockstor # systemctl start rockstor-bootstrap
buildvm:/opt/rockstor # systemctl status rockstor-bootstrap
● rockstor-bootstrap.service - Rockstor bootstrapping tasks
     Loaded: loaded (/usr/lib/systemd/system/rockstor-bootstrap.service; enabled; vendor preset: enabled)
     Active: active (exited) since Fri 2023-06-02 20:36:30 WEST; 21s ago
    Process: 6068 ExecStart=/opt/rockstor/.venv/bin/bootstrap (code=exited, status=0/SUCCESS)
   Main PID: 6068 (code=exited, status=0/SUCCESS)

Jun 02 20:36:23 buildvm systemd[1]: Starting Rockstor bootstrapping tasks...
Jun 02 20:36:30 buildvm bootstrap[6068]: BTRFS device scan complete
Jun 02 20:36:30 buildvm bootstrap[6068]: Bootstrapping complete
Jun 02 20:36:30 buildvm bootstrap[6068]: Running qgroup cleanup. /opt/rockstor/.venv/bin/qgroup-clean
Jun 02 20:36:30 buildvm bootstrap[6068]: Running qgroup limit maxout. /opt/rockstor/.venv/bin/qgroup-maxout-limit
Jun 02 20:36:30 buildvm systemd[1]: Finished Rockstor bootstrapping tasks.

We must have a myriad of string handling issues still but that is quite encouraging at least. But I've had to take out our prior env hack on run_comand() so will have to circle back around on that one.

Reboot gives same result on services: I better sit down I think.

@phillxnet
Copy link
Member Author

@Hooverdan96 Re:

not changing any of the other package versions

A little more on this, I just trying to minimise the scope of change - at least initially. I.e. changing our underlying language version seemed plenty large enough initially: mixing that with every individual dependency changing seemed like asking for trouble. We already here have a change in the included email module from the language change so lets see where we go initially with just the language change. Almost all of our dependencies are already Python 3.6 compatible (if Poetry is doing it job) so let see.

I'm still getting to grips with the new string handling which will likely keep cropping up. This PR is intended as a proof of concept for just jumping the language version up. If it pans out I'll write it up and pop it in as say "Initial Python 3.6 migration" pull request and we can then, as you say, spin off the various problems found there-after.

@phillxnet
Copy link
Member Author

phillxnet commented Jun 3, 2023

System - Services (TypeError):

[03/Jun/2023 09:41:52] ERROR [storageadmin.util:45] Exception: 'cmp' is an invalid keyword argument for this function
Traceback (most recent call last):
File "/opt/rockstor/src/rockstor/rest_framework_custom/generic_view.py", line 41, in _handle_exception
yield
File "/opt/rockstor/src/rockstor/smart_manager/views/base_service.py", line 94, in get_queryset
sos, cmp=lambda x, y: cmp(x.display_name, y.display_name)
TypeError: 'cmp' is an invalid keyword argument for this function

The previously build-in cmp() has been dropped by Python 3:
https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons

And we have a compound issue here with our use of old style sorted():

builtin.sorted() and list.sort() no longer accept the cmp argument providing a comparison function. Use the key argument instead. N.B. the key and reverse arguments are now “keyword-only”.

"cmp" sorted parameter and buildin function dropped
in Python 3.
@phillxnet
Copy link
Member Author

System - Users (Type Error)

File "/opt/rockstor/src/rockstor/storageadmin/views/ug_helpers.py", line 81, in combined_users
users, cmp=lambda x, y: cmp(x.username.lower(), y.username.lower()) # noqa F821
TypeError: 'cmp' is an invalid keyword argument for this function

"cmp" sorted parameter and builtin function dropped
in Python 3.
Partial fix as only Admin users showing - suspect unrelated
issue.
@phillxnet
Copy link
Member Author

phillxnet commented Jun 3, 2023

System - Group ( Expected object of type bytes or bytearray, got: <class 'str'> )

        Traceback (most recent call last):

File "/opt/rockstor/src/rockstor/rest_framework_custom/generic_view.py", line 41, in _handle_exception
yield
File "/opt/rockstor/src/rockstor/storageadmin/views/group.py", line 40, in get_queryset
return combined_groups()
File "/opt/rockstor/src/rockstor/storageadmin/views/ug_helpers.py", line 85, in combined_groups
sys_groups = get_groups()
File "/opt/rockstor/src/rockstor/system/users.py", line 133, in get_groups
charset = chardet.detect(g.gr_name)
File "/opt/rockstor/.venv/lib/python3.6/site-packages/chardet/init.py", line 37, in detect
'{}'.format(type(byte_str)))
TypeError: Expected object of type bytes or bytearray, got: <class 'str'>

https://pypi.org/project/chardet/

https://github.com/chardet/chardet/releases/tag/5.0.0
has Python 3.6 min and next/latest version:
https://github.com/chardet/chardet/releases/tag/5.1.0
has 3.7 minimum (removed 3.6 support) with 3.10 preferred.

Updated to 5.0.0 while we are here, just in case:
Caveate:

[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
        Traceback (most recent call last):

File "/opt/rockstor/src/rockstor/rest_framework_custom/generic_view.py", line 41, in _handle_exception
yield
File "/opt/rockstor/src/rockstor/storageadmin/views/group.py", line 40, in get_queryset
return combined_groups()
File "/opt/rockstor/src/rockstor/storageadmin/views/ug_helpers.py", line 85, in combined_groups
sys_groups = get_groups()
File "/opt/rockstor/src/rockstor/system/users.py", line 133, in get_groups
charset = chardet.detect(g.gr_name)
File "/opt/rockstor/.venv/lib/python3.6/site-packages/chardet/init.py", line 35, in detect
f"Expected object of type bytes or bytearray, got: {type(byte_str)}"
TypeError: Expected object of type bytes or bytearray, got: <class 'str'>

@phillxnet
Copy link
Member Author

Touching on our own chardet dependency here, with the last comments observed caveat (where upgrading for us may break for PySocks) we could now (post Python 3.6) side-step this depending instead and move to:

charset-normalizer - which was brought in indirectly by Poetry to serve currently certifi

[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= "3""}

https://pypi.org/project/charset-normalizer/

Python >=2.7,<3.5: Unsupported
Python 3.5: charset-normalizer < 2.1
Python 3.6: charset-normalizer < 3.1

@phillxnet
Copy link
Member Author

Turns out we are the only remaining user of chardet so dropping in favour of charset-normalizer which is already used by our requests dependency. Not sure of prior mention of chardet on PySocks.

Replace hard chardet dependency with soft
charset-normalizer also used by requests.
Removes redundant encoding on groupname already
encoded.
@FroggyFlox
Copy link
Member

@Hooverdan96, I believe the removal has already begun. See b56967c, where it has now been removed from the list of dependencies and the code started to be adjusted accordingly.

@Hooverdan96
Copy link
Member

Ah, ok. I thought it would be replaced with charset-normalizer instead, which would then perform the same function. I guess, my "real" question was whether the recognition of a given encoding is really relevant for Rockstor in general ...

@FroggyFlox
Copy link
Member

I thought it would be replaced with charset-normalizer instead, which would then perform the same function.

You are correct; although it doesn't seem to be a drop-in replacement either. I'm not sure about that exactly, so @phillxnet will confirm/correct.

I guess, my "real" question was whether the recognition of a given encoding is really relevant for Rockstor in general ...

This is where I'll show even more my limits. To the best of my knowledge, it is important for those users with different locales and characters that would otherwise not be understood/read properly; that would of course be a big deal for user names, for instance.

@Hooverdan96
Copy link
Member

ah, yes, I think you're right. Obviously, the encoding matter for anything that is entered manually like share names, user/login, etc. Got it.

FroggyFlox and others added 3 commits June 4, 2023 10:08
…_runtime

Move UDEVADM and SHUTDOWN definitions to runtime constants rockstor#2564
…poetry.lock_for_python_3.6

Move passwd to str and use crypt.mksalt() to generate salt rockstor#2564
@phillxnet
Copy link
Member Author

Linking too two now merged (into this working branch) pull requests from @FroggyFlox
phillxnet#2
phillxnet#3

@phillxnet
Copy link
Member Author

Having now intergrated @FroggyFlox changes I'm now following up on more @FroggyFlox exploration into our not haveing any non admin users:
Working on:

[05/Jun/2023 12:39:45] ERROR [system.users:90] must be str, not bytes
Traceback (most recent call last):
  File "/opt/rockstor/src/rockstor/system/users.py", line 85, in get_users
    user_data += p.stdout.read()
TypeError: must be str, not bytes

@phillxnet
Copy link
Member Author

Side channel chat suggests we move to subprocess.run() in the system.users.get_users() due to changes in open and our new python 3 base.

phillxnet added 2 commits June 5, 2023 15:22
Move to more modern - time limited subprocess.run().
@phillxnet
Copy link
Member Author

Non admin users are now found as expected.

Remaining Dashboard issues:

  • Network widget non-functional

@phillxnet
Copy link
Member Author

Planned initial P3 fix is configuring Samba results in:

[05/Jun/2023 15:45:35] ERROR [storageadmin.util:45] Exception: Samba could not be configured. Try again. Exception: 'dict' object has no attribute 'iteritems'
Traceback (most recent call last):
  File "/opt/rockstor/src/rockstor/smart_manager/views/samba_service.py", line 99, in post
    update_global_config(global_config, adconfig)
  File "/opt/rockstor/src/rockstor/system/samba.py", line 132, in update_global_config
    for key, value in smb_default_options.iteritems():
AttributeError: 'dict' object has no attribute 'iteritems'

@FroggyFlox
Copy link
Member

FroggyFlox commented Jun 5, 2023

Remaining Dashboard issues:

* [ ]  Network widget non-functional

I may have figured that one out:
image

[@phillxnet EDIT] Proposed for dedicated issue post "Preliminary python 3.6 port".

@phillxnet
Copy link
Member Author

phillxnet commented Jun 5, 2023

Initial working samba config via:

d.iteritems() to iter(d.items())

https://peps.python.org/pep-0469/

@phillxnet
Copy link
Member Author

phillxnet commented Jun 5, 2023

We have working Rock-ons system: at least with no involved shares:
Python3-rock-on-install-no-shares

[EDIT] and with a single share (rights to use):
Python3-working-rock-on_with_share

@phillxnet
Copy link
Member Author

scheduled snapshot configurable and ends up running but Web_UI has no knowledge of these runs:

Jun 05 19:30:01 buildvm CRON[22121]: (root) CMD (/opt/rockstor/.venv/bin/st-snapshot 1 \*-*-*-*-*-*)
Jun 05 19:30:02 buildvm CRON[22119]: (root) CMDEND (/opt/rockstor/.venv/bin/st-snapshot 1 \*-*-*-*-*-*)
...
Jun 05 19:35:01 buildvm CRON[23870]: (root) CMD (/opt/rockstor/.venv/bin/st-snapshot 1 \*-*-*-*-*-*)
Jun 05 19:35:01 buildvm CRON[23869]: (root) CMDEND (/opt/rockstor/.venv/bin/st-snapshot 1 \*-*-*-*-*-*)

no-sched-snap-feedback

@phillxnet
Copy link
Member Author

phillxnet commented Jun 5, 2023

System - Logs manager -

Logs Reader

Non functional: i.e. no tail type output.

Logs Downloader :: compressed packet builder

Looks to work as intended with working download link generated. Tested for single and multiple selections of requsted logs.

[EDIT] Proposed for dedicated issue, post Preliminary python 3.6 port.

@phillxnet phillxnet changed the title Update pyproject.toml and poetry.lock for python 3.6 #2564 Preliminary python 3.6 port #2564 Jun 6, 2023
@phillxnet
Copy link
Member Author

phillxnet commented Jun 6, 2023

Confirming @FroggyFlox side-channel chat config-backup issue re port:

System - Config backups -

[06/Jun/2023 11:54:56] ERROR [storageadmin.util:45] Exception: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
Traceback (most recent call last):
  File "/opt/rockstor/src/rockstor/rest_framework_custom/generic_view.py", line 41, in _handle_exception
    yield
  File "/opt/rockstor/src/rockstor/storageadmin/views/config_backup.py", line 662, in post
    cbo = backup_config()
  File "/opt/rockstor/src/rockstor/system/config_backup.py", line 76, in backup_config
    cbo = ConfigBackup(filename=gz_name, md5sum=md5sum(fp), size=size)
  File "/opt/rockstor/src/rockstor/system/osi.py", line 1444, in md5sum
    for l in tfo.readlines():
  File "/usr/lib64/python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

Proposed for dedicated issue. [EDIT] post Preliminary python 3.6 port.

Noting a PyCharm editor warning on: src/rockstor/storageadmin/models/config_backup.py
return os.path.join(self.cb_dir(), self.filename)
"Unexpected Types"

phillxnet added 2 commits June 6, 2023 12:16
Includes prior TODO re ascii to utf-8 on SMART
custom options.
Custom options autodev related byte assertion.
@phillxnet
Copy link
Member Author

As this draft PR was a proof of concept and has got us to a mostly working Python 3.6 base it is proposed that I now move what we have to a non draft status after some squashing etc. We can then spin off, in testing dedicated issues. Most of which are likely type related.

We also have the following test results to approach with likely a large amount of overlap with our proposed spin-off issues here:

Ran 252 tests in 20.288s

FAILED (failures=12, errors=6)

@phillxnet
Copy link
Member Author

Closing as superseded by:
#2567

@phillxnet phillxnet closed this Jun 6, 2023
@phillxnet phillxnet deleted the 2564_Update_pyproject.toml_and_poetry.lock_for_python_3.6 branch June 6, 2023 15:12
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 this pull request may close these issues.

3 participants