def exit(code, status=None): """ exits with the code provided, properly disposing of resources If status is not None, use sd_notify to report the status to systemd """ if status is not None and status != "": sd_notify("STATUS=%s" % status) if executor: try: executor.terminate() except KeyboardInterrupt: signal.signal(signal.SIGINT, signal.SIG_IGN) for v in executor.virts: v.stop() if v.ident: v.join() for d in executor.destinations: d.stop() if d.ident: d.join() if log.hasQueueLogger(): queueLogger = log.getQueueLogger() queueLogger.terminate() sys.exit(code)
def exit(code, status=None): """ exits with the code provided, properly disposing of resources If status is not None, use sd_notify to report the status to systemd """ if status is not None and status != "": sd_notify("STATUS=%s" % status) if executor: executor.logger.debug(str(status)) try: executor.terminate() except KeyboardInterrupt: signal.signal(signal.SIGINT, signal.SIG_IGN) for v in executor.virts: v.stop() if v.ident: v.join() for d in executor.destinations: d.stop() if d.ident: d.join() if log.hasQueueLogger(): queueLogger = log.getQueueLogger() queueLogger.terminate() sys.exit(code)
def exit(code, status=None): """ exits with the code provided, properly disposing of resources If status is not None, use sd_notify to report the status to systemd """ if status is not None: sd_notify("STATUS=%s" % status) if virtWho: virtWho.terminate() queueLogger = log.getDefaultQueueLogger() if queueLogger: queueLogger.terminate() sys.exit(code)
def exit(code, status=None): """ exits with the code provided, properly disposing of resources If status is not None, use sd_notify to report the status to systemd """ if status is not None: sd_notify("STATUS=%s" % status) if virtWho: virtWho.terminate() queueLogger = log.getQueueLogger() if queueLogger: queueLogger.terminate() sys.exit(code)
def notify(): sd_notify("WATCHDOG=1") loop.call_later(interval, notify)
def main(): logger = effective_config = None try: logger, effective_config = parse_options() # We now have the effective_config except OptionError as e: print(str(e), file=sys.stderr) exit(1, status="virt-who can't be started: %s" % str(e)) lock = PIDLock(PIDFILE) if lock.is_locked(): msg = "virt-who seems to be already running. If not, remove %s" % \ PIDFILE print(msg, file=sys.stderr) exit(1, status=msg) if not effective_config[VW_GLOBAL].is_valid(): message = "Required section 'global' is invalid:\n" message += "\n".join([ msg for (level, msg) in effective_config[VW_GLOBAL].validation_messages ]) message += "\n" exit(1, "virt-who can't be started: %s" % message) valid_virt_sections = [(name, section) for (name, section) in effective_config.virt_sections() if section.is_valid()] if not valid_virt_sections: err = "virt-who can't be started: no valid configuration found" logger.error(err) exit(1, err) global executor has_error = False try: executor = Executor(logger, effective_config) except (InvalidKeyFile, InvalidPasswordFormat) as e: logger.error(str(e)) exit(1, "virt-who can't be started: %s" % str(e)) if len(executor.dest_to_source_mapper.dests) == 0: if has_error: err = "virt-who can't be started: no valid destination found" logger.error(err) exit(1, err) if len(effective_config[VW_GLOBAL]['configs']) > 0: # When config file is provided using -c or --config, then other config # files in /etc/virt-who.d are ignored. When it is not possible to read # any configuration file, then virt-who should be terminated cli_config_file_readable = False for file_name in effective_config[VW_GLOBAL]['configs']: if os.path.isfile(file_name): cli_config_file_readable = True if cli_config_file_readable is False: err = 'No valid configuration file provided using -c/--config' logger.error(err) exit(1, "virt-who can't be started: %s" % str(err)) for name, config in executor.dest_to_source_mapper.configs: logger.info('Using configuration "%s" ("%s" mode)', name, config['type']) logger.info("Using reporter_id='%s'", effective_config[VW_GLOBAL]['reporter_id']) log.closeLogger(logger) with lock: signal.signal(signal.SIGHUP, reload) signal.signal(signal.SIGTERM, atexit_fn) executor.logger = logger = log.getLogger(name='main', queue=True) sd_notify("READY=1\nMAINPID=%d" % os.getpid()) while True: try: return _main(executor) except ReloadRequest: logger.info("Reloading") continue except ExitRequest as e: exit(e.code, status=e.message)
def main(args=None): '''Mount S3QL file system''' if args is None: args = sys.argv[1:] options = parse_args(args) # Save handler so that we can remove it when daemonizing stdout_log_handler = setup_logging(options) if not os.path.exists(options.mountpoint): raise QuietError('Mountpoint does not exist.', exitcode=36) if options.threads is None: options.threads = determine_threads(options) avail_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if avail_fd == resource.RLIM_INFINITY: avail_fd = 4096 resource.setrlimit(resource.RLIMIT_NOFILE, (avail_fd, avail_fd)) # Subtract some fd's for random things we forgot, and a fixed number for # each upload thread (because each thread is using at least one socket and # at least one temporary file) avail_fd -= 32 + 3 * options.threads if options.max_cache_entries is None: if avail_fd <= 64: raise QuietError("Not enough available file descriptors.", exitcode=37) log.info( 'Autodetected %d file descriptors available for cache entries', avail_fd) options.max_cache_entries = avail_fd else: if options.max_cache_entries > avail_fd: log.warning( "Up to %d cache entries requested, but detected only %d " "available file descriptors.", options.max_cache_entries, avail_fd) options.max_cache_entries = avail_fd if options.profile: import cProfile import pstats prof = cProfile.Profile() backend_factory = get_backend_factory(options.storage_url, options.backend_options, options.authfile, options.compress) backend_pool = BackendPool(backend_factory) atexit.register(backend_pool.flush) # Get paths cachepath = get_backend_cachedir(options.storage_url, options.cachedir) # Retrieve metadata with backend_pool() as backend: (param, db) = get_metadata(backend, cachepath) #if param['max_obj_size'] < options.min_obj_size: # raise QuietError('Maximum object size must be bigger than minimum object size.', # exitcode=2) # Handle --cachesize rec_cachesize = options.max_cache_entries * param['max_obj_size'] / 2 avail_cache = shutil.disk_usage(os.path.dirname(cachepath))[2] / 1024 if options.cachesize is None: options.cachesize = min(rec_cachesize, 0.8 * avail_cache) log.info('Setting cache size to %d MB', options.cachesize / 1024) elif options.cachesize > avail_cache: log.warning('Requested cache size %d MB, but only %d MB available', options.cachesize / 1024, avail_cache / 1024) if options.nfs: # NFS may try to look up '..', so we have to speed up this kind of query log.info('Creating NFS indices...') db.execute( 'CREATE INDEX IF NOT EXISTS ix_contents_inode ON contents(inode)') else: db.execute('DROP INDEX IF EXISTS ix_contents_inode') metadata_upload_thread = MetadataUploadThread( backend_pool, param, db, options.metadata_upload_interval) block_cache = BlockCache(backend_pool, db, cachepath + '-cache', options.cachesize * 1024, options.max_cache_entries) commit_thread = CommitThread(block_cache) operations = fs.Operations(block_cache, db, max_obj_size=param['max_obj_size'], inode_cache=InodeCache(db, param['inode_gen']), upload_event=metadata_upload_thread.event) block_cache.fs = operations metadata_upload_thread.fs = operations with ExitStack() as cm: log.info('Mounting %s at %s...', options.storage_url, options.mountpoint) try: llfuse.init(operations, options.mountpoint, get_fuse_opts(options)) except RuntimeError as exc: raise QuietError(str(exc), exitcode=39) unmount_clean = False def unmount(): log.info("Unmounting file system...") llfuse.close(unmount=unmount_clean) cm.callback(unmount) if options.fg: faulthandler.enable() faulthandler.register(signal.SIGUSR1) else: if stdout_log_handler: logging.getLogger().removeHandler(stdout_log_handler) global crit_log_fh crit_log_fh = open( os.path.join(options.cachedir, 'mount.s3ql_crit.log'), 'a') faulthandler.enable(crit_log_fh) faulthandler.register(signal.SIGUSR1, file=crit_log_fh) daemonize(options.cachedir) mark_metadata_dirty(backend, cachepath, param) block_cache.init(options.threads) cm.callback(block_cache.destroy) metadata_upload_thread.start() cm.callback(metadata_upload_thread.join) cm.callback(metadata_upload_thread.stop) commit_thread.start() cm.callback(commit_thread.join) cm.callback(commit_thread.stop) if options.upstart: os.kill(os.getpid(), signal.SIGSTOP) if sd_notify is not None: sd_notify('READY=1') sd_notify('MAINPID=%d' % os.getpid()) exc_info = setup_exchook() workers = 1 if options.single else None # use default if options.profile: ret = prof.runcall(llfuse.main, workers) else: ret = llfuse.main(workers) if ret is not None: raise RuntimeError('Received signal %d, terminating' % (ret, )) # Allow operations to terminate while block_cache is still available # (destroy() will be called again when from llfuse.close(), but at that # point the block cache is no longer available). with llfuse.lock: operations.destroy() # Re-raise if main loop terminated due to exception in other thread if exc_info: (exc_inst, exc_tb) = exc_info raise exc_inst.with_traceback(exc_tb) log.info("FUSE main loop terminated.") unmount_clean = True # At this point, there should be no other threads left # Do not update .params yet, dump_metadata() may fail if the database is # corrupted, in which case we want to force an fsck. param['max_inode'] = db.get_val('SELECT MAX(id) FROM inodes') if operations.failsafe: log.warning('File system errors encountered, marking for fsck.') param['needs_fsck'] = True with backend_pool() as backend: seq_no = get_seq_no(backend) if metadata_upload_thread.db_mtime == os.stat(cachepath + '.db').st_mtime: log.info('File system unchanged, not uploading metadata.') del backend['s3ql_seq_no_%d' % param['seq_no']] param['seq_no'] -= 1 save_params(cachepath, param) elif seq_no == param['seq_no']: param['last-modified'] = time.time() dump_and_upload_metadata(backend, db, param) save_params(cachepath, param) else: log.error( 'Remote metadata is newer than local (%d vs %d), ' 'refusing to overwrite!', seq_no, param['seq_no']) log.error( 'The locally cached metadata will be *lost* the next time the file system ' 'is mounted or checked and has therefore been backed up.') for name in (cachepath + '.params', cachepath + '.db'): for i in range(4)[::-1]: if os.path.exists(name + '.%d' % i): os.rename(name + '.%d' % i, name + '.%d' % (i + 1)) os.rename(name, name + '.0') log.info('Cleaning up local metadata...') db.execute('ANALYZE') db.execute('VACUUM') db.close() if options.profile: with tempfile.NamedTemporaryFile() as tmp, \ open('s3ql_profile.txt', 'w') as fh: prof.dump_stats(tmp.name) p = pstats.Stats(tmp.name, stream=fh) p.strip_dirs() p.sort_stats('cumulative') p.print_stats(50) p.sort_stats('time') p.print_stats(50) log.info('All done.')
def serve(self): if sd_notify is not None and sd_booted(): sd_notify("READY=1") return self.httpd.serve_forever()
def notify_stopping(): sd_notify("STOPPING=1")
def main(): logger = effective_config = None try: logger, effective_config = parse_options() # We now have the effective_config except OptionError as e: print(str(e), file=sys.stderr) exit(1, status="virt-who can't be started: %s" % str(e)) lock = PIDLock(PIDFILE) if lock.is_locked(): msg = "virt-who seems to be already running. If not, remove %s" % \ PIDFILE print(msg, file=sys.stderr) exit(1, status=msg) if not effective_config[VW_GLOBAL].is_valid(): message = "Required section 'global' is invalid:\n" message += "\n".join([msg for (level, msg) in effective_config[VW_GLOBAL].validation_messages]) message += "\n" exit(1, "virt-who can't be started: %s" % message) valid_virt_sections = [(name, section) for (name, section) in effective_config.virt_sections() if section.is_valid()] if not valid_virt_sections: err = "virt-who can't be started: no valid configuration found" logger.error(err) exit(1, err) global executor has_error = False try: executor = Executor(logger, effective_config) except (InvalidKeyFile, InvalidPasswordFormat) as e: logger.error(str(e)) exit(1, "virt-who can't be started: %s" % str(e)) if len(executor.dest_to_source_mapper.dests) == 0: if has_error: err = "virt-who can't be started: no valid destination found" logger.error(err) exit(1, err) for name, config in executor.dest_to_source_mapper.configs: logger.info('Using configuration "%s" ("%s" mode)', name, config['type']) logger.info("Using reporter_id='%s'", effective_config[VW_GLOBAL]['reporter_id']) log.closeLogger(logger) with lock: signal.signal(signal.SIGHUP, reload) signal.signal(signal.SIGTERM, atexit_fn) executor.logger = logger = log.getLogger(name='main', queue=True) sd_notify("READY=1\nMAINPID=%d" % os.getpid()) while True: try: return _main(executor) except ReloadRequest: logger.info("Reloading") continue except ExitRequest as e: exit(e.code, status=e.message)
def main(args=None): '''Mount S3QL file system''' if args is None: args = sys.argv[1:] options = parse_args(args) # Save handler so that we can remove it when daemonizing stdout_log_handler = setup_logging(options) if not os.path.exists(options.mountpoint): raise QuietError('Mountpoint does not exist.', exitcode=36) if options.threads is None: options.threads = determine_threads(options) avail_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if avail_fd == resource.RLIM_INFINITY: avail_fd = 4096 resource.setrlimit(resource.RLIMIT_NOFILE, (avail_fd, avail_fd)) # Subtract some fd's for random things we forgot, and a fixed number for # each upload thread (because each thread is using at least one socket and # at least one temporary file) avail_fd -= 32 + 3 * options.threads if options.max_cache_entries is None: if avail_fd <= 64: raise QuietError("Not enough available file descriptors.", exitcode=37) log.info('Autodetected %d file descriptors available for cache entries', avail_fd) options.max_cache_entries = avail_fd else: if options.max_cache_entries > avail_fd: log.warning("Up to %d cache entries requested, but detected only %d " "available file descriptors.", options.max_cache_entries, avail_fd) options.max_cache_entries = avail_fd if options.profile: import cProfile import pstats prof = cProfile.Profile() backend_factory = get_backend_factory(options.storage_url, options.backend_options, options.authfile, options.compress) backend_pool = BackendPool(backend_factory) atexit.register(backend_pool.flush) # Get paths cachepath = get_backend_cachedir(options.storage_url, options.cachedir) # Retrieve metadata with backend_pool() as backend: (param, db) = get_metadata(backend, cachepath) #if param['max_obj_size'] < options.min_obj_size: # raise QuietError('Maximum object size must be bigger than minimum object size.', # exitcode=2) # Handle --cachesize rec_cachesize = options.max_cache_entries * param['max_obj_size'] / 2 avail_cache = shutil.disk_usage(os.path.dirname(cachepath))[2] / 1024 if options.cachesize is None: options.cachesize = min(rec_cachesize, 0.8 * avail_cache) log.info('Setting cache size to %d MB', options.cachesize / 1024) elif options.cachesize > avail_cache: log.warning('Warning! Requested cache size %d MB, but only %d MB available', options.cachesize / 1024, avail_cache / 1024) if options.nfs: # NFS may try to look up '..', so we have to speed up this kind of query log.info('Creating NFS indices...') db.execute('CREATE INDEX IF NOT EXISTS ix_contents_inode ON contents(inode)') else: db.execute('DROP INDEX IF EXISTS ix_contents_inode') metadata_upload_thread = MetadataUploadThread(backend_pool, param, db, options.metadata_upload_interval) block_cache = BlockCache(backend_pool, db, cachepath + '-cache', options.cachesize * 1024, options.max_cache_entries) commit_thread = CommitThread(block_cache) operations = fs.Operations(block_cache, db, max_obj_size=param['max_obj_size'], inode_cache=InodeCache(db, param['inode_gen']), upload_event=metadata_upload_thread.event) metadata_upload_thread.fs = operations with ExitStack() as cm: log.info('Mounting %s at %s...', options.storage_url, options.mountpoint) try: llfuse.init(operations, options.mountpoint, get_fuse_opts(options)) except RuntimeError as exc: raise QuietError(str(exc), exitcode=39) unmount_clean = False def unmount(): log.info("Unmounting file system...") # Acquire lock so that Operations.destroy() is called with the # global lock like all other handlers with llfuse.lock: llfuse.close(unmount=unmount_clean) cm.callback(unmount) if options.fg: faulthandler.enable() faulthandler.register(signal.SIGUSR1) else: if stdout_log_handler: logging.getLogger().removeHandler(stdout_log_handler) global crit_log_fh crit_log_fh = open(os.path.join(options.cachedir, 'mount.s3ql_crit.log'), 'a') faulthandler.enable(crit_log_fh) faulthandler.register(signal.SIGUSR1, file=crit_log_fh) daemonize(options.cachedir) mark_metadata_dirty(backend, cachepath, param) block_cache.init(options.threads) cm.callback(block_cache.destroy) metadata_upload_thread.start() cm.callback(metadata_upload_thread.join) cm.callback(metadata_upload_thread.stop) commit_thread.start() cm.callback(commit_thread.join) cm.callback(commit_thread.stop) if options.upstart: os.kill(os.getpid(), signal.SIGSTOP) if sd_notify is not None: sd_notify('READY=1') sd_notify('MAINPID=%d' % os.getpid()) exc_info = setup_exchook() if options.profile: prof.runcall(llfuse.main, options.single) else: llfuse.main(options.single) # Allow operations to terminate while block_cache is still available # (destroy() will be called again when from llfuse.close(), but at that # point the block cache is no longer available). with llfuse.lock: operations.destroy() # Re-raise if main loop terminated due to exception in other thread if exc_info: (exc_inst, exc_tb) = exc_info raise exc_inst.with_traceback(exc_tb) log.info("FUSE main loop terminated.") unmount_clean = True # At this point, there should be no other threads left # Do not update .params yet, dump_metadata() may fail if the database is # corrupted, in which case we want to force an fsck. param['max_inode'] = db.get_val('SELECT MAX(id) FROM inodes') if operations.failsafe: log.warning('File system errors encountered, marking for fsck.') param['needs_fsck'] = True with backend_pool() as backend: seq_no = get_seq_no(backend) if metadata_upload_thread.db_mtime == os.stat(cachepath + '.db').st_mtime: log.info('File system unchanged, not uploading metadata.') del backend['s3ql_seq_no_%d' % param['seq_no']] param['seq_no'] -= 1 with open(cachepath + '.params', 'wb') as fh: fh.write(freeze_basic_mapping(param)) elif seq_no == param['seq_no']: param['last-modified'] = time.time() dump_and_upload_metadata(backend, db, param) with open(cachepath + '.params', 'wb') as fh: fh.write(freeze_basic_mapping(param)) else: log.error('Remote metadata is newer than local (%d vs %d), ' 'refusing to overwrite!', seq_no, param['seq_no']) log.error('The locally cached metadata will be *lost* the next time the file system ' 'is mounted or checked and has therefore been backed up.') for name in (cachepath + '.params', cachepath + '.db'): for i in range(4)[::-1]: if os.path.exists(name + '.%d' % i): os.rename(name + '.%d' % i, name + '.%d' % (i + 1)) os.rename(name, name + '.0') log.info('Cleaning up local metadata...') db.execute('ANALYZE') db.execute('VACUUM') db.close() if options.profile: with tempfile.NamedTemporaryFile() as tmp, \ open('s3ql_profile.txt', 'w') as fh: prof.dump_stats(tmp.name) p = pstats.Stats(tmp.name, stream=fh) p.strip_dirs() p.sort_stats('cumulative') p.print_stats(50) p.sort_stats('time') p.print_stats(50) log.info('All done.')
def main(): try: logger, options = parseOptions() except OptionError as e: print >>sys.stderr, str(e) exit(1, status="virt-who can't be started: %s" % str(e)) lock = PIDLock(PIDFILE) if lock.is_locked(): msg = "virt-who seems to be already running. If not, remove %s" % PIDFILE print >>sys.stderr, msg exit(1, status=msg) global virtWho try: virtWho = VirtWho(logger, options) except (InvalidKeyFile, InvalidPasswordFormat) as e: logger.error(str(e)) exit(1, "virt-who can't be started: %s" % str(e)) if options.virtType is not None: config = Config("env/cmdline", options.virtType, virtWho.configManager._defaults, **options) config.checkOptions(logger) virtWho.configManager.addConfig(config) for conffile in options.configs: try: virtWho.configManager.readFile(conffile) except Exception as e: logger.error('Config file "%s" skipped because of an error: %s' % (conffile, str(e))) if len(virtWho.configManager.configs) == 0: # In order to keep compatibility with older releases of virt-who, # fallback to using libvirt as default virt backend logger.info("No configurations found, using libvirt as backend") virtWho.configManager.addConfig(Config("env/cmdline", "libvirt")) for config in virtWho.configManager.configs: if config.name is None: logger.info('Using commandline or sysconfig configuration ("%s" mode)', config.type) else: logger.info('Using configuration "%s" ("%s" mode)' % (config.name, config.type)) log.closeLogger(logger) if options.background: locker = lambda: daemon.DaemonContext(pidfile=lock) else: locker = lambda: lock with locker(): signal.signal(signal.SIGHUP, reload) signal.signal(signal.SIGTERM, atexit_fn) virtWho.logger = logger = log.getLogger(name='main', config=None, queue=True) sd_notify("READY=1\nMAINPID=%d" % os.getpid()) while True: try: _main(virtWho) break except ReloadRequest: logger.info("Reloading") continue
def main(): try: logger, options = parseOptions() except OptionError as e: print >> sys.stderr, str(e) exit(1, status="virt-who can't be started: %s" % str(e)) lock = PIDLock(PIDFILE) if lock.is_locked(): msg = "virt-who seems to be already running. If not, remove %s" % PIDFILE print >> sys.stderr, msg exit(1, status=msg) global RetryInterval if options.interval < RetryInterval: RetryInterval = options.interval global virtWho try: virtWho = VirtWho(logger, options) except (InvalidKeyFile, InvalidPasswordFormat) as e: logger.error(str(e)) exit(1, "virt-who can't be started: %s" % str(e)) if options.virtType is not None: config = Config("env/cmdline", options.virtType, **options.__dict__) config.checkOptions(options.smType, logger) virtWho.configManager.addConfig(config) for conffile in options.configs: try: virtWho.configManager.readFile(conffile) except Exception as e: logger.error('Config file "%s" skipped because of an error: %s' % (conffile, str(e))) if len(virtWho.configManager.configs) == 0: # In order to keep compatibility with older releases of virt-who, # fallback to using libvirt as default virt backend logger.info("No configurations found, using libvirt as backend") virtWho.configManager.addConfig(Config("env/cmdline", "libvirt")) for config in virtWho.configManager.configs: if config.name is None: logger.info( 'Using commandline or sysconfig configuration ("%s" mode)', config.type) else: logger.info('Using configuration "%s" ("%s" mode)' % (config.name, config.type)) log.closeLogger(logger) if options.background: locker = lambda: daemon.DaemonContext(pidfile=lock) else: locker = lambda: lock with locker(): signal.signal(signal.SIGHUP, reload) signal.signal(signal.SIGTERM, atexit_fn) virtWho.logger = logger = log.getLogger(options, queue=True) sd_notify("READY=1\nMAINPID=%d" % os.getpid()) while True: try: _main(virtWho) break except ReloadRequest: logger.info("Reloading") continue
def notify_reloading(): sd_notify("RELOADING=1")
def main(): logger = options = None try: logger, options = parseOptions() except OptionError as e: print >>sys.stderr, str(e) exit(1, status="virt-who can't be started: %s" % str(e)) lock = PIDLock(PIDFILE) if lock.is_locked(): msg = "virt-who seems to be already running. If not, remove %s" % PIDFILE print >>sys.stderr, msg exit(1, status=msg) global executor try: executor = Executor(logger, options) except (InvalidKeyFile, InvalidPasswordFormat) as e: logger.error(str(e)) exit(1, "virt-who can't be started: %s" % str(e)) if options.virtType is not None: config = Config("env/cmdline", options.virtType, executor.configManager._defaults, **options) try: config.checkOptions(logger) except InvalidOption as e: err = "virt-who can't be started: %s" % str(e) logger.error(err) exit(1, err) executor.configManager.addConfig(config) has_error = False for conffile in options.configs: try: executor.configManager.readFile(conffile) except InvalidPasswordFormat as e: err = "virt-who can't be started: %s" % str(e) logger.error(err) exit(1, err) except Exception as e: logger.error('Config file "%s" skipped because of an error: %s', conffile, str(e)) has_error = True if len(executor.configManager.configs) == 0: if has_error: err = "virt-who can't be started: no valid configuration found" logger.error(err) exit(1, err) # In order to keep compatibility with older releases of virt-who, # fallback to using libvirt as default virt backend logger.info("No configurations found, using libvirt as backend") executor.configManager.addConfig(Config("env/cmdline", "libvirt")) for config in executor.configManager.configs: if config.name is None: logger.info('Using commandline or sysconfig configuration ("%s" mode)', config.type) else: logger.info('Using configuration "%s" ("%s" mode)', config.name, config.type) logger.info("Using reporter_id='%s'", options.reporter_id) log.closeLogger(logger) if options.background: locker = lambda: daemon.DaemonContext(pidfile=lock) # flake8: noqa else: locker = lambda: lock # flake8: noqa with locker(): signal.signal(signal.SIGHUP, reload) signal.signal(signal.SIGTERM, atexit_fn) executor.logger = logger = log.getLogger(name='main', config=None, queue=True) sd_notify("READY=1\nMAINPID=%d" % os.getpid()) while True: try: return _main(executor) except ReloadRequest: logger.info("Reloading") continue
def main(): logger = options = None try: logger, options = parse_options() # We now have the effective_config except OptionError as e: print(str(e), file=sys.stderr) exit(1, status="virt-who can't be started: %s" % str(e)) lock = PIDLock(PIDFILE) if lock.is_locked(): msg = "virt-who seems to be already running. If not, remove %s" % \ PIDFILE print(msg, file=sys.stderr) exit(1, status=msg) if not options[VW_GLOBAL].is_valid(): message = "Required section 'global' is invalid:\n" message += "\n".join([msg for (level, msg) in options[VW_GLOBAL].validation_messages]) message += "\n" exit(1, "virt-who can't be started: %s" % message) valid_virt_sections = [(name, section) for (name, section) in options.virt_sections() if section.is_valid()] if not valid_virt_sections: err = "virt-who can't be started: no valid configuration found" logger.error(err) exit(1, err) global executor has_error = False try: executor = Executor(logger, options) except (InvalidKeyFile, InvalidPasswordFormat) as e: logger.error(str(e)) exit(1, "virt-who can't be started: %s" % str(e)) if len(executor.dest_to_source_mapper.dests) == 0: if has_error: err = "virt-who can't be started: no valid destination found" logger.error(err) exit(1, err) for name, config in executor.dest_to_source_mapper.configs: logger.info('Using configuration "%s" ("%s" mode)', name, config['type']) logger.info("Using reporter_id='%s'", options[VW_GLOBAL]['reporter_id']) log.closeLogger(logger) with lock: signal.signal(signal.SIGHUP, reload) signal.signal(signal.SIGTERM, atexit_fn) executor.logger = logger = log.getLogger(name='main', queue=True) sd_notify("READY=1\nMAINPID=%d" % os.getpid()) while True: try: return _main(executor) except ReloadRequest: logger.info("Reloading") continue except ExitRequest as e: exit(e.code, status=e.message)
def notify_ready(): sd_notify("READY=1")
def notify_watchdog(): sd_notify("WATCHDOG=1")
def notify_status(msg): sd_notify("STATUS={0}".format(msg))