# -*- coding: utf-8 -*- """Apply configuration of EOLE servers. """ import os import argparse import time import shutil from glob import glob import spwd import getpass from itertools import count from pyeole.log import getLogger from pyeole.log import init_logging from pyeole.log import set_formatter from pyeole.log import set_filters from pyeole import scriptargs from pyeole.lock import acquire, release from pyeole import process from pyeole.schedule import display_schedules, apply_schedules from pyeole import ihm from pyeole.pkg import report, EolePkg, _configure_sources_mirror, _MIRROR_DIST from pyeole.pkg import PackageNotFoundError, RepositoryError, AptProxyError, AptCacherError from pyeole.service import manage_service, unmanaged_service, manage_services, \ ServiceError from pyeole.encode import normalize from pyeole.diagnose.diagnose import MAJ_SUCCES_LOCK from .error import FileNotFound, LockError, UnlockError from .error import UserExit, UserExitError from .error import VirtError from .client import CreoleClient, CreoleClientError, NotFoundError import fonctionseole, template, cert from .eosfunc import is_instanciate from .config import configeol, INSTANCE_LOCKFILE, UPGRADE_LOCKFILE, \ container_instance_lockfile, gen_conteneurs_needed, VIRTROOT, charset from .containers import is_lxc_enabled, is_lxc_running, is_lxc_started, \ generate_lxc_container, create_mount_point, lxc_need_restart from .error import NetworkConfigError from pyeole.i18n import i18n _ = i18n('creole') try: from zephir.lib_zephir import lock, unlock zephir_libs = True except Exception: zephir_libs = False client = CreoleClient() global PKGMGR PKGMGR = None error_msg_documentation = _(u"""For more informations, read section 'Mise en œuvre des modules EOLE' in module documentation or common documentation.""") def load_pkgmgr(): global PKGMGR if PKGMGR is None: cache() PKGMGR = EolePkg('apt', container_mode=CACHE['is_lxc_enabled']) PKGMGR.pkgmgr.groups = CACHE PKGMGR.pkgmgr._load_apt_cache() eoles = [] for eole in client.get_creole(u'serveur_maj'): eoles.append('http://{0}/eole/'.format(eole)) ubuntus = [] for ubuntu in client.get_creole(u'ubuntu_update_mirrors'): ubuntus.append('http://{0}/ubuntu/'.format(ubuntu)) envoles = [] try: for envole in client.get_creole(u'envole_update_mirrors'): envoles.append('http://{0}/envole/'.format(envole)) except NotFoundError: pass for cache_ in PKGMGR.pkgmgr.cache._list.list: if cache_.uri in eoles: PKGMGR.pkgmgr._test_mirror(cache_.uri, _MIRROR_DIST['EOLE']) eoles = [] if cache_.uri in ubuntus: PKGMGR.pkgmgr._test_mirror(cache_.uri, _MIRROR_DIST['Ubuntu']) ubuntus = [] if cache_.uri in envoles: PKGMGR.pkgmgr._test_mirror(cache_.uri, _MIRROR_DIST['Envole']) envoles = [] fonctionseole.PkgManager = PKGMGR _LOGFILENAME = '/var/log/reconfigure.log' # Command line options class Option: """Manage commande line options with defaults """ def __init__(self): self.parser = argparse.ArgumentParser( description=_(u"Applying EOLE configuration."), parents=[scriptargs.container(), scriptargs.logging(level='info')]) self.parser.add_argument('-i', '--interactive', action='store_true', help=_(u"leave process in interactive mode")) self.parser.add_argument('-f', '--force', action='store_true', help=_(u"override Zéphir lock")) self.parser.add_argument('-a', '--auto', action='store_true', help=_(u"automatic reboot if necessary")) self.__opts = self.parser.parse_args([]) def update_from_cmdline(self, force_args=None, force_options=None): """Parse command line """ self.__opts = self.parser.parse_args(force_args) if self.__opts.verbose: self.__opts.log_level = 'info' if self.__opts.debug: self.__opts.log_level = 'debug' if force_options is not None: for key, value in force_options.items(): setattr(self.__opts, key, value) self.__dict__.update(self.__opts.__dict__) def __getattr__(self, name): if name in ['__opts', 'update_from_cmdline']: return self.__dict__[name] else: return getattr(self.__opts, name) options = Option() # To use log from every functions log = getLogger(__name__) # Same name for instance and reconfigure LOCK_NAME = u'reconfigure' # Run scripts in directories RUNPARTS_PATH = u'/usr/share/eole' RUNPARTS_CMD = u'/bin/run-parts --exit-on-error -v {directory} --arg {compat} 2>&1' # Compatibility COMPAT_NAME = u'reconfigure' #def parse_cmdline(): # """Parse command line # """ # descr = u"Application de la configuration EOLE" # parser = argparse.ArgumentParser(description=descr, # parents=[scriptargs.container(), # scriptargs.logging(level='info')]) # parser.add_argument('-i', '--interactive', action='store_true', # help=u"lancer le processus en mode interactif") # parser.add_argument('-f', '--force', action='store_true', # help=u"force l'action même s'il existe des verrous") # parser.add_argument('-a', '--auto', action='store_true', # help=u"redémarrage automatique si nécessaire") # # opts = parser.parse_args() # if opts.verbose: # opts.log_level = 'info' # if opts.debug: # opts.log_level = 'debug' # return opts def copyDirectoryContent(src, dst): for fic in os.listdir(src): # Skip links or we ovewrite existing certificates if os.path.islink(os.path.join(src, fic)): continue try: shutil.copy2(os.path.join(src, fic), dst) except shutil.Error, err: # ignore if files already exists pass def user_exit(*args, **kwargs): """ sortie utilisateur "propre" """ log.warn(_(u'! Abandoning configuration !')) log.warn(_(u'System may be in an incoherent state.\n\n')) raise UserExitError() def unlock_actions(need_lock=True): if zephir_libs: #FIXME: lock de Zephir ! unlock('actions') try: release(LOCK_NAME, level='system') except Exception, err: # FIXME: move lock exception to pyeole.lock #7400 if need_lock: raise UnlockError(str(err)) def lock_actions(): try: acquire(LOCK_NAME, level="system") except Exception, err: # FIXME: move lock exception to pyeole.lock #7400 raise LockError(str(err)) if zephir_libs: #FIXME: lock de Zephir ! lock('actions') def reset_compat_name(): """ Réinitialise le nom de la procédure en cours en fonction de l'environnement """ global COMPAT_NAME if options.interactive: COMPAT_NAME = u'instance' else: COMPAT_NAME = u'reconfigure' def run_parts(directory): """Run scripts in a directory @param directory: name of a directory @type directory: C{str} """ dirpath = os.path.join(RUNPARTS_PATH, directory) if os.path.isdir(dirpath): ihm.print_title(_(u'Running scripts {0}').format(directory)) code = os.system(RUNPARTS_CMD.format(directory=dirpath, compat=COMPAT_NAME)) if code != 0: raise Exception(_(u'Error {0}').format(directory)) def restart_creoled(): """ Restart creoled service and verify if the client is OK """ unmanaged_service(u'restart', u'creoled', u'service', display='console') try: client.get_creole(u'eole_version') except CreoleClientError: msg = _(u"Please check creoled's log (/var/log/rsyslog/local/creoled/creoled.info.log)\nand restart service with command 'service creoled start'") raise CreoleClientError(msg) def prepare(need_lock=True): """Sanity checks. """ global RUNPARTS_CMD # Clean exit if need_lock: ihm.catch_signal(user_exit) lock_actions() if options.container != None: RUNPARTS_CMD += u" --regex '^[09][09]-{0}$'".format(options.container) ihm.print_title(_(u"Preparation for {0}").format(COMPAT_NAME)) if not os.path.isfile(configeol): print _(u"Server is not configured.") print print error_msg_documentation print raise FileNotFound(_(u'Missing file {0}.').format(configeol)) display_info = False if not options.interactive and (is_instanciate() == 'non' or os.path.isfile(UPGRADE_LOCKFILE)): ihm.print_red(_(u"Server must be instantiated before any reconfiguration can occur.")) display_info = True if options.interactive and is_instanciate() == 'oui' and \ not os.path.isfile(UPGRADE_LOCKFILE) and \ not os.path.isfile(container_instance_lockfile): ihm.print_red(_(u"Server already instantiated.")) print print _(u"To modify configuration parameter (e.g. IP address), use:") print _(u"'gen_config'") print _(u"then 'reconfigure' to apply changes.") display_info = True if os.path.isfile(container_instance_lockfile) and not options.interactive: raise Exception(_('you have run gen_conteneurs, please use instance instead of reconfigure')) if os.path.isfile(gen_conteneurs_needed): raise Exception(_('You have to run gen_conteneurs before instance')) if display_info: print print error_msg_documentation print if not options.interactive: raise Exception(_(u"First instantiate server.")) else: if ihm.prompt_boolean(_(u"Proceeding with instantiation ?"), interactive=options.interactive, default=False) is False: raise UserExit() else: fonctionseole.zephir("MSG", "Instance forcée par l'utilisateur", COMPAT_NAME.upper()) # redémarrage du service creoled restart_creoled() if fonctionseole.init_proc(COMPAT_NAME.upper()) == False and not options.force: log.warn(_(u"This process is blocked, contact Zéphir administrator.")) if ihm.prompt_boolean(_(u"Force execution?"), interactive=options.interactive, default=False) is False: if not options.interactive: log.warn(_(u"Use -f option if you want to force execution")) raise UserExitError() else: fonctionseole.zephir("MSG", "Instance forcée par l'utilisateur", COMPAT_NAME.upper()) def valid_mandatory(need_lock): try: client.valid_mandatory() except Exception, err: log.warn(_('Configuration validation problem, please check server configuration.')) print print error_msg_documentation print unlock_actions(need_lock) raise ValueError(str(err)) def _start_containers(): """ Try to start containers and make sure they are started """ cache() for group_name in CACHE['groups_container']: group = CACHE['group_infos'][group_name] create_mount_point(group) if os.access('/usr/share/eole/preservice/00-lxc-net', os.X_OK): log.debug("Override lxc-net systemd script") process.system_code(['/usr/share/eole/preservice/00-lxc-net']) unmanaged_service(u'start', u'lxc-net', u'systemd', display='console', ctx=CACHE['group_infos']['root']) try: unmanaged_service(u'status', u'lxc', u'systemd') except ServiceError: unmanaged_service(u'start', u'lxc', u'systemd', display='console', ctx=CACHE['group_infos']['root']) #if lxc not started, do not wait for it #(we already waiting for it in systemd service) #if started, waiting for ssh access max_try = 10 for count in range(max_try): s_code, s_out, s_err = process.system_out(['lxc-ls', '--stopped']) stopped = s_out.split() f_code, f_out, f_err = process.system_out(['lxc-ls', '--frozen']) frozen = f_out.split() if stopped or frozen: not_running = stopped + frozen else: # Everything is started by LXC # Are they reachable by SSH? not_running = [] for group_name in CACHE['groups_container']: group_infos = CACHE['group_infos'][group_name] if not is_lxc_running(group_infos): not_running.append(group_name) log.debug('Waiting 1 second for SSH access') time.sleep(1) if not not_running: break if stopped: for cont in stopped: log.debug('Manual start of stopped container “{0}”'.format(cont)) process.system_out(['lxc-start', '--name', cont, '--daemon', '-o', '/var/log/lxc-{0}.log'.format(cont)]) if frozen: for cont in frozen: log.debug('Manual unfreeze of frozen container “{0}”'.format(cont)) process.system_out(['lxc-unfreeze', '--name', cont, '-o', '/var/log/lxc-{0}.log'.format(cont)]) if not_running: waiting_for = ', '.join(not_running) msg = _(u'Unable to start LXC container : {0}', u'Unable to start LXC containers : {0}', len(not_running)) raise VirtError(msg.format(waiting_for)) def containers(minimal=False, log_=None): """Generate containers """ if log_ is None: log_ = log VAR_LXC='/var/lib/lxc' OPT_LXC='/opt/lxc' cache() if not CACHE['is_lxc_enabled']: log.debug(_(u'Container mode is disabled.')) return True if not options.interactive: for group in CACHE['groups_container']: if not os.path.isdir(os.path.join(VIRTROOT, group)): raise Exception(_(u'container {0} does not already exist, please use gen_conteneurs to create this container').format(group)) else: # make /var/lib/lxc -> /opt/lxc if os.path.isdir(VAR_LXC) and not os.path.exists(OPT_LXC): ihm.print_title(_(u"Setting up {0}").format(OPT_LXC)) unmanaged_service(u'stop', u'lxc', u'systemd', display='console') unmanaged_service(u'stop', u'lxc-net', u'systemd', display='console') shutil.move(VAR_LXC, OPT_LXC) os.symlink(OPT_LXC, VAR_LXC) #first instance should be in minimal mode minimal = True ihm.print_title(_(u'Generating containers')) engine = template.CreoleTemplateEngine() rootctx = CACHE['group_infos']['root'] if minimal: # inject var _minimal_mode in creole's vars that can be used in template engine.creole_variables_dict['_minimal_mode'] = True engine.instance_file(u'/etc/ssh/ssh_config', ctx=rootctx) engine.instance_file(u'/etc/lxc/default.conf', ctx=rootctx) engine.instance_file(u'/etc/dnsmasq.d/lxc', ctx=rootctx) engine.instance_file(u'/etc/default/lxc-net', ctx=rootctx) engine.instance_file(u'/etc/apt/apt.conf.d/02eoleproxy', ctx=rootctx) if CACHE['module_instancie'] == 'oui': engine.instance_file(u'/etc/resolv.conf', ctx=rootctx) load_pkgmgr() PKGMGR.pkgmgr._prepare_cache() for group in CACHE['groups_container']: generate_lxc_container(group) groupctx = CACHE['group_infos'][group] if minimal: engine.instance_file(u'../fstab', container=group, ctx=groupctx) engine.instance_file(u'../config', container=group, ctx=groupctx) engine.instance_file(u'../devices.hook', container=group, ctx=groupctx) engine.instance_file(u'/etc/network/interfaces', container=group, ctx=groupctx) engine.instance_file(u'/etc/apt/apt.conf.d/02eoleproxy', container=group, ctx=groupctx) engine.instance_file(u'/etc/ssh/sshd_config', container=group, ctx=groupctx) if CACHE['module_instancie'] == 'oui': container_path = os.path.join(groupctx['path'], 'etc/resolv.conf') if os.path.islink(container_path): os.remove(container_path) engine.instance_file(u'/etc/resolv.conf', container=group, ctx=groupctx) PKGMGR.pkgmgr._umount_cdrom() ihm.print_title(_(u'Starting containers')) _start_containers() def remove_packages(): """ Remove packages listed in /usr/share/eole/remove.d/ files param: repo: EoleApt Object """ torm_conf = glob(u'/usr/share/eole/remove.d/*.conf') pkg_list = [] for config in torm_conf: try: f_h = open(config, 'r') for line in f_h.readlines(): pkg_list.append(line.strip('\n')) f_h.close() except IOError, err: log.error(_(u'Can not read file {0}: {1}').format(config, err)) try: load_pkgmgr() except (RepositoryError, AptProxyError, AptCacherError), err: pass kernels = fonctionseole.get_kernel_to_remove() if kernels: ihm.print_line(_(u"Removing old linux kernels and associate headers.")) pkg_list.extend(kernels) if pkg_list != []: try: PKGMGR.remove(packages=pkg_list) except (PackageNotFoundError, SystemError), err: msg = _(u'Unable to remove some packages: {0}') log.warn(msg.format(err)) log.warn(_(u"These packages will be removed next 'reconfigure'")) CACHE = {} def cache(): global CACHE if not 'groups' in CACHE: CACHE['groups'] = client.get_groups() CACHE['groups_container'] = [] for group in CACHE['groups']: if group not in ['root', 'all']: CACHE['groups_container'].append(group) CACHE['group_infos'] = {} for group_name in CACHE['groups']: group_infos = client.get_group_infos(group_name) CACHE['group_infos'][group_name] = group_infos CACHE['is_lxc_enabled'] = is_lxc_enabled() CACHE['module_instancie'] = client.get_creole('module_instancie') def install_packages(silent=False): """Install package for each container group """ load_pkgmgr() cache() header = _(u'Checking Packages for container') for group_name, group_infos in CACHE['group_infos'].items(): package_names = [pkg[u'name'] for pkg in group_infos[u'packages']] if package_names != []: msg = header + ' {0}: {1}'.format(group_name, ' '.join(package_names)) ihm.print_line(msg) PKGMGR.install(packages=package_names, silent=silent, container=group_infos[u'name']) def packages(): """Manage packages """ ihm.print_title(_(u'Managing packages')) log.info(_(u' Removing packages')) ihm.print_line(_(u'Removing packages')) remove_packages() log.info(_(u' Installing packages')) ihm.print_line(_(u'Installing packages')) install_packages() def templates(): """Run pretemplate scripts and manage templates """ ihm.print_title(_(u'Generating configuration files')) log.info(_(u'Generating configuration files')) cache() try: tmpl = template.CreoleTemplateEngine() tmpl.instance_files(container=options.container, containers_ctx=CACHE['group_infos'].values()) except Exception, err: if options.debug: log.debug(err, exc_info=True) else: log.error(err) raise err def services(action, display_title=True, try_restart_lxc=True): """Manage services """ cache() exclude = None if action == u'stop': if display_title: ihm.print_title(_(u"Stopping services")) exclude = (('root', 'networking'),) elif action == u'start': if display_title: ihm.print_title(_(u"Starting services")) # ne pas demarrer le service certbot, c'est un service oneshot # et pyeole.service n'a pas l'air d'aimer ... #22092 exclude = (('root', 'networking'), ('root', 'certbot')) ctx = CACHE['group_infos']['root'] manage_services(action, u'networking', display='console', containers_ctx=[ctx]) if try_restart_lxc and CACHE['is_lxc_enabled']: if lxc_need_restart(): unmanaged_service(u'stop', u'lxc', u'systemd', display='console', ctx=ctx) unmanaged_service(u'stop', u'lxc-net', u'systemd', display='console', ctx=ctx) _start_containers() elif action == u'configure': if display_title: ihm.print_title(_(u"Configuring services")) else: raise ValueError(_(u"Unknown service action: {0}").format(action)) if options.container is not None: containers_ctx = [CACHE['group_infos'][options.containers]] else: containers_ctx = CACHE['group_infos'].values() manage_services(action, container=options.container, display='console', exclude=exclude, containers_ctx=containers_ctx) def _gen_user_list(): """Generate list of users for password modification Start with basic one and ask for supplementary users. """ yield 'root' node = client.get_creole(u'activer_onenode', 'non') master = client.get_creole(u'activer_onesinglenode', 'non') if node == 'oui' and master == 'non': yield 'oneadmin' for number in count(1): if number == 1: yield 'eole' else: yield 'eole{0}'.format(number) def users(): """Manage users """ from passlib.context import CryptContext ihm.print_title(_(u'Managing system user accounts')) schemes = [u'sha512_crypt', u'sha256_crypt', u'sha1_crypt', u'md5_crypt'] cryptctx = CryptContext(schemes=schemes) default_pass = {u'root': u'$eole&123456$', u'eole': u'$fpmf&123456$', u'oneadmin': u'$eole&123456$'} if not options.interactive: log.debug(_(u'No system user account management in non-interactive mode.')) return for user in _gen_user_list(): try: user_infos = spwd.getspnam(user) except KeyError: if user == u'root': msg = _(u"'root' user unknown. This is abnormal.") raise Exception(msg) # no new administrator with NFS (#16321) if user != 'eole' and client.get_creole(u'adresse_serveur_nfs', None) is not None: log.warn(_(u'No new EOLE account with /home on NFS')) break prompt = _('Create new administrator user account {0}?') if user != 'eole' and ihm.prompt_boolean(prompt.format(user)) is False: break msg = _(u"Creating unexistent user {0}") log.info(msg.format(user)) cmd = ['adduser', '--quiet', '--shell', '/usr/bin/manage-eole', '--gecos', '{0} user'.format(user.upper()), '--disabled-password', user] code = process.system_code(cmd) if code != 0: msg = _(u"Unable to create user {0}") raise Exception(msg.format(user)) cmd = ['usermod', '--append', '--groups', 'adm,mail', user] code, out, err = process.system_out(cmd) if code != 0: msg = _(u"Unable to add '{0}' to group 'adm'.") raise Exception(msg.format(user)) # Update informations user_infos = spwd.getspnam(user) if user not in default_pass and user_infos.sp_pwd not in ['!', '*']: msg = _(u"No modification of password of administrator user account {0}.") log.warn(msg.format(user)) continue # Change password: # - on first instance # - if user is not an EOLE default user # - if user password match default ones if (not os.path.isfile(INSTANCE_LOCKFILE) or (user not in default_pass or user_infos.sp_pwd in ['!', '*'] or cryptctx.verify(default_pass[user], user_infos.sp_pwd))): msg = _(u"# Modificating password for user account {0} #") msg = msg.format(user) log.warn(u'#' * len(msg)) log.warn(msg) log.warn(u'#' * len(msg)) max_try = 5 prompt = u'{0}{1}: ' first_prompt = _(u"New password") second_prompt = _(u"Confirming new password") loop_counter = u'' for attempt in range(1, max_try+2): if attempt == max_try+1: msg = _(u"Password input errors for {0}. Abandon.") raise Exception(msg.format(user)) loop_counter = loop_counter.format(attempt, max_try) passwd = getpass.getpass(prompt.format(first_prompt, loop_counter)) confirm_pass = getpass.getpass(prompt.format(second_prompt, loop_counter)) if passwd == confirm_pass: if user in default_pass and default_pass[user] == passwd: log.error(_(u"Can not use default password.")) else: # Now we have the password stdin = '{0}:{1}'.format(user, passwd) code, stdout, stderr = process.system_out(['chpasswd'], stdin=stdin) if code == 0: msg = _(u'User {0} password updated.') log.info(msg.format(user)) # Success break msg = _(u"Error changing password for {0}.") try_again_pos = stdout.find('Try again.') chpassmsg = stdout[0:try_again_pos] log.error(msg.format(user)) print chpassmsg else: log.error(_(u"Passwords mismatch.")) # Display counter loop_counter = u' ({0}/{1})' def certificates(): """Manage certificates """ ihm.print_title(_(u'Managing certificates')) try: # regénération des hashes des certificats SSL après avec créé les nouveaux certificats # porté de 2.3 #8488 cert.rehash_if_needed() cert.gen_certs() except Exception, err: if options.debug: log.debug(err, exc_info=True) else: log.error(err) raise Exception(_(u"Error while generating certificates: {0}").format(err)) cache() if CACHE['is_lxc_enabled']: src = os.path.join(cert.ssl_dir, "certs") for group_name in CACHE['groups_container']: group = CACHE['group_infos'][group_name] ihm.print_line(_("Copying certificates in {0}").format(group['name'])) dst = os.path.join('/', group['path'].lstrip('/').encode(charset), src.lstrip('/')) copyDirectoryContent(src, dst) process.system_out(['/usr/bin/c_rehash'], container=group_name) def param_kernel(): """Manage kernel parameters """ ihm.print_title(_(u'Applying kernel parameters')) os.system('/sbin/sysctl -p >/dev/null') def kill_dhclient(): """Kill dhclient for static IP configuration. """ if client.get_creole(u'eth0_method') == u'statique': os.system('killall dhclient dhclient3 2>/dev/null') def finalize(need_lock=True): """Clean up """ ihm.print_title(_(u'Finalizing configuration')) # enregistrement try: process.system_out("/usr/share/creole/diag.py") except Exception: pass fonctionseole.zephir("FIN", "Configuration terminée", COMPAT_NAME.upper()) if not os.path.isfile(INSTANCE_LOCKFILE): # l'instance est allée à son terme (#7051) file(INSTANCE_LOCKFILE, 'w').close() if os.path.isfile(UPGRADE_LOCKFILE): os.unlink(UPGRADE_LOCKFILE) if os.path.isfile(container_instance_lockfile): os.unlink(container_instance_lockfile) # sauvegarde des 2 dernières versions de la configuration (#8455) old = '{0}.bak'.format(configeol) old1 = '{0}.bak.1'.format(configeol) if not os.path.isfile(old): log.debug(_(u'Backup {0} in {1}'.format(configeol, old))) shutil.copy(configeol, old) elif process.system_out(['diff', '-q', configeol, old])[0] == 0: log.debug(_(u"{0} was not modified".format(configeol))) else: log.debug(_(u'Backup {0} in {1}'.format(old, old1))) shutil.copy(old, old1) log.debug(_(u'Backup {0} in {1}'.format(configeol, old))) shutil.copy(configeol, old) if need_lock: unlock_actions() def update_server(): """Manage server update """ if os.path.isfile(MAJ_SUCCES_LOCK): os.remove(MAJ_SUCCES_LOCK) if options.interactive: log.info(_(u'Managing update')) ihm.print_title(_(u'Updating server')) if ihm.prompt_boolean(_(u"""An update is recommended. Do you want to proceed with network update now ?"""), default=True, level='warn', default_uninteractive=False) is True: report(2) try: load_pkgmgr() _configure_sources_mirror(PKGMGR.pkgmgr) PKGMGR.update(silent=True) upgrades = PKGMGR.get_upgradable_list(silent=True) require_dist_upgrade = False for container, upgrades in upgrades.items(): if upgrades: require_dist_upgrade = True break if require_dist_upgrade: # At least one container require upgrade PKGMGR.dist_upgrade() # Update lock => OK, will be deleted at next reconfigure report(0) # recall reconfigure main(force_options={'interactive': False}) # back to instance options.interactive = True reset_compat_name() else: log.warn(_(u"No updates available.")) report(3) except Exception, err: report(1, normalize(err)) raise err def schedule(): """Manage task scheduling """ ihm.print_title(_(u'Task scheduling')) apply_schedules() display_schedules() # 1er lancement de instance #if not os.path.isfile(schedule.SCHEDULE_FILE): # schedule.add_post_schedule('majauto', 'weekly') #schedule.prog_schedule() def is_valid_ip_eth0(): """Check if adresse_ip_eth0 is 169.254.0.1 """ ip_eth0 = client.get_creole(u'adresse_ip_eth0') if ip_eth0 == "169.254.0.1": return False else: return True def reboot_server(): """Reboot the server if required """ if fonctionseole.controle_kernel(): if options.interactive: print if ihm.prompt_boolean(_(u"""Reboot is necessary. Do you want to reboot now?"""), default=True, level='warn') is True: fonctionseole.zephir("MSG", "Demande de redémarrage acceptée par l'utilisateur", COMPAT_NAME.upper()) process.system_code(['reboot']) else: fonctionseole.zephir("MSG", "Demande de redémarrage refusée par l'utilisateur", COMPAT_NAME.upper()) else: print ihm.print_orange(_(u'Reboot necessary')) time.sleep(1) print if options.auto: fonctionseole.zephir("MSG", "Redémarrage automatique", COMPAT_NAME.upper()) process.system_code(['reboot']) else: fonctionseole.zephir("MSG", "Redémarrage du serveur à planifier", COMPAT_NAME.upper()) def main(force_options=None, force_args=None, need_lock=True): """Entry point """ global log options.update_from_cmdline(force_args=force_args, force_options=force_options) try: # module level logger log = init_logging(name=u'reconfigure', level=options.log_level, console=['stderr', 'stddebug'], filename=_LOGFILENAME) # Remove module name prefix from Warn/error messages emitted # from here set_formatter(log, 'stderr', 'brief') # Define handlers for additional loggers # Thoses logger are not for use # Log pyeole.service pyeole_service_log = init_logging(name=u'pyeole.service', level=options.log_level, filename=_LOGFILENAME, console=['stderr']) # Log pyeole.pkg pyeole_pkg_log = init_logging(name=u'pyeole.pkg', level=options.log_level, filename=_LOGFILENAME) passlib_log = init_logging(name=u'passlib.registry', level='error', filename=_LOGFILENAME) # Disable warnings from pyeole.service set_filters(pyeole_service_log, 'stderr', ['error', 'critical']) if options.verbose or options.debug: # Enable creole logs creole_log = init_logging(name=u'creole', level=options.log_level, filename=_LOGFILENAME) # Define a root logger when verbose or debug is activated root_log = init_logging(level=options.log_level) else: # Enable creole logs creole_log = init_logging(name=u'creole', level=options.log_level, filename=_LOGFILENAME, console=['stderr']) creolemajauto_log = init_logging(name=u'creole.majauto', level=options.log_level, filename=_LOGFILENAME, console=['stderr', 'stdout']) ihm.print_title(_(u'Beginning of configuration')) # instance or reconfigure ? reset_compat_name() fonctionseole.zephir("INIT", "Début de configuration", COMPAT_NAME.upper()) prepare(need_lock) valid_mandatory(need_lock) cache() containers() packages() run_parts(u'preservice') services(action=u'stop') run_parts(u'pretemplate') templates() if not is_valid_ip_eth0(): log.info(_(u"eth0 network interface does not have a valid IP address.")) log.info(_(u"Restarting networking service")) manage_service(u'restart', u'networking', display='console') templates() if not is_valid_ip_eth0(): log.info(_(u"eth0 network interface does not have a valid IP address.")) msg = _(u"Unable to obtain IP address.") raise NetworkConfigError(msg) services(action=u'configure') # posttemplate/00-annuaire needs the certificates certificates() run_parts(u'posttemplate') #close all connexion before param kernel #17408 client.close() param_kernel() kill_dhclient() services(action=u'start') users() run_parts(u'postservice') schedule() finalize(need_lock) ihm.print_title(_(u'Reconfiguration OK')) update_server() # IMPORTANT : Ne rien faire après ces lignes # car le serveur est susceptible d'être redémarré reboot_server() except (UserExit, UserExitError), err: unlock_actions(need_lock) fonctionseole.zephir("FIN", "Abandon par l'utilisateur", COMPAT_NAME.upper()) raise err except Exception, err: if options.debug: log.debug(err, exc_info=True) else: log.error(err) fonctionseole.zephir('ERR', str(err), COMPAT_NAME.upper(), console=False) if need_lock: release(LOCK_NAME, valid=False, level='system') raise err if __name__ == '__main__': main()