creole/creole/fonctionseole.py

281 lines
8.9 KiB
Python
Raw Normal View History

2019-11-23 08:17:35 +01:00
# -*- coding: utf-8 -*-
"""
fonctions communes Creole
"""
import os, time, re
from os.path import join, isfile
from pyeole.process import system_out, system_code
from pyeole.ansiprint import print_orange
from pyeole.log import init_logging
from pyeole.pkg import EolePkg
from pyeole.encode import normalize
from .config import LOCALKERNEL_FILE, REBOOT_FILE
from .i18n import _
#si creole client n'est pas démarré
global PkgManager
PkgManager = None
######################
# Gestion des noyaux #
######################
def split_version(version):
"""
return version as list splitting subnumbers
:param version: version number string
:type version: string
"""
version_splitted = re.split('[-\.]', version)
version_splitted = map(int, version_splitted)
return version_splitted
def get_version_filtered_pkgs(prefix='linux-image'):
"""
return installed packages list ordered by version number
"""
vers_pkg_re = r"{0}-(?P<vers>[0-9]+(?P<upstr_vers>\.[0-9]+)*(-(?P<pkg_vers>[0-9]+))?)".format(prefix)
vers_pkg_re = re.compile(vers_pkg_re)
installed_pkgs = get_installed_kernel(prefix)
vers_pkgs = [(pkg, split_version(vers_pkg_re.search(pkg).group('vers')))
for pkg in installed_pkgs
if vers_pkg_re.search(pkg)]
vers_pkgs = [pkg[0] for pkg in sorted(vers_pkgs, key=lambda p: p[1])]
return vers_pkgs
def get_custom_kernel():
"""
renvoie le nom du noyau personnalisé
ou None
"""
if isfile(LOCALKERNEL_FILE):
# noyau personnalisé détecté
kernel_file = LOCALKERNEL_FILE
return file(kernel_file).read().strip()
def get_wanted_kernel():
"""
renvoie le nom du noyau sur lequel on veut tourner
"""
custom_kernel = get_custom_kernel()
if custom_kernel:
ret = custom_kernel
else:
kernel_images = get_version_filtered_pkgs()
# Get last kernel version
last_ver = kernel_images[-1].split('-')
if len(last_ver) >= 4:
last_ver = "{0}-{1}-{2}".format(*last_ver[2:5])
elif len(last_ver) == 3:
last_ver = "{0}".format(last_ver[-1])
ret = last_ver
return ret
def get_current_kernel():
"""
renvoie le nom du noyau sur lequel on tourne
"""
version = system_out(['uname', '-r'])[1].strip()
return version
def get_installed_kernel(kernel):
"""
renvoie la liste des noyaux installés
correspondant à celui demandé
"""
cmd = """COLUMNS=180 dpkg -l 2>/dev/null | awk -F " " '/^(i|h)i.*%s/ {print $2}'""" % kernel
return os.popen(cmd).read().splitlines()
def get_package_depends(pkg):
"""
Renvois les dépendances d'un paquet
"""
try:
global PkgManager
if PkgManager is None:
PkgManager = EolePkg('apt')
res = PkgManager.get_depends(pkg)
return res
except:
return []
def controle_kernel(force_grub=True):
"""
Vérifie si on est sur le noyau désiré
Renvoie True si un reboot est nécessaire
"""
need_boot = False
if isfile(REBOOT_FILE):
# i.e. /var/run/reboot-required
need_boot = True
wanted_kernel = get_wanted_kernel()
# on utilise le noyau spécifié
if wanted_kernel != get_current_kernel():
need_boot = True
if force_grub:
# Update grub does the job since eole-kernel-version 2.3-eole37~2
print _(u"Updating Grub configuration")
# ajout de LVM_SUPPRESS_FD_WARNINGS pour #10761
system_code("/usr/sbin/update-grub2", env={'LVM_SUPPRESS_FD_WARNINGS': '1', "LC_ALL": 'fr_FR.UTF-8'})
# reboot nécessaire ?
return need_boot
def regen_initrd():
"""
vérifie la présence de l'initrd
"""
noyau = get_wanted_kernel()
if not isfile("/boot/initrd.img-%s" % noyau):
print _(u"Initramfs missing, generating :")
cmd = ["/usr/sbin/update-initramfs", '-c', '-k', noyau]
system_code(cmd)
def get_kernel_to_remove():
"""
Obtenir la liste des noyaux a supprimer. Tous les noyaux sauf :
- le noyau courant
- les deux noyaux les plus récents
- l'éventuel noyau personnalisé
"""
# tous les noyaux installés
installed_kernels = get_version_filtered_pkgs()
# les deux noyaux les plus récents
to_keep = installed_kernels[-2:]
# tous les headers installés
installed_kernels.extend(get_version_filtered_pkgs(prefix='linux-headers'))
# le noyau courant
to_keep.append('linux-image-{0}'.format(get_current_kernel()))
# l'éventuel noyau personnalisé
custom_kernel = get_custom_kernel()
if custom_kernel:
to_keep.append('linux-image-{0}'.format(custom_kernel))
# les headers correspondants aux noyaux à conserver
headers_to_keep = [k.replace('image', 'headers') for k in to_keep]
headers_to_keep.extend([h.replace('-generic', '') for h in headers_to_keep])
to_keep.extend(headers_to_keep)
# on fait la différence
to_remove = list(set(installed_kernels) - set(to_keep))
return to_remove
def purge_rc():
"""
Purge des paquets "rc"
"""
cmd = """COLUMNS=180 dpkg -l|grep "^rc"|awk -F " " '{print $2}'"""
rcs = os.popen(cmd).read().splitlines()
for pak in rcs:
os.system("dpkg -P %s >/dev/null" % pak)
def log(etat, msg, type_proc, console=True):
"""
effectue un log local et éventuellement sur zephir
"""
msg = normalize(msg)
type_proc = normalize(type_proc)
display = False
log_func = 'info'
if etat == "ERR":
if console:
# affichage sur la console
display = True
log_func = 'error'
try:
z_logger = init_logging(name=u'zephir', syslog=True, level=u'info', console=display)
except ValueError, err:
z_logger = init_logging(name=u'zephir', level=u'info', console=True)
z_logger.warn(_(u"Syslog logging is not working properly: {0}".format(err)))
z_logger.warn(_(u"You may need to start/restart systemd-journald"))
getattr(z_logger, log_func)("%s => %s : %s " % (type_proc, etat, msg))
def zephir(etat, msg, type_proc, console=True):
""" gestion des messages Zephir """
etat_zeph = None
if etat.upper().startswith("INIT"):
etat_zeph = -1
elif etat.upper().startswith("FIN"):
etat_zeph = 0
elif etat.upper().startswith('ERR'):
etat_zeph = 1
elif etat.upper().startswith('MSG'):
etat_zeph = -2
# log local si msg ou erreur
if (len(msg) > 0) or (etat.upper() == "ERR"):
log(etat, msg, type_proc, console)
# log sur zephir si disponible
if etat_zeph is not None:
try:
# si serveur enregistré, on envoie un log à Zéphir
from zephir.zephir_conf.zephir_conf import id_serveur
except:
pass
else:
from zephir.lib_zephir import log as zlog
zlog(type_proc, etat_zeph, msg, str(time.ctime()))
def init_proc(type_proc):
"""
initialisation d'une procédure (log démarrage + bcage éventuel)
"""
if verify_lock(type_proc):
return True
else:
return False
#def end_proc(etat,msg,type_proc):
# """
# loggue la fin d'une procédure
# """
# log(etat,msg,type_proc )
def verify_lock(name):
"""
vérifie le bloquage ou non d'une procédure
"""
LOCK_FILE = "/usr/share/zephir/zephir_locks"
if name == "":
return True
from zephir.lib_zephir import zephir_path
try:
from zephir.lib_zephir import config, zephir, convert
locks = convert(zephir.serveurs.get_locks(config.id_serveur))
if locks[0] == 0:
# erreur sur zephir, on ignore cette phase
raise Exception
locks = [lock[0] for lock in locks[1]]
except Exception, mess:
# pas de message d'erreur si le serveur n'est pas enregistré
zephir_error = False
if isfile(join(zephir_path, "zephir_conf", "zephir_conf.py")):
# on ne bloque pas si l'appel à zephir échoue
print ""
print_orange(_(u"Checking permissions on Zéphir for {0} impossible.").format(name))
print_orange(_(u"Error message: {0}").format(mess))
zephir_error = True
# on regarde le denier état
if os.path.exists(LOCK_FILE):
if zephir_error:
print_orange(_(u"Using stored parameters"))
file_lock = file(LOCK_FILE)
locks = file_lock.read().split('\n')
file_lock.close()
# on bloque si interdit
if name in locks:
return False
else:
# mise en place du fichier de droits
content = "\n".join(locks)
try:
file_lock = file(LOCK_FILE, "w")
file_lock.write(content)
file_lock.close()
except:
print _(u"Updating {0} impossible (insufficient rights).").format(LOCK_FILE)
# retour du code
if name in locks:
return False
return True