示例#1
0
def checkIfMultipleCallsSucceed():
    be = JSONRPCBackend(address='192.168.105.1',
                        username='******',
                        password='******')
    first = be.backend_info()
    second = be.backend_info()
    third = be.backend_info()

    assert first == second
    assert second == third
示例#2
0
    def _getDepotConnection(self, depotId):
        depotId = forceHostId(depotId)
        if depotId == self._depotId:
            return self

        try:
            return self._depotConnections[depotId]
        except KeyError:
            if not self._opsiHostKey:
                depots = self._context.host_getObjects(id=self._depotId)  # pylint: disable=maybe-no-member
                if not depots or not depots[0].getOpsiHostKey():
                    raise BackendMissingDataError(
                        u"Failed to get opsi host key for depot '{0}'".format(
                            self._depotId))
                self._opsiHostKey = depots[0].getOpsiHostKey()

            try:
                self._depotConnections[depotId] = JSONRPCBackend(
                    address=u'https://%s:4447/rpc/backend/dhcpd' % (depotId),
                    username=self._depotId,
                    password=self._opsiHostKey)
            except Exception as error:
                raise BackendUnableToConnectError(
                    u"Failed to connect to depot '%s': %s" % (depotId, error))

            return self._depotConnections[depotId]
示例#3
0
 def _getExternalBackendConnection(self,
                                   address,
                                   username,
                                   password,
                                   port=4447):
     try:
         return JSONRPCBackend(address=u'https://%s:%s/rpc/backend/%s' %
                               (address, port, self._name),
                               username=username,
                               password=password)
     except Exception as error:
         raise BackendUnableToConnectError(
             u"Failed to connect to depot '%s': %s" % (address, error))
示例#4
0
    def run(self):  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        with log_context({'instance': 'service connection'}):
            logger.debug("ServiceConnectionThread started...")
            self.running = True
            self.connected = False
            self.cancelled = False

            try:  # pylint: disable=too-many-nested-blocks
                verify_server_cert = (
                    config.get('global', 'verify_server_cert')
                    or config.get('global', 'verify_server_cert_by_ca'))
                ca_cert_file = config.ca_cert_file
                self.prepare_ca_cert_file()

                compression = config.get('config_service', 'compression')
                if "localhost" in self._configServiceUrl or "127.0.0.1" in self._configServiceUrl:
                    compression = False
                    verify_server_cert = False

                if verify_server_cert:
                    if os.path.exists(ca_cert_file):
                        logger.info(
                            "Server verification enabled, using CA cert file '%s'",
                            ca_cert_file)
                    else:
                        logger.error(
                            "Server verification enabled, but CA cert file '%s' not found, skipping verification",
                            ca_cert_file)
                        ca_cert_file = None
                        verify_server_cert = False

                tryNum = 0
                while not self.cancelled and not self.connected:
                    tryNum += 1
                    try:
                        logger.notice("Connecting to config server '%s' #%d",
                                      self._configServiceUrl, tryNum)
                        self.setStatusMessage(
                            _("Connecting to config server '%s' #%d") %
                            (self._configServiceUrl, tryNum))
                        if len(self._username.split('.')) < 3:
                            raise Exception(
                                f"Domain missing in username '{self._username}'"
                            )

                        logger.debug(
                            "JSONRPCBackend address=%s, verify_server_cert=%s, ca_cert_file=%s, proxy_url=%s, application=%s",
                            self._configServiceUrl, verify_server_cert,
                            ca_cert_file, config.get('global', 'proxy_url'),
                            f"opsiclientd/{__version__}")

                        self.configService = JSONRPCBackend(
                            address=self._configServiceUrl,
                            username=self._username,
                            password=self._password,
                            verify_server_cert=verify_server_cert,
                            ca_cert_file=ca_cert_file,
                            proxy_url=config.get('global', 'proxy_url'),
                            application=f"opsiclientd/{__version__}",
                            compression=compression,
                            ip_version=config.get('global', 'ip_version'))
                        self.configService.accessControl_authenticated()  # pylint: disable=no-member
                        self.connected = True
                        self.connectionError = None
                        serverVersion = self.configService.serverVersion
                        self.setStatusMessage(
                            _("Connected to config server '%s'") %
                            self._configServiceUrl)
                        logger.notice(
                            "Connected to config server '%s' (name=%s, version=%s)",
                            self._configServiceUrl,
                            self.configService.serverName, serverVersion)

                        if serverVersion and (serverVersion[0] > 4 or
                                              (serverVersion[0] == 4
                                               and serverVersion[1] > 1)):
                            if not os.path.exists(
                                    config.ca_cert_file
                            ) or verify_server_cert or config.get(
                                    'global', 'install_opsi_ca_into_os_store'):
                                # Renew CA if not exists or connection is verified
                                try:
                                    update_ca_cert(self.configService,
                                                   allow_remove=True)
                                except Exception as err:  # pylint: disable=broad-except
                                    logger.error(err, exc_info=True)
                    except OpsiServiceVerificationError as verificationError:
                        self.connectionError = forceUnicode(verificationError)
                        self.setStatusMessage(
                            _("Failed to connect to config server '%s': Service verification failure"
                              ) % self._configServiceUrl)
                        logger.error(
                            "Failed to connect to config server '%s': %s",
                            self._configServiceUrl, verificationError)
                        break
                    except Exception as error:  # pylint: disable=broad-except
                        self.connectionError = forceUnicode(error)
                        self.setStatusMessage(
                            _("Failed to connect to config server '%s': %s") %
                            (self._configServiceUrl, forceUnicode(error)))
                        logger.info(
                            "Failed to connect to config server '%s': %s",
                            self._configServiceUrl, error)
                        logger.debug(error, exc_info=True)

                        if isinstance(error, OpsiAuthenticationError):
                            fqdn = System.getFQDN()
                            try:
                                fqdn = forceFqdn(fqdn)
                            except Exception as fqdnError:  # pylint: disable=broad-except
                                logger.warning(
                                    "Failed to get fqdn from os, got '%s': %s",
                                    fqdn, fqdnError)
                                break

                            if self._username != fqdn:
                                logger.notice(
                                    "Connect failed with username '%s', got fqdn '%s' from os, trying fqdn",
                                    self._username, fqdn)
                                self._username = fqdn
                            else:
                                break

                        if 'is not supported by the backend' in self.connectionError.lower(
                        ):
                            try:
                                from cryptography.hazmat.backends import default_backend  # pylint: disable=import-outside-toplevel
                                logger.debug(
                                    "Got the following crypto backends: %s",
                                    default_backend()._backends)  # pylint: disable=no-member,protected-access
                            except Exception as cryptoCheckError:  # pylint: disable=broad-except
                                logger.debug(
                                    "Failed to get info about installed crypto modules: %s",
                                    cryptoCheckError)

                        for _unused in range(
                                3):  # Sleeping before the next retry
                            time.sleep(1)
            except Exception as err:  # pylint: disable=broad-except
                logger.error(err, exc_info=True)
            finally:
                self.running = False
示例#5
0
class ServiceConnectionThread(KillableThread):  # pylint: disable=too-many-instance-attributes
    def __init__(self,
                 configServiceUrl,
                 username,
                 password,
                 statusSubject=None):
        KillableThread.__init__(self)
        self._configServiceUrl = configServiceUrl
        self._username = username
        self._password = password
        self._statusSubject = statusSubject
        self.configService = None
        self.running = False
        self.connected = False
        self.cancelled = False
        self.connectionError = None
        if not self._configServiceUrl:
            raise Exception("No config service url given")

    def setStatusMessage(self, message):
        if not self._statusSubject:
            return
        self._statusSubject.setMessage(message)

    def getUsername(self):
        return self._username

    def prepare_ca_cert_file(self):  # pylint: disable=no-self-use
        certs = ""
        if os.path.exists(config.ca_cert_file):
            # Read all certs from file except UIB_OPSI_CA
            uib_opsi_ca_cert = load_certificate(FILETYPE_PEM,
                                                UIB_OPSI_CA.encode("ascii"))
            with open(config.ca_cert_file, "r", encoding="utf-8") as file:
                for match in re.finditer(
                        r"(-+BEGIN CERTIFICATE-+.*?-+END CERTIFICATE-+)",
                        file.read(), re.DOTALL):
                    cert = load_certificate(FILETYPE_PEM,
                                            match.group(1).encode("ascii"))
                    if cert.get_subject().CN != uib_opsi_ca_cert.get_subject(
                    ).CN:
                        certs += dump_certificate(FILETYPE_PEM,
                                                  cert).decode("ascii")
        if not certs:
            if os.path.exists(config.ca_cert_file):
                # Accept all server certs on the next connection attempt
                os.remove(config.ca_cert_file)
            return

        if config.get('global', 'trust_uib_opsi_ca'):
            certs += UIB_OPSI_CA

        with open(config.ca_cert_file, "w", encoding="utf-8") as file:
            file.write(certs)

    def run(self):  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        with log_context({'instance': 'service connection'}):
            logger.debug("ServiceConnectionThread started...")
            self.running = True
            self.connected = False
            self.cancelled = False

            try:  # pylint: disable=too-many-nested-blocks
                verify_server_cert = (
                    config.get('global', 'verify_server_cert')
                    or config.get('global', 'verify_server_cert_by_ca'))
                ca_cert_file = config.ca_cert_file
                self.prepare_ca_cert_file()

                compression = config.get('config_service', 'compression')
                if "localhost" in self._configServiceUrl or "127.0.0.1" in self._configServiceUrl:
                    compression = False
                    verify_server_cert = False

                if verify_server_cert:
                    if os.path.exists(ca_cert_file):
                        logger.info(
                            "Server verification enabled, using CA cert file '%s'",
                            ca_cert_file)
                    else:
                        logger.error(
                            "Server verification enabled, but CA cert file '%s' not found, skipping verification",
                            ca_cert_file)
                        ca_cert_file = None
                        verify_server_cert = False

                tryNum = 0
                while not self.cancelled and not self.connected:
                    tryNum += 1
                    try:
                        logger.notice("Connecting to config server '%s' #%d",
                                      self._configServiceUrl, tryNum)
                        self.setStatusMessage(
                            _("Connecting to config server '%s' #%d") %
                            (self._configServiceUrl, tryNum))
                        if len(self._username.split('.')) < 3:
                            raise Exception(
                                f"Domain missing in username '{self._username}'"
                            )

                        logger.debug(
                            "JSONRPCBackend address=%s, verify_server_cert=%s, ca_cert_file=%s, proxy_url=%s, application=%s",
                            self._configServiceUrl, verify_server_cert,
                            ca_cert_file, config.get('global', 'proxy_url'),
                            f"opsiclientd/{__version__}")

                        self.configService = JSONRPCBackend(
                            address=self._configServiceUrl,
                            username=self._username,
                            password=self._password,
                            verify_server_cert=verify_server_cert,
                            ca_cert_file=ca_cert_file,
                            proxy_url=config.get('global', 'proxy_url'),
                            application=f"opsiclientd/{__version__}",
                            compression=compression,
                            ip_version=config.get('global', 'ip_version'))
                        self.configService.accessControl_authenticated()  # pylint: disable=no-member
                        self.connected = True
                        self.connectionError = None
                        serverVersion = self.configService.serverVersion
                        self.setStatusMessage(
                            _("Connected to config server '%s'") %
                            self._configServiceUrl)
                        logger.notice(
                            "Connected to config server '%s' (name=%s, version=%s)",
                            self._configServiceUrl,
                            self.configService.serverName, serverVersion)

                        if serverVersion and (serverVersion[0] > 4 or
                                              (serverVersion[0] == 4
                                               and serverVersion[1] > 1)):
                            if not os.path.exists(
                                    config.ca_cert_file
                            ) or verify_server_cert or config.get(
                                    'global', 'install_opsi_ca_into_os_store'):
                                # Renew CA if not exists or connection is verified
                                try:
                                    update_ca_cert(self.configService,
                                                   allow_remove=True)
                                except Exception as err:  # pylint: disable=broad-except
                                    logger.error(err, exc_info=True)
                    except OpsiServiceVerificationError as verificationError:
                        self.connectionError = forceUnicode(verificationError)
                        self.setStatusMessage(
                            _("Failed to connect to config server '%s': Service verification failure"
                              ) % self._configServiceUrl)
                        logger.error(
                            "Failed to connect to config server '%s': %s",
                            self._configServiceUrl, verificationError)
                        break
                    except Exception as error:  # pylint: disable=broad-except
                        self.connectionError = forceUnicode(error)
                        self.setStatusMessage(
                            _("Failed to connect to config server '%s': %s") %
                            (self._configServiceUrl, forceUnicode(error)))
                        logger.info(
                            "Failed to connect to config server '%s': %s",
                            self._configServiceUrl, error)
                        logger.debug(error, exc_info=True)

                        if isinstance(error, OpsiAuthenticationError):
                            fqdn = System.getFQDN()
                            try:
                                fqdn = forceFqdn(fqdn)
                            except Exception as fqdnError:  # pylint: disable=broad-except
                                logger.warning(
                                    "Failed to get fqdn from os, got '%s': %s",
                                    fqdn, fqdnError)
                                break

                            if self._username != fqdn:
                                logger.notice(
                                    "Connect failed with username '%s', got fqdn '%s' from os, trying fqdn",
                                    self._username, fqdn)
                                self._username = fqdn
                            else:
                                break

                        if 'is not supported by the backend' in self.connectionError.lower(
                        ):
                            try:
                                from cryptography.hazmat.backends import default_backend  # pylint: disable=import-outside-toplevel
                                logger.debug(
                                    "Got the following crypto backends: %s",
                                    default_backend()._backends)  # pylint: disable=no-member,protected-access
                            except Exception as cryptoCheckError:  # pylint: disable=broad-except
                                logger.debug(
                                    "Failed to get info about installed crypto modules: %s",
                                    cryptoCheckError)

                        for _unused in range(
                                3):  # Sleeping before the next retry
                            time.sleep(1)
            except Exception as err:  # pylint: disable=broad-except
                logger.error(err, exc_info=True)
            finally:
                self.running = False

    def stopConnectionCallback(self, choiceSubject):  # pylint: disable=unused-argument
        logger.notice("Connection cancelled by user")
        self.stop()

    def stop(self):
        logger.debug("Stopping thread")
        self.cancelled = True
        self.running = False
        for _unused in range(10):
            if not self.is_alive():
                break
            self.terminate()
            time.sleep(0.5)
示例#6
0
def main(argv):
	if os.path.exists(os.path.join('C:', 'opsi.org', 'log')):
		logDir = os.path.join('C:', 'opsi.org', 'log')
	else:
		logDir = os.path.join('C:', 'tmp')

	logFile = os.path.join(logDir, 'hwaudit.log')

	parser = argparse.ArgumentParser(
		description="Perform hardware audit on a client and sent the result to an opsi server.",
		add_help=False
	)
	parser.add_argument('--help', action="store_true", help="Display help.")
	parser.add_argument('--version', action='version', version=__version__)
	parser.add_argument(
		'--log-level', '--loglevel', '-l', default=LOG_ERROR,
		dest="logLevel", type=int, choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
		help="Set the desired loglevel."
	)
	parser.add_argument('--log-file', '-f', dest="logFile", default=logFile, help="Path to file where debug logs will be written.")
	parser.add_argument('--hostid', '-h', help="Hostid that will be used. If nothing is set the value from --username will be used.")
	parser.add_argument('--username', '-u', help="Username to connect to the service. If nothing is set the value from --hostid will be used.")
	parser.add_argument('--password', '-p', required=True, help="Password for authentication")
	parser.add_argument('--address', '-a', required=True, help="Address to connect to. Example: https://server.domain.local:4447")

	opts = parser.parse_args()

	if opts.help:
		parser.print_help()
		sys.exit(0)

	password = opts.password

	logger.addConfidentialString(password)
	logger.setConsoleLevel(opts.logLevel)
	logger.setLogFile(opts.logFile)
	logger.setFileLevel(LOG_DEBUG2)

	logger.notice("starting hardware audit (script version {})", __version__)

	address = opts.address
	if address.startswith(u"https://"):
		address = address + u"/rpc"

	if not address:
		logger.critical(u"Address not set")
		raise RuntimeError("Address not set")

	host_id = opts.hostid or opts.username
	username = opts.username or opts.hostid

	if not (username and host_id):
		raise RuntimeError("Host id and username not set")

	logger.notice(u"Connecting to service at '{}' as '{}'", address, username)

	backendConfig = dict(
		username=username,
		password=password,
		address=address,
		application='opsi hwaudit %s' % __version__
	)

	with JSONRPCBackend(**backendConfig) as backend:
		logger.notice(u"Connected to opsi server")

		logger.notice(u"Fetching opsi hw audit configuration")
		config = backend.auditHardware_getConfig()

		logger.notice(u"Fetching hardware information from WMI")
		values = getHardwareInformationFromWMI(config)

		logger.notice(u"Fetching hardware information from Registry")
		values = getHardwareInformationFromRegistry(config, values)

		logger.notice(u"Fetching hardware information from Executing Command")
		values = getHardwareInformationFromExecuteCommand(config, values)

		logger.info(u"Hardware information from WMI:\n%s" % objectToBeautifiedText(values))
		auditHardwareOnHosts = []
		for hardwareClass, devices in values.items():
			if hardwareClass == 'SCANPROPERTIES':
				continue

			for device in devices:
				data = {str(attribute): value for attribute, value in device.items()}
				data['hardwareClass'] = hardwareClass
				data['hostId'] = host_id

				auditHardwareOnHosts.append(AuditHardwareOnHost.fromHash(data))

		logger.info(u"Obsoleting old hardware audit data")
		backend.auditHardwareOnHost_setObsolete(host_id)
		logger.notice(u"Sending hardware information to service")
		backend.auditHardwareOnHost_updateObjects(auditHardwareOnHosts)

	logger.notice(u"Exiting...")
def testCreatinBackendWithCompression(compressionOptions, expectedCompression):
    backend = JSONRPCBackend("localhost",
                             connectoninit=False,
                             **compressionOptions)

    assert backend.isCompressionUsed() == expectedCompression
def jsonRpcBackend():
    yield JSONRPCBackend("localhost", connectoninit=False)
def testParsingCompressionValue(value, expectedResult):
    assert JSONRPCBackend._parseCompressionValue(value) == expectedResult
示例#10
0
def checkAsynchronosProcessing():
    be = JSONRPCBackend(address='192.168.1.14',
                        username='******',
                        password='******')
    assert be.authenticated()

    def callback(jsonrpc):
        print(jsonrpc.result)

    class Thread(threading.Thread):
        def __init__(self, be):
            threading.Thread.__init__(self)
            self.be = be

        def run(self):
            for i in range(5):
                be.authenticated().setCallback(callback)
                time.sleep(0.3)

    be = JSONRPCBackend(address='192.168.1.14',
                        username='******',
                        password='******',
                        deflate=True,
                        connectionPoolSize=30)

    be.setAsync(True)

    threads = [Thread(be) for i in range(20)]
    [t.start() for t in threads]
    [t.join() for t in threads]

    runs = 0
    while runs < 10:
        print(be.authenticated())
        print(be.group_getIdents())
        print(be.host_getIdents())
        time.sleep(2)
        runs += 1

    be.setAsync(True)

    #jsonrpc1 = JSONRPC(jsonrpcBackend = be, baseUrl = be._baseUrl, method = 'authenticated', params = [], retry = False)
    be.authenticated().setCallback(callback)
    #jsonrpc2 = JSONRPC(jsonrpcBackend = be, baseUrl = be._baseUrl, method = 'group_getIdents', params = [], retry = False)
    be.group_getIdents().setCallback(callback)
    #jsonrpc3 = JSONRPC(jsonrpcBackend = be, baseUrl = be._baseUrl, method = 'host_getIdents', params = [], retry = False)
    be.host_getIdents().setCallback(callback)
    be.host_getIdents().setCallback(callback)
    be.host_getIdents().setCallback(callback)
    be.host_getIdents().setCallback(callback)
    be.host_getIdents().setCallback(callback)

    be.setAsync(False)
    print("===", be.host_getIdents())

    be.backend_exit()
示例#11
0
def checkIfConnectionWithCertWorks():
    be = JSONRPCBackend(address='192.168.1.14',
                        username='******',
                        password='******',
                        serverCertFile='/tmp/server-cert.pem',
                        verifyServerCert=True)
def main():  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
    if len(sys.argv) != 17:
        print(
            f"Usage: {os.path.basename(sys.argv[0])} <hostId> <hostKey> <controlServerPort>"
            " <logFile> <logLevel> <depotRemoteUrl> <depotDrive> <depotServerUsername> <depotServerPassword>"
            " <sessionId> <actionProcessorDesktop> <actionProcessorCommand> <actionProcessorTimeout>"
            " <runAsUser> <runAsPassword> <createEnvironment>")
        sys.exit(1)

    (  # pylint: disable=unbalanced-tuple-unpacking
        hostId, hostKey, controlServerPort, logFile, logLevel, depotRemoteUrl,
        depotDrive, depotServerUsername, depotServerPassword, sessionId,
        actionProcessorDesktop, actionProcessorCommand, actionProcessorTimeout,
        runAsUser, runAsPassword, createEnvironment) = sys.argv[1:]

    if hostKey:
        secret_filter.add_secrets(hostKey)
    if depotServerPassword:
        secret_filter.add_secrets(depotServerPassword)
    if runAsPassword:
        secret_filter.add_secrets(runAsPassword)

    init_logging(stderr_level=LOG_NONE,
                 stderr_format=DEFAULT_STDERR_LOG_FORMAT,
                 log_file=logFile,
                 file_level=int(logLevel),
                 file_format=DEFAULT_FILE_LOG_FORMAT)

    log_instance = f'{os.path.basename(sys.argv[0]).rsplit(".", 1)[0]}_s{sessionId}'
    with log_context({'instance': log_instance}):
        logger.debug(
            "Called with arguments: %s", ', '.join(
                (hostId, hostKey, controlServerPort, logFile, logLevel,
                 depotRemoteUrl, depotDrive, depotServerUsername,
                 depotServerPassword, sessionId, actionProcessorDesktop,
                 actionProcessorCommand, actionProcessorTimeout, runAsUser,
                 runAsPassword, createEnvironment)))

        language = "en"
        try:
            language = locale.getdefaultlocale()[0].split('_')[0]
        except Exception as err:  # pylint: disable=broad-except
            logger.debug("Failed to find default language: %s", err)

        def _(string):
            """ Fallback function """
            return string

        sp = None
        try:
            logger.debug("Loading translation for language '%s'", language)
            sp = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            if os.path.exists(os.path.join(sp, "site-packages")):
                sp = os.path.join(sp, "site-packages")
            sp = os.path.join(sp, 'opsiclientd_data', 'locale')
            translation = gettext.translation('opsiclientd', sp, [language])
            _ = translation.gettext
        except Exception as err:  # pylint: disable=broad-except
            logger.debug("Failed to load locale for %s from %s: %s", language,
                         sp, err)

        createEnvironment = bool(
            runAsUser and createEnvironment.lower() in ('yes', 'true', '1'))
        actionProcessorTimeout = int(actionProcessorTimeout)
        imp = None
        depotShareMounted = False
        be = None
        depot_url = urlparse(depotRemoteUrl)

        try:
            be = JSONRPCBackend(
                username=hostId,
                password=hostKey,
                address=f"https://127.0.0.1:{controlServerPort}/opsiclientd")

            if runAsUser:
                if getpass.getuser().lower() != runAsUser.lower():
                    logger.info("Impersonating user '%s'", runAsUser)
                    imp = System.Impersonate(username=runAsUser,
                                             password=runAsPassword,
                                             desktop=actionProcessorDesktop)
                    imp.start(logonType="INTERACTIVE",
                              newDesktop=False,
                              createEnvironment=createEnvironment)
            elif depot_url.scheme in ("smb", "cifs"):
                logger.info("Impersonating network account '%s'",
                            depotServerUsername)
                imp = System.Impersonate(username=depotServerUsername,
                                         password=depotServerPassword,
                                         desktop=actionProcessorDesktop)
                imp.start(logonType="NEW_CREDENTIALS")

            if depot_url.hostname.lower() not in ("127.0.0.1", "localhost",
                                                  "::1"):
                logger.notice("Mounting depot share %s", depotRemoteUrl)
                set_status_message(be, sessionId,
                                   _("Mounting depot share %s") %
                                   depotRemoteUrl)  # pylint: disable=no-member

                if runAsUser or depot_url.scheme not in ("smb", "cifs"):
                    System.mount(depotRemoteUrl,
                                 depotDrive,
                                 username=depotServerUsername,
                                 password=depotServerPassword)
                else:
                    System.mount(depotRemoteUrl, depotDrive)
                depotShareMounted = True

            logger.notice("Starting action processor")
            set_status_message(be, sessionId, _("Action processor is running"))  # pylint: disable=no-member

            if imp:
                imp.runCommand(actionProcessorCommand,
                               timeoutSeconds=actionProcessorTimeout)
            else:
                System.execute(actionProcessorCommand,
                               waitForEnding=True,
                               timeout=actionProcessorTimeout)

            logger.notice("Action processor ended")
            set_status_message(be, sessionId, _("Action processor ended"))  # pylint: disable=no-member
        except Exception as err:  # pylint: disable=broad-except
            logger.error(err, exc_info=True)
            error = f"Failed to process action requests: {err}"
            logger.error(error)
            if be:
                set_status_message(be, sessionId, error)

        if depotShareMounted:
            try:
                logger.notice("Unmounting depot share")
                System.umount(depotDrive)
            except Exception:  # pylint: disable=broad-except
                pass
        if imp:
            try:
                imp.end()
            except Exception:  # pylint: disable=broad-except
                pass

        if be:
            try:
                be.backend_exit()
            except Exception:  # pylint: disable=broad-except
                pass