better handling of pip requirements

- install packages needed for install when import failed
- all other packages (currently for frappy) are to be installed
  in user space
This commit is contained in:
2025-11-26 15:58:27 +01:00
parent 42a6a2e319
commit c7e725c13a
2 changed files with 39 additions and 57 deletions
+39 -54
View File
@@ -16,36 +16,33 @@ import re
import types
import socket
import tempfile
import importlib
from pathlib import Path
from subprocess import Popen, PIPE
from ipaddress import IPv4Interface
from os.path import getmtime, exists
from gitea import change_to_gitea
def exit():
print('please restart ./install.py again')
def exit(text='please restart ./install.py again'):
if text:
print(text)
sys.exit()
try:
import serial
except ImportError:
if 'yes'.startswith(input('install pyserial? [y]')):
from ipaddress import IPv4Interface
from utils import BoxInfo, check_service, unix_cmd, change_firewall, UndefinedConfigFile, convert_cfg
except ImportError as e:
pkgs = 'pyserial', 'ipaddress', 'netifaces'
if 'yes'.startswith(input(f'install {", ".join(pkgs)}? [y]')):
os.system('sudo apt update')
os.system('sudo apt install python3-pip')
os.system('sudo pip3 install --break-system-packages pyserial')
serial = None
for pkg in pkgs:
os.system(f'sudo pip3 install --break-system-packages {pkg}')
exit()
else:
exit('')
try:
from utils import BoxInfo, check_service, unix_cmd, change_firewall, UndefinedConfigFile, convert_cfg
except ImportError:
if 'yes'.startswith(input('install netifaces? [y]')):
os.system('sudo pip3 install --break-system-packages netifaces')
serial = None
if serial is None:
exit()
main_ports = {22} # ssh
@@ -183,11 +180,7 @@ ExecStart = /usr/bin/python /home/l_samenv/boxweb/flaskserver.py {page} {port}
WantedBy = default.target
"""
pip_requirements = {
'root': {},
'l_samenv': {},
}
pip_requirements = {}
box = BoxInfo()
box.hostname_changed = False
@@ -216,12 +209,11 @@ def do_copy(src, dst):
def frappy(cfg=None, port=None, requirements='', **kwds):
if not cfg:
return False, None
req = pip_requirements['l_samenv']
main_ports.add(int(port or 10767))
if requirements:
req[cfg] = '\n'.join(requirements.split(','))
pip_requirements[cfg] = '\n'.join(requirements.split(','))
with open('/home/l_samenv/frappy/requirements.txt') as f:
req['frappy main'] = f.read()
pip_requirements['frappy main'] = f.read()
return False, FRAPPY_SERVICE
@@ -236,11 +228,6 @@ def router(**opts):
router_ports.update((1110, 1111, 1112))
if not opts:
return True, None
try:
with open(TOOLS / 'requirements.txt') as f:
pip_requirements['root']['tools'] = f.read()
except FileNotFoundError:
pass
return True, ROUTER_SERVICE
@@ -251,7 +238,7 @@ def display_update(cfg):
if write_when_new(STARTUP_TEXT, text):
print('change startup text')
if doit:
os.rename(STARTUP_TEXT, STARTUP_TEXT + '.todo')
os.rename(STARTUP_TEXT, str(STARTUP_TEXT) + '.todo')
return True
return False
@@ -263,29 +250,21 @@ def display(**opts):
def pip():
for user, requirements in pip_requirements.items():
if not requirements:
continue
if user == 'root':
tmpname = '/root/pip_requirements.tmp'
pipcmd = ['sudo pip3 install -r', tmpname]
else:
tmpname = f'/home/{user}/pip_requirements.tmp'
pipcmd = ['pip3 install --user --break-system-packages -r', tmpname]
filename = tmpname.replace('.tmp', '.txt')
content = ''.join('# --- for %s ---\n%s\n' % kv for kv in requirements.items())
if content:
print(user, filename)
if write_when_new(filename, content, user=='root'):
if doit:
unix_cmd('mv', filename, tmpname, sudo=True)
if os.system(' '.join(pipcmd)) == 0:
unix_cmd('mv', tmpname, filename, sudo=True)
else:
unix_cmd('rm', tmpname, sudo=True)
filename = TOOLS.parent / 'pip_requirements.txt'
tmpname = TOOLS.parent / 'pip_requirements.tmp'
pipcmd = f'pip3 install --user --break-system-packages -r {tmpname}'
content = ''.join('# --- for %s ---\n%s\n' % kv for kv in pip_requirements.items())
if content:
if write_when_new(filename, content, as_root=False):
if doit:
unix_cmd('mv', filename, tmpname, sudo=False)
if os.system(pipcmd) == 0:
unix_cmd('mv', tmpname, filename, sudo=False)
else:
print(' '.join(pipcmd))
show.dirty = True
unix_cmd('rm', tmpname, sudo=False)
else:
print(pipcmd)
show.dirty = True
def boxweb(port=8080, page=None):
@@ -319,6 +298,7 @@ def write_when_new(filename, content, as_root=False, ignore_reduction=False):
content += '\n'
lines = content.split('\n')
try:
os.makedirs(Path(filename).parent, exist_ok=True)
for parent in reversed(Path(filename).absolute().parents):
unix_cmd('chmod', 'o+rx', parent, sudo=True)
with open(filename) as fil:
@@ -707,8 +687,12 @@ def handle_config():
continue
else:
if not enabled:
if not doit:
print(service, 'is not enabled')
to_start[service] = 'enable', as_root
elif not active:
if not doit:
print(service, 'is not active')
to_start[service] = 'restart', as_root
if as_root:
systemdir = Path('/etc/systemd/system')
@@ -724,7 +708,8 @@ def handle_config():
show.dirty = True
if 'dialout' not in unix_cmd('id l_samenv'):
do_cmd('usermod -a -G dialout l_samenv')
pip()
if pip_requirements:
pip()
for as_root in reload_systemd:
if as_root:
do_cmd('systemctl daemon-reload', sudo=True)
-3
View File
@@ -1,3 +0,0 @@
pyserial
ipaddress
netifaces