コード例 #1
0
 def check_restart_marker(self):
     logger.info("Checking if restart marker '%s' exists",
                 self.restart_marker)
     if os.path.exists(self.restart_marker):
         if os.path.getsize(self.restart_marker) == 0:
             logger.notice(
                 "Old restart marker found, gui startup and daemon startup events disabled"
             )
             self.disabledEventTypes = ["gui startup", "daemon startup"]
         else:
             logger.notice("Reading restart marker")
             with open(self.restart_marker, "r", encoding="utf-8") as file:
                 for line in file.readlines():
                     line = line.strip()
                     if line.startswith("#") or not "=" in line:
                         continue
                     option, value = line.split("=", 1)
                     option = option.strip().lower()
                     if option == "disabled_event_types":
                         self.disabledEventTypes = [
                             v.strip().lower() for v in value.split(",")
                             if v.strip().lower()
                         ]
                         logger.notice(
                             "Event types %s disabled by restart marker",
                             self.disabledEventTypes)
         try:
             os.remove(self.restart_marker)
         except Exception as err:  # pylint: disable=broad-except
             logger.error(err)
コード例 #2
0
def reconfigureEventGenerators():
    eventConfigs = getEventConfigs()
    for eventGenerator in _EVENT_GENERATORS.values():
        eventGenerator.setEventConfigs([])

    for (eventConfigId, eventConfig) in eventConfigs.items():
        mainEventConfigId = eventConfigId.split('{')[0]

        try:
            eventGenerator = _EVENT_GENERATORS[mainEventConfigId]
        except KeyError:
            logger.info(
                "Cannot reconfigure event generator for event '%s': not found",
                eventConfigId)
            continue

        try:
            eventType = eventConfig['type']
            del eventConfig['type']
            ec = EventConfigFactory(eventType, eventConfigId, **eventConfig)
            eventGenerator.addEventConfig(ec)
            logger.notice("Event config '%s' added to event generator '%s'",
                          eventConfigId, mainEventConfigId)
        except Exception as err:  # pylint: disable=broad-except
            logger.error("Failed to reconfigure event generator '%s': %s",
                         mainEventConfigId, err)
コード例 #3
0
 def connectionTimedOut(self):
     error = (
         f"Failed to connect to config service '{self._configServiceUrl}': "
         f"timed out after {config.get('config_service', 'connection_timeout')} seconds"
     )
     logger.error(error)
     raise Exception(error)
コード例 #4
0
ファイル: ControlPipe.py プロジェクト: opsi-org/opsiclientd
    def run(self):
        with log_context({'instance': 'control pipe'}):
            try:
                while not self._stopEvent.is_set():
                    if self.clientInfo:
                        self.checkConnection()
                    else:
                        # Old protocol
                        with self.comLock:
                            request = self.read()
                            if request:
                                logger.info("Received request '%s' from %s",
                                            request, self)
                                response = self.processIncomingRpc(request)
                                logger.info("Sending response '%s' to %s",
                                            response, self)
                                self.write(response)

                                if self.clientInfo:
                                    # Switch to new protocol
                                    self.executeRpc('blockLogin', [
                                        self._controller._opsiclientd.
                                        _blockLogin
                                    ],
                                                    with_lock=False)  # pylint: disable=protected-access
                    time.sleep(0.5)
            except Exception as err:  # pylint: disable=broad-except
                logger.error(err, exc_info=True)
            finally:
                self.clientDisconnected()
コード例 #5
0
    def getFromService(self, configService):
        ''' Get settings from service '''
        logger.notice("Getting config from service")
        if not configService:
            raise Exception("Config service is undefined")

        query = {
            "objectId":
            self.get('global', 'host_id'),
            "configId": [
                'clientconfig.configserver.url',
                'clientconfig.depot.drive',
                'clientconfig.depot.id',
                'clientconfig.depot.user',
                'clientconfig.suspend_bitlocker_on_reboot',
                'opsiclientd.*'  # everything starting with opsiclientd.
            ]
        }

        configService.backend_setOptions({"addConfigStateDefaults": True})
        for configState in configService.configState_getObjects(**query):
            logger.info("Got config state from service: %r", configState)

            if not configState.values:
                logger.debug("No values - skipping %s", configState.configId)
                continue

            if configState.configId == 'clientconfig.configserver.url':
                self.set('config_service', 'url', configState.values)
            elif configState.configId == 'clientconfig.depot.drive':
                self.set('depot_server', 'drive', configState.values[0])
            elif configState.configId == 'clientconfig.depot.id':
                self.set('depot_server', 'depot_id', configState.values[0])
            elif configState.configId == 'clientconfig.depot.user':
                self.set('depot_server', 'username', configState.values[0])
            elif configState.configId == 'clientconfig.suspend_bitlocker_on_reboot':
                self.set('global', 'suspend_bitlocker_on_reboot',
                         configState.values[0])

            elif configState.configId.startswith('opsiclientd.'):
                try:
                    parts = configState.configId.lower().split('.')
                    if len(parts) < 3:
                        logger.debug(
                            "Expected at least 3 parts in %s - skipping.",
                            configState.configId)
                        continue

                    value = configState.values
                    if len(value) == 1:
                        value = value[0]
                    self.set(section=parts[1], option=parts[2], value=value)
                except Exception as err:  # pylint: disable=broad-except
                    logger.error("Failed to process configState '%s': %s",
                                 configState.configId, err)

        logger.notice("Got config from service")
        logger.debug("Config is now:\n %s",
                     objectToBeautifiedText(self.getDict()))
コード例 #6
0
 def clearRebootRequest(self):
     rebootFile = os.path.join(self._PID_DIR, "reboot")
     if os.path.exists(rebootFile):
         try:
             os.remove(rebootFile)
         except OSError as err:
             logger.error("Failed to remove reboot file %s: %s", err,
                          rebootFile)
コード例 #7
0
 def clearShutdownRequest(self):
     shutdownFile = os.path.join(self._PID_DIR, "shutdown")
     if os.path.exists(shutdownFile):
         try:
             os.remove(shutdownFile)
         except OSError as err:
             logger.error("Failed to remove shutdown file %s: %s", err,
                          shutdownFile)
コード例 #8
0
    def disconnectConfigService(self):
        if self._configService:
            try:
                self._configService.backend_exit()
            except Exception as exit_error:  # pylint: disable=broad-except
                logger.error("Failed to disconnect config service: %s",
                             exit_error)

        self._configService = None
コード例 #9
0
    def hidePopup(self):
        if self._popupNotificationServer:
            try:
                logger.info("Stopping popup message notification server")

                self._popupNotificationServer.stop(stopReactor=False)
            except Exception as err:  # pylint: disable=broad-except
                logger.error("Failed to stop popup notification server: %s",
                             err)
コード例 #10
0
    def setBlockLogin(self, blockLogin, handleNotifier=True):  # pylint: disable=too-many-branches
        blockLogin = forceBool(blockLogin)
        changed = self._blockLogin != blockLogin
        self._blockLogin = blockLogin
        logger.notice("Block login now set to '%s'", self._blockLogin)

        if self._blockLogin:
            if not self._blockLoginEventId:
                self._blockLoginEventId = timeline.addEvent(
                    title="Blocking login",
                    description="User login blocked",
                    category="block_login",
                    durationEvent=True)

            if not self._blockLoginNotifierPid and config.get(
                    'global', 'block_login_notifier'):
                if handleNotifier and RUNNING_ON_WINDOWS:
                    logger.info("Starting block login notifier app")
                    # Start block login notifier on physical console
                    sessionId = System.getActiveConsoleSessionId()
                    while True:
                        try:
                            self._blockLoginNotifierPid = System.runCommandInSession(
                                command=config.get('global',
                                                   'block_login_notifier'),
                                sessionId=sessionId,
                                desktop='winlogon',
                                waitForProcessEnding=False)[2]
                            break
                        except Exception as err:  # pylint: disable=broad-except
                            logger.error(
                                "Failed to start block login notifier app: %s",
                                err)
                            break
        else:
            if self._blockLoginEventId:
                timeline.setEventEnd(eventId=self._blockLoginEventId)
                self._blockLoginEventId = None

            if handleNotifier and self._blockLoginNotifierPid:
                try:
                    logger.info(
                        "Terminating block login notifier app (pid %s)",
                        self._blockLoginNotifierPid)
                    System.terminateProcess(
                        processId=self._blockLoginNotifierPid)
                except Exception as err:  # pylint: disable=broad-except
                    logger.warning(
                        "Failed to terminate block login notifier app: %s",
                        err)
                self._blockLoginNotifierPid = None

        if changed and self._controlPipe:
            try:
                self._controlPipe.executeRpc("blockLogin", self._blockLogin)
            except Exception as rpc_error:  # pylint: disable=broad-except
                logger.debug(rpc_error)
コード例 #11
0
    def self_update_from_file(self, filename):
        logger.notice("Self-update from file %s", filename)

        test_file = "base_library.zip"
        inst_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
        if not os.path.exists(os.path.join(inst_dir, test_file)):
            raise RuntimeError(
                f"File not found: {os.path.join(inst_dir, test_file)}")

        if self._selfUpdating:
            raise RuntimeError("Self-update already running")
        self._selfUpdating = True
        try:
            with tempfile.TemporaryDirectory() as tmpdir:
                destination = os.path.join(tmpdir, "content")
                shutil.unpack_archive(filename=filename,
                                      extract_dir=destination)

                bin_dir = destination
                if not os.path.exists(os.path.join(bin_dir, test_file)):
                    bin_dir = None
                    for fn in os.listdir(destination):
                        if os.path.exists(
                                os.path.join(destination, fn, test_file)):
                            bin_dir = os.path.join(destination, fn)
                            break
                if not bin_dir:
                    raise RuntimeError("Invalid archive")

                try:
                    check_signature(bin_dir)
                except Exception as err:  # pylint: disable=broad-except
                    logger.error("Could not verify signature!\n%s",
                                 err,
                                 exc_info=True)
                    logger.error("Not performing self_update.")
                    raise RuntimeError("Invalid signature") from err

                binary = os.path.join(bin_dir, os.path.basename(self._argv[0]))

                logger.info("Testing new binary: %s", binary)
                out = subprocess.check_output([binary, "--version"])
                logger.info(out)

                move_dir = inst_dir + "_old"
                logger.info("Moving current installation dir '%s' to '%s'",
                            inst_dir, move_dir)
                if os.path.exists(move_dir):
                    shutil.rmtree(move_dir)
                os.rename(inst_dir, move_dir)

                logger.info("Installing '%s' into '%s'", bin_dir, inst_dir)
                shutil.copytree(bin_dir, inst_dir)

                self.restart(3)
        finally:
            self._selfUpdating = False
コード例 #12
0
ファイル: Timeline.py プロジェクト: opsi-org/opsiclientd
 def start(self):
     db_file = config.get('global', 'timeline_db')
     logger.notice("Starting timeline (database location: %s)", db_file)
     try:
         self._createDatabase()
     except sqlite3.DatabaseError as err:
         logger.error(
             "Failed to connect to database %s: %s, recreating database",
             db_file, err)
         self._createDatabase(delete_existing=True)
     self._cleanupDatabase()
コード例 #13
0
ファイル: State.py プロジェクト: opsi-org/opsiclientd
    def _readStateFile(self):
        with self._stateLock:
            try:
                if os.path.exists(self._stateFile):
                    with codecs.open(self._stateFile, 'r',
                                     'utf8') as stateFile:
                        jsonstr = stateFile.read()

                    self._state = json.loads(jsonstr)
            except Exception as error:  # pylint: disable=broad-except
                logger.error("Failed to read state file '%s': %s",
                             self._stateFile, error)
コード例 #14
0
ファイル: Timeline.py プロジェクト: opsi-org/opsiclientd
 def _cleanupDatabase(self):
     with self._db_lock, self._sql.session() as session:
         try:
             self._sql.execute(
                 session,
                 f'delete from EVENT where `start` < "{timestamp(time.time() - 7*24*3600)}"'
             )
             self._sql.update(session, 'EVENT',
                              '`durationEvent` = 1 AND `end` is NULL',
                              {'durationEvent': False})
         except Exception as cleanup_error:  # pylint: disable=broad-except
             logger.error(cleanup_error)
コード例 #15
0
ファイル: State.py プロジェクト: opsi-org/opsiclientd
    def _writeStateFile(self):
        with self._stateLock:
            try:
                jsonstr = json.dumps(self._state)
                if not os.path.exists(os.path.dirname(self._stateFile)):
                    os.makedirs(os.path.dirname(self._stateFile))

                with codecs.open(self._stateFile, 'w', 'utf8') as stateFile:
                    stateFile.write(jsonstr)
            except Exception as error:  # pylint: disable=broad-except
                logger.error("Failed to write state file '%s': %s",
                             self._stateFile, error)
コード例 #16
0
 def suspendBitlocker(self):  # pylint: disable=no-self-use
     logger.notice("Suspending bitlocker for one reboot if active")
     try:
         System.execute(
             "powershell.exe -ExecutionPolicy Bypass -Command \""
             "foreach($v in Get-BitLockerVolume)"
             "{if ($v.EncryptionPercentage -gt 0)"
             "{$v | Suspend-BitLocker -RebootCount 1}}\"",
             captureStderr=True,
             waitForEnding=True,
             timeout=20)
     except Exception as err:  # pylint: disable=broad-except
         logger.error("Failed to suspend bitlocker: %s", err, exc_info=True)
コード例 #17
0
ファイル: service.py プロジェクト: opsi-org/opsiclientd
    def __init__(self, args):
        """
		Initialize service and create stop event
		"""
        self.opsiclientd = None
        try:
            logger.debug("OpsiclientdService initiating")
            win32serviceutil.ServiceFramework.__init__(self, args)
            self._stopEvent = win32event.CreateEvent(None, 0, 0, None)
            socket.setdefaulttimeout(60)
            logger.debug("OpsiclientdService initiated")
        except Exception as err:  # pylint: disable=broad-except
            logger.error(err, exc_info=True)
            raise
コード例 #18
0
ファイル: setup.py プロジェクト: opsi-org/opsiclientd
def setup(full=False, options=None) -> None:
    logger.notice("Running opsiclientd setup")
    errors = []

    if full:
        opsi_service_setup(options)
        try:
            install_service()
        except Exception as err:  # pylint: disable=broad-except
            logger.error("Failed to install service: %s", err, exc_info=True)
            errors.append(str(err))

    try:
        setup_ssl(full)
    except Exception as err:  # pylint: disable=broad-except
        logger.error("Failed to setup ssl: %s", err, exc_info=True)
        errors.append(str(err))

    try:
        setup_firewall()
    except Exception as err:  # pylint: disable=broad-except
        logger.error("Failed to setup firewall: %s", err, exc_info=True)
        errors.append(str(err))

    try:
        setup_on_shutdown()
    except Exception as err:  # pylint: disable=broad-except
        logger.error("Failed to setup on_shutdown: %s", err, exc_info=True)
        errors.append(str(err))

    logger.notice("Setup completed with %d errors", len(errors))
    if errors and full:
        raise RuntimeError(", ".join(errors))
コード例 #19
0
ファイル: Basic.py プロジェクト: opsi-org/opsiclientd
    def run(self):
        with opsicommon.logging.log_context(
            {'instance': f'event generator {self._generatorConfig.getId()}'}):
            try:
                logger.info("Initializing event generator '%s'", self)
                self.initialize()

                if self._generatorConfig.activationDelay > 0:
                    logger.debug(
                        "Waiting %d seconds before activation of event generator '%s'",
                        self._generatorConfig.activationDelay, self)
                    time.sleep(self._generatorConfig.activationDelay)

                logger.info("Activating event generator '%s'", self)
                while not self._stopped and (
                    (self._generatorConfig.maxRepetitions < 0) or
                    (self._eventsOccured <=
                     self._generatorConfig.maxRepetitions)):
                    logger.info("Getting next event...")
                    event = self.getNextEvent()  # pylint: disable=assignment-from-none,assignment-from-no-return
                    self._eventsOccured += 1  # Count as occured, even if event is None!
                    if event:
                        logger.info("Got new event: %s (%d/%d)", event,
                                    self._eventsOccured,
                                    self._generatorConfig.maxRepetitions + 1)
                        self.fireEvent(event)
                    for _unused in range(10):
                        if self._stopped:
                            break
                        time.sleep(1)
                if not self._stopped:
                    logger.notice(
                        "Event generator '%s' now deactivated after %d event occurrences",
                        self, self._eventsOccured)
            except Exception as err:  # pylint: disable=broad-except
                if not self._stopped:
                    logger.error("Failure in event generator '%s': %s",
                                 self,
                                 err,
                                 exc_info=True)
            try:
                self.cleanup()
            except Exception as err:  # pylint: disable=broad-except
                if not self._stopped:
                    logger.error("Failed to clean up: %s", err)

            logger.info("Event generator '%s' exiting ", self)
コード例 #20
0
ファイル: setup.py プロジェクト: opsi-org/opsiclientd
def opsi_service_setup(options=None):
    try:
        config.readConfigFile()
    except Exception as err:  # pylint: disable=broad-except
        logger.info(err)

    if os.path.exists(config.ca_cert_file):
        # Delete ca cert which could be invalid or expired
        os.remove(config.ca_cert_file)

    service_address = getattr(options, "service_address", None) or config.get(
        'config_service', 'url')[0]
    service_username = getattr(options, "service_username",
                               None) or config.get('global', 'host_id')
    service_password = getattr(options, "service_password",
                               None) or config.get('global', 'opsi_host_key')
    if getattr(options, "client_id", None):
        config.set('global', 'host_id', options.client_id)
    if not config.get('global', 'host_id'):
        fqdn = get_fqdn()
        fqdn = config.set('global', 'host_id', fqdn)

    secret_filter.add_secrets(service_password)

    logger.notice("Connecting to '%s' as '%s'", service_address,
                  service_username)
    jsonrpc_client = JSONRPCClient(address=service_address,
                                   username=service_username,
                                   password=service_password,
                                   verify_server_cert=False)

    try:
        update_ca_cert(jsonrpc_client, allow_remove=False)
    except Exception as err:  # pylint: disable=broad-except
        logger.error(err, exc_info=True)

    try:
        client = jsonrpc_client.host_getObjects(id=config.get(
            'global', 'host_id'))  # pylint: disable=no-member
        if client and client[0] and client[0].opsiHostKey:
            config.set('global', 'opsi_host_key', client[0].opsiHostKey)

        config.getFromService(jsonrpc_client)
        config.updateConfigFile(force=True)
    finally:
        jsonrpc_client.disconnect()
コード例 #21
0
ファイル: Basic.py プロジェクト: opsi-org/opsiclientd
 def run(self):
     with opsicommon.logging.log_context({
             'instance':
             'event generator ' + self._event.eventConfig.getId()
     }):
         if self._event.eventConfig.notificationDelay > 0:
             logger.debug(
                 "Waiting %d seconds before notifying listener '%s' of event '%s'",
                 self._event.eventConfig.notificationDelay,
                 self._eventListener, self._event)
             time.sleep(self._event.eventConfig.notificationDelay)
         try:
             logger.info("Calling processEvent on listener %s",
                         self._eventListener)
             self._eventListener.processEvent(self._event)
         except Exception as err:  # pylint: disable=broad-except
             logger.error(err, exc_info=True)
コード例 #22
0
ファイル: service.py プロジェクト: opsi-org/opsiclientd
 def ReportServiceStatus(self,
                         serviceStatus,
                         waitHint=5000,
                         win32ExitCode=0,
                         svcExitCode=0):  # pylint: disable=invalid-name
     # Wrapping because ReportServiceStatus sometimes lets windows
     # report a crash of opsiclientd (python 2.6.5) invalid handle
     try:
         logger.debug("Reporting service status: %s", serviceStatus)
         win32serviceutil.ServiceFramework.ReportServiceStatus(
             self,
             serviceStatus,
             waitHint=waitHint,
             win32ExitCode=win32ExitCode,
             svcExitCode=svcExitCode)
     except Exception as err:  # pylint: disable=broad-except
         logger.error("Failed to report service status %s: %s",
                      serviceStatus, err)
コード例 #23
0
ファイル: Timeline.py プロジェクト: opsi-org/opsiclientd
    def addEvent(self,
                 title,
                 description='',
                 isError=False,
                 category=None,
                 durationEvent=False,
                 start=None,
                 end=None):  # pylint: disable=too-many-arguments
        if self._stopped:
            return -1

        with self._db_lock, self._sql.session() as session:
            try:
                if category:
                    category = forceUnicode(category)
                if not start:
                    start = timestamp()
                start = forceOpsiTimestamp(start)

                if end:
                    end = forceOpsiTimestamp(end)
                    durationEvent = True

                event = {
                    'title': forceUnicode(title),
                    'category': category,
                    'description': forceUnicode(description),
                    'isError': forceBool(isError),
                    'durationEvent': forceBool(durationEvent),
                    'start': start,
                    'end': end,
                }
                try:
                    return self._sql.insert(session, 'EVENT', event)
                except sqlite3.DatabaseError as db_error:
                    logger.error(
                        "Failed to add event '%s': %s, recreating database",
                        title, db_error)
                    self._sql.delete_db()
                    self._createDatabase(delete_existing=True)
                    return self._sql.insert(session, 'EVENT', event)
            except Exception as add_error:  # pylint: disable=broad-except
                logger.error("Failed to add event '%s': %s", title, add_error)
        return -1
コード例 #24
0
ファイル: Timeline.py プロジェクト: opsi-org/opsiclientd
    def setEventEnd(self, eventId, end=None):
        if self._stopped:
            return -1

        with self._db_lock, self._sql.session() as session:
            try:
                eventId = forceInt(eventId)
                if not end:
                    end = timestamp()
                end = forceOpsiTimestamp(end)
                return self._sql.update(session, 'EVENT', f'`id` = {eventId}',
                                        {
                                            'end': end,
                                            'durationEvent': True
                                        })
            except Exception as end_error:  # pylint: disable=broad-except
                logger.error("Failed to set end of event '%s': %s", eventId,
                             end_error)
        return -1
コード例 #25
0
ファイル: ControlPipe.py プロジェクト: opsi-org/opsiclientd
    def executeRpc(self, method, params=None, with_lock=True):
        params = params or []
        with log_context({'instance': 'control pipe'}):
            rpc_id = 1
            if not self.clientInfo:
                return {
                    "id": rpc_id,
                    "error":
                    f"Cannot execute rpc, not supported by client {self}",
                    "result": None
                }

            request = {"id": rpc_id, "method": method, "params": params}
            try:
                if with_lock:
                    self.comLock.acquire()  # pylint: disable=consider-using-with
                try:
                    request_json = toJson(request)
                    logger.info("Sending request '%s' to client %s",
                                request_json, self)
                    self.write(request_json)
                    response_json = self.read()
                    if not response_json:
                        logger.warning(
                            "No response for method '%s' received from client %s",
                            request["method"], self)
                        return {"id": rpc_id, "error": None, "result": None}
                    logger.info("Received response '%s' from client %s",
                                response_json, self)
                    response = fromJson(response_json)
                    if method == "loginUser" and response.get("result"):
                        # Credential provider can only handle one successful login.
                        # Ensure, that the credential provider is not used for a
                        # second login if it keeps the pipe connection open.
                        self.login_capable = False
                    return response
                finally:
                    if with_lock:
                        self.comLock.release()
            except Exception as client_err:  # pylint: disable=broad-except
                logger.error(client_err, exc_info=True)
                return {"id": rpc_id, "error": str(client_err), "result": None}
コード例 #26
0
        def getDaemonLoopingContext():
            with getEventGeneratorContext():
                for event_generator in getEventGenerators(
                        generatorClass=DaemonStartupEventGenerator):
                    try:
                        event_generator.createAndFireEvent()
                    except ValueError as err:
                        logger.error(
                            "Unable to fire DaemonStartupEvent from %s: %s",
                            event_generator,
                            err,
                            exc_info=True)

                if getEventGenerators(generatorClass=GUIStartupEventGenerator):
                    # Wait until gui starts up
                    logger.notice(
                        "Waiting for gui startup (timeout: %d seconds)",
                        config.get('global', 'wait_for_gui_timeout'))
                    self.waitForGUI(
                        timeout=config.get('global', 'wait_for_gui_timeout'))
                    if not self.is_stopping():
                        logger.notice("Done waiting for GUI")
                        # Wait some more seconds for events to fire
                        time.sleep(5)

                try:
                    yield
                finally:
                    for event_generator in getEventGenerators(
                            generatorClass=DaemonShutdownEventGenerator):
                        logger.info(
                            "Create and fire shutdown event generator %s",
                            event_generator)
                        try:
                            event_generator.createAndFireEvent()
                        except ValueError as err:
                            logger.error(
                                "Unable to fire DaemonStartupEvent from %s: %s",
                                event_generator,
                                err,
                                exc_info=True)
コード例 #27
0
def start_pty(shell="powershell.exe", lines=30, columns=120):
    logger.notice("Starting %s (%d/%d)", shell, lines, columns)
    try:
        # Import of winpty may sometimes fail because of problems with the needed dll.
        # Therefore we do not import at toplevel
        from winpty import PtyProcess  # pylint: disable=import-error,import-outside-toplevel
    except ImportError as err:
        logger.error("Failed to start pty: %s", err, exc_info=True)
        raise
    process = PtyProcess.spawn(shell, dimensions=(lines, columns))

    def read(length: int):
        return process.read(length).encode("utf-8")

    def write(data: bytes):
        return process.write(data.decode("utf-8"))

    def stop():
        process.close()

    return (read, write, stop)
コード例 #28
0
 def getControlPipe():
     logger.notice("Starting control pipe")
     try:
         self._controlPipe = ControlPipeFactory(self)
         self._controlPipe.daemon = True
         self._controlPipe.start()
         logger.notice("Control pipe started")
         yield
     except Exception as err:  # pylint: disable=broad-except
         logger.error("Failed to start control pipe: %s",
                      err,
                      exc_info=True)
         raise
     finally:
         logger.info("Stopping control pipe")
         try:
             self._controlPipe.stop()
             self._controlPipe.join(2)
             logger.info("Control pipe stopped")
         except (NameError, RuntimeError) as stopError:
             logger.debug("Stopping controlPipe failed: %s", stopError)
コード例 #29
0
    def readConfigFile(self):
        ''' Get settings from config file '''
        logger.notice("Trying to read config from file: '%s'",
                      self.get('global', 'config_file'))

        try:
            self._config_file_mtime = os.path.getmtime(
                self.get('global', 'config_file'))
            # Read Config-File
            config = IniFile(filename=self.get('global', 'config_file'),
                             raw=True).parse()

            # Read log settings early
            if config.has_section('global') and config.has_option(
                    'global', 'log_level'):
                self.set('global', 'log_level',
                         config.get('global', 'log_level'))

            for section in config.sections():
                logger.debug("Processing section '%s' in config file: '%s'",
                             section, self.get('global', 'config_file'))

                for (option, value) in config.items(section):
                    option = option.lower()
                    self.set(section.lower(), option, value)
        except Exception as err:  # pylint: disable=broad-except
            # An error occured while trying to read the config file
            logger.error("Failed to read config file '%s': %s",
                         self.get('global', 'config_file'), err)
            logger.error(err, exc_info=True)
            return

        if not self.get("depot_server", "master_depot_id"):
            self.set("depot_server", "master_depot_id",
                     self.get("depot_server", "depot_id"))

        logger.notice("Config read")
        logger.debug("Config is now:\n %s",
                     objectToBeautifiedText(self._config))
コード例 #30
0
ファイル: __init__.py プロジェクト: opsi-org/opsiclientd
def init_logging(log_dir: str, stderr_level: int = LOG_NONE, log_filter: str = None):
	if not os.path.isdir(log_dir):
		log_dir = tempfile.gettempdir()
	log_file = os.path.join(log_dir, "opsiclientd.log")

	config.set("global", "log_file", log_file)

	log_file_without_ext, ext = os.path.splitext(log_file) # ext contains '.'

	for i in (9, 8, 7, 6, 5, 4, 3, 2, 1, 0):
		old_lf = f"{log_file_without_ext}{ext}.{i-1}" # old format
		new_lf = f"{log_file_without_ext}_{i}{ext}"
		if i > 0 and os.path.exists(old_lf):
			try:
				# Rename existing log file from old to new format
				os.rename(old_lf, new_lf)
			except Exception as err: # pylint: disable=broad-except
				logger.error("Failed to rename %s to %s: %s", old_lf, new_lf, err)

	logging_config(
		stderr_level=stderr_level,
		stderr_format=DEFAULT_STDERR_LOG_FORMAT,
		log_file=log_file,
		file_level=LOG_DEBUG,
		file_format=DEFAULT_FILE_LOG_FORMAT,
		file_rotate_max_bytes=config.get("global", "max_log_size")*1000*1000,
		file_rotate_backup_count=config.get("global", "keep_rotated_logs")
	)
	def namer(default_name):
		tmp = default_name.rsplit(".", 2)
		return f"{tmp[0]}_{int(tmp[2]) - 1}.{tmp[1]}"

	handler = get_all_handlers(handler_type=RotatingFileHandler)[0]
	handler.namer = namer
	handler.doRollover()
	if log_filter:
		set_filter_from_string(log_filter)

	logger.essential("Log file %s started", log_file)