def _write_success_event(self, app, context_id, args): return write_event(APP_REMOVE_SUCCESS, { 'name': app.name, 'version': app.version }, username=self._get_username(args), context_id=context_id)
def _write_fail_event(self, app, context_id, status, args): return write_event(APP_REMOVE_FAILURE, { 'name': app.name, 'version': app.version, 'error_code': str(status) }, username=self._get_username(args), context_id=context_id)
def _write_start_event(self, app, args): return write_event(APP_UPGRADE_START, {'name': app.name, 'version': self.old_app.version}, username=self._get_username(args))
def do_package_updates(options: Namespace, checkForUpdates: bool, silent: bool) -> bool: interactive = not (options.noninteractive or checkForUpdates) updater = UniventionUpdater() # check if component updates are available dprint(silent, 'Checking for package updates: ', newline=False) new_packages, upgraded_packages, removed_packages = updater.component_update_get_packages( ) update_available = bool(new_packages + upgraded_packages + removed_packages) if not update_available: dprint(silent, 'none') return False # updates available ==> stop here in "check-mode" if checkForUpdates: dprint(silent, 'found') return True dprint(silent, 'found\n') if len(removed_packages) > 0: dprint( silent, 'The following packages will be REMOVED:\n %s' % _package_list(removed_packages)) if len(new_packages) > 0: dprint( silent, 'The following packages will be installed:\n %s' % _package_list(new_packages)) if len(upgraded_packages) > 0: dprint( silent, 'The following packages will be upgraded:\n %s' % _package_list(upgraded_packages)) if interactive and not readcontinue('\nDo you want to continue [Y|n]?'): return False time.sleep(1) dprint(silent, 'Starting dist-update at %s...' % (time.ctime()), debug=True) dprint(silent, 'Starting package upgrade', newline=False) hostname = socket.gethostname() context_id = write_event(UPDATE_STARTED, {'hostname': hostname}) if context_id: os.environ['ADMINDIARY_CONTEXT'] = context_id returncode = updater.run_dist_upgrade() if returncode: dprint(silent, 'exitcode of apt-get dist-upgrade: %s' % returncode, debug=True) dprint( silent, 'ERROR: update failed. Please check /var/log/univention/updater.log\n' ) update_status(status='FAILED', errorsource='UPDATE') write_event(UPDATE_FINISHED_FAILURE, {'hostname': hostname}) sys.exit(1) dprint(silent, 'dist-update finished at %s...' % (time.ctime()), debug=True) dprint(silent, 'done') write_event( UPDATE_FINISHED_SUCCESS, { 'hostname': hostname, 'version': 'UCS %(version/version)s-%(version/patchlevel)s errata%(version/erratalevel)s' % configRegistry }) time.sleep(1) return True
def main(): # type: () -> None # PATH does not contain */sbin when called from cron os.environ[ 'PATH'] = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' opt = parse_args() ucr = ConfigRegistry() ucr.load() global fd_log with setup_logging(opt, ucr) as fd_log: try: try: with UpdaterLock(): if opt.check: sys.exit(check(opt, ucr)) ret = find(opt, ucr) if ret: run(opt, ucr, ret[0], ret[1]) update_status(status='DONE') if os.path.exists(failure): os.unlink(failure) if ret: os.execv(sys.argv[0], sys.argv) except VerificationError as ex: msg = '\n'.join([ "Update aborted due to verification error:", "%s" % (ex, ), ] + wrap( dedent("""\ This can and should only be disabled temporarily using the UCR variable 'repository/online/verify'. """))) raise UpdateError(msg, errorsource='SETTINGS') except ConfigurationError as e: msg = 'Update aborted due to configuration error: %s' % e raise UpdateError(msg, errorsource='SETTINGS') except RequiredComponentError as ex: update_status(status='DONE', errorsource='PREPARATION') dprint(ex) except PreconditionError as ex: (phase, order, component, script) = ex.args if phase == 'preup': phase = 'pre-update' errorsource = 'PREUP' # type: _ESRC elif phase == 'postup': phase = 'post-update' errorsource = 'POSTUP' else: errorsource = 'UPDATE' if order == 'main': order = 'release %s' % component elif order == 'pre': order = 'component %s before calling release script' % component elif order == 'post': order = 'component %s after calling release script' % component msg = 'Update aborted by %s script of %s' % (phase, order) raise UpdateError(msg, errorsource=errorsource) update_ucr_updatestatus() except UpdateError as msg: write_event(UPDATE_FINISHED_FAILURE, {'hostname': ucr.get('hostname')}) update_status(status='FAILED', errorsource=msg.errorsource) dprint("Error: %s" % msg) call(['touch', failure]) sys.exit('Error: Please check "%s" for details.' % LOGNAME) except KeyboardInterrupt: update_status(status='FAILED') dprint("\nUpdate aborted by user (ctrl-c)\n") sys.exit(1)
def run(opt, ucr, updater, nextversion): # type: (Namespace, ConfigRegistry, UniventionUpdater, UCS_Version) -> None if opt.noninteractive: opt.ignore_releasenotes = True os.environ['UCS_FRONTEND'] = 'noninteractive' with open(os.path.devnull, 'r') as null: os.dup2(null.fileno(), sys.stdin.fileno()) dprint('Update to = %s' % nextversion) update_status(next_version=nextversion) if opt.updateto: update_status(target_version=opt.updateto) if opt.ignore_releasenotes: os.environ['update_warning_releasenotes_internal'] = 'no' if opt.ignoressh: os.environ['update%d%d_ignoressh' % nextversion.mm] = 'yes' if opt.ignoreterm: os.environ['update%d%d_ignoreterm' % nextversion.mm] = 'yes' add_temporary_sources_list( updater.release_update_temporary_sources_list(nextversion)) try: phase = 'preup' update_status(phase='PREUP') scripts = updater.get_sh_files(nextversion, nextversion) for phase, order in updater.call_sh_files(scripts, LOGNAME, str(nextversion)): # do not switch back and forth between PRE and UPDATE phase resp. UPDATE and POST phase. if (phase, order) not in ( ('update', 'pre'), ('update', 'post'), ): update_status(phase=phase.upper()) if (phase, order) == ('update', 'pre'): log('**** Downloading scripts at %s' % datetime.now().ctime()) elif (phase, order) == ('preup', 'pre'): log('**** Starting actual update at %s' % datetime.now().ctime()) elif (phase, order) == ('update', 'main'): with apt_lock(): if call(cmd_update, shell=True, stdout=fd_log, stderr=fd_log): raise UpdateError('Failed to execute "%s"' % cmd_update, errorsource='UPDATE') context_id = write_event(UPDATE_STARTED, {'hostname': ucr.get('hostname')}) if context_id: os.environ['ADMINDIARY_CONTEXT'] = context_id # Used by ../univention-maintenance-mode/univention-maintenance-mode-update-progress detailed_status = FN_STATUS + '.details' with apt_lock(), open(detailed_status, 'w+b') as detailed_status_fd: fno = detailed_status_fd.fileno() env = dict(os.environ, DEBIAN_FRONTEND="noninteractive") cmd2 = "%s -o APT::Status-FD=%s" % (cmd_dist_upgrade, fno) resultCode = call(cmd2, shell=True, stdout=fd_log, stderr=fd_log, env=env, pass_fds=(fno, )) if os.path.exists(detailed_status): os.unlink(detailed_status) if resultCode != 0: raise UpdateError('Failed to execute "%s"' % cmd_dist_upgrade, errorsource='UPDATE') elif (phase, order) == ('postup', 'main'): # Bug #23202: After an update of Python ucr.handler_set() may not work any more cmd = [ 'univention-config-registry', 'set', 'version/version={}'.format(nextversion.FORMAT % nextversion), 'version/patchlevel={0.patchlevel}'.format(nextversion), ] call(cmd, stdout=fd_log, stderr=fd_log) except BaseException: if phase == 'preup' or (phase == 'update' and order == 'pre'): remove_temporary_sources_list() raise remove_temporary_sources_list() if os.path.exists('/usr/sbin/univention-pkgdb-scan'): call(['/usr/sbin/univention-pkgdb-scan'], stdout=fd_log, stderr=fd_log) if not opt.no_clean: call(['apt-get', 'clean']) call(['touch', reboot_required]) write_event( UPDATE_FINISHED_SUCCESS, { 'hostname': ucr.get('hostname'), 'version': 'UCS %(version/version)s-%(version/patchlevel)s errata%(version/erratalevel)s' % ucr })