def __init__(self, parent=None): QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint) self._cfg = Config.get() self._nodes = Nodes.instance() self._db = Database.instance() self._notification_callback.connect(self._cb_notification_callback) self._notifications_sent = {} self.setupUi(self) self.dbFileButton.setVisible(False) self.dbLabel.setVisible(False) self.acceptButton.clicked.connect(self._cb_accept_button_clicked) self.applyButton.clicked.connect(self._cb_apply_button_clicked) self.cancelButton.clicked.connect(self._cb_cancel_button_clicked) self.popupsCheck.clicked.connect(self._cb_popups_check_toggled) self.dbFileButton.clicked.connect(self._cb_file_db_clicked) if QtGui.QIcon.hasThemeIcon("emblem-default") == False: self.applyButton.setIcon(self.style().standardIcon( getattr(QtWidgets.QStyle, "SP_DialogApplyButton"))) self.cancelButton.setIcon(self.style().standardIcon( getattr(QtWidgets.QStyle, "SP_DialogCloseButton"))) self.acceptButton.setIcon(self.style().standardIcon( getattr(QtWidgets.QStyle, "SP_DialogSaveButton"))) self.dbFileButton.setIcon(self.style().standardIcon( getattr(QtWidgets.QStyle, "SP_DirOpenIcon")))
def __init__(self, app, on_exit): super(UIService, self).__init__() self.MENU_ENTRY_STATS = QtCore.QCoreApplication.translate("contextual_menu", "Statistics") self.MENU_ENTRY_FW_ENABLE = QtCore.QCoreApplication.translate("contextual_menu", "Enable") self.MENU_ENTRY_FW_DISABLE = QtCore.QCoreApplication.translate("contextual_menu", "Disable") self.MENU_ENTRY_HELP = QtCore.QCoreApplication.translate("contextual_menu", "Help") self.MENU_ENTRY_CLOSE = QtCore.QCoreApplication.translate("contextual_menu", "Close") self._cfg = Config.init() self._db = Database.instance() db_file=self._cfg.getSettings(self._cfg.DEFAULT_DB_FILE_KEY) db_status, db_error = self._db.initialize( dbtype=self._cfg.getInt(self._cfg.DEFAULT_DB_TYPE_KEY), dbfile=db_file ) if db_status is False: Message.ok( QtCore.QCoreApplication.translate("preferences", "Warning"), QtCore.QCoreApplication.translate("preferences", "The DB is corrupted and it's not safe to continue.<br>\ Remove, backup or recover the file before continuing.<br><br>\ Corrupted database file: {0}".format(db_file)), QtWidgets.QMessageBox.Warning) sys.exit(-1) self._db_sqlite = self._db.get_db() self._last_ping = None self._version_warning_shown = False self._asking = False self._connected = False self._fw_enabled = False self._path = os.path.abspath(os.path.dirname(__file__)) self._app = app self._on_exit = on_exit self._exit = False self._msg = QtWidgets.QMessageBox() self._prompt_dialog = PromptDialog() self._remote_lock = Lock() self._remote_stats = {} self._setup_interfaces() self._setup_icons() self._stats_dialog = StatsDialog(dbname="general", db=self._db) self._setup_tray() self._setup_slots() self._nodes = Nodes.instance() self._last_stats = {} self._last_items = { 'hosts':{}, 'procs':{}, 'addrs':{}, 'ports':{}, 'users':{} }
def __init__(self, parent=None): QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint) # Other interesting flags: QtCore.Qt.Tool | QtCore.Qt.BypassWindowManagerHint self._cfg = Config.get() self.setupUi(self) self._width = self.width() self._height = self.height() dialog_geometry = self._cfg.getSettings("promptDialog/geometry") if dialog_geometry == QtCore.QByteArray: self.restoreGeometry(dialog_geometry) self.setWindowTitle("OpenSnitch v%s" % version) self._lock = threading.Lock() self._con = None self._rule = None self._local = True self._peer = None self._prompt_trigger.connect(self.on_connection_prompt_triggered) self._timeout_trigger.connect(self.on_timeout_triggered) self._tick_trigger.connect(self.on_tick_triggered) self._tick = int(self._cfg.getSettings( self._cfg.DEFAULT_TIMEOUT_KEY)) if self._cfg.hasKey( self._cfg.DEFAULT_TIMEOUT_KEY) else self.DEFAULT_TIMEOUT self._tick_thread = None self._done = threading.Event() self._timeout_text = "" self._timeout_triggered = False self._apps_parser = LinuxDesktopParser() self.denyButton.clicked.connect(self._on_deny_clicked) # also accept button self.applyButton.clicked.connect(self._on_apply_clicked) self._apply_text = QC.translate("popups", "Allow") self._deny_text = QC.translate("popups", "Deny") self._default_action = self._cfg.getInt(self._cfg.DEFAULT_ACTION_KEY) self.whatIPCombo.setVisible(False) self.checkDstIP.setVisible(False) self.checkDstPort.setVisible(False) self.checkUserID.setVisible(False) self.appDescriptionLabel.setVisible(False) self._ischeckAdvanceded = False self.checkAdvanced.toggled.connect(self._check_advanced_toggled) if QtGui.QIcon.hasThemeIcon("emblem-default") == False: self.applyButton.setIcon(self.style().standardIcon( getattr(QtWidgets.QStyle, "SP_DialogApplyButton"))) self.denyButton.setIcon(self.style().standardIcon( getattr(QtWidgets.QStyle, "SP_DialogCancelButton")))
def __init__(self, parent=None, appicon=None): QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint) self._themes = Themes.instance() self._saved_theme = "" self._cfg = Config.get() self._nodes = Nodes.instance() self._db = Database.instance() self._notification_callback.connect(self._cb_notification_callback) self._notifications_sent = {} self._desktop_notifications = DesktopNotifications() self.setupUi(self) self.setWindowIcon(appicon) self.dbFileButton.setVisible(False) self.dbLabel.setVisible(False) self.dbType = None self.acceptButton.clicked.connect(self._cb_accept_button_clicked) self.applyButton.clicked.connect(self._cb_apply_button_clicked) self.cancelButton.clicked.connect(self._cb_cancel_button_clicked) self.helpButton.clicked.connect(self._cb_help_button_clicked) self.popupsCheck.clicked.connect(self._cb_popups_check_toggled) self.dbFileButton.clicked.connect(self._cb_file_db_clicked) self.checkUIRules.toggled.connect(self._cb_check_ui_rules_toggled) self.cmdTimeoutUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.SUM)) self.cmdTimeoutDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.REST)) self.cmdDBMaxDaysUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.SUM)) self.cmdDBMaxDaysDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.REST)) self.cmdDBPurgesUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBPurgeInterval, self.SUM)) self.cmdDBPurgesDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBPurgeInterval, self.REST)) self.cmdTestNotifs.clicked.connect(self._cb_test_notifs_clicked) self.radioSysNotifs.clicked.connect(self._cb_radio_system_notifications) self.helpButton.setToolTipDuration(30 * 1000) if QtGui.QIcon.hasThemeIcon("emblem-default") == False: self.applyButton.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_DialogApplyButton"))) self.cancelButton.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_DialogCloseButton"))) self.acceptButton.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_DialogSaveButton"))) self.dbFileButton.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_DirOpenIcon"))) if QtGui.QIcon.hasThemeIcon("list-add") == False: self.cmdTimeoutUp.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_ArrowUp"))) self.cmdTimeoutDown.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_ArrowDown"))) self.cmdDBMaxDaysUp.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_ArrowUp"))) self.cmdDBMaxDaysDown.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_ArrowDown"))) self.cmdDBPurgesUp.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_ArrowUp"))) self.cmdDBPurgesDown.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_ArrowDown")))
def __init__(self, app, on_exit): super(UIService, self).__init__() self.MENU_ENTRY_STATS = QtCore.QCoreApplication.translate( "contextual_menu", "Statistics") self.MENU_ENTRY_FW_ENABLE = QtCore.QCoreApplication.translate( "contextual_menu", "Enable") self.MENU_ENTRY_FW_DISABLE = QtCore.QCoreApplication.translate( "contextual_menu", "Disable") self.MENU_ENTRY_HELP = QtCore.QCoreApplication.translate( "contextual_menu", "Help") self.MENU_ENTRY_CLOSE = QtCore.QCoreApplication.translate( "contextual_menu", "Close") self._cfg = Config.init() self._db = Database.instance() self._db.initialize( dbtype=self._cfg.getInt(self._cfg.DEFAULT_DB_TYPE_KEY), dbfile=self._cfg.getSettings(self._cfg.DEFAULT_DB_FILE_KEY)) self._db_sqlite = self._db.get_db() self._last_ping = None self._version_warning_shown = False self._asking = False self._connected = False self._fw_enabled = False self._path = os.path.abspath(os.path.dirname(__file__)) self._app = app self._on_exit = on_exit self._exit = False self._msg = QtWidgets.QMessageBox() self._prompt_dialog = PromptDialog() self._remote_lock = Lock() self._remote_stats = {} self._setup_interfaces() self._setup_icons() self._stats_dialog = StatsDialog(dbname="general", db=self._db) self._setup_tray() self._setup_slots() self._nodes = Nodes.instance() self._last_stats = {} self._last_items = { 'hosts': {}, 'procs': {}, 'addrs': {}, 'ports': {}, 'users': {} }
def __init__(self, _interval, _callback): Thread.__init__(self, name="cleaner_db_thread") self.interval = _interval * 60 self.stop_flag = Event() self.callback = _callback self._cfg = Config.init() # We need to instantiate a new QsqlDatabase object with a unique name, # because it's not thread safe: # "A connection can only be used from within the thread that created it." # https://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module # The filename and type is the same, the one chosen by the user. self.db = Database("db-cleaner-connection") self.db_status, db_error = self.db.initialize( dbtype=self._cfg.getInt(self._cfg.DEFAULT_DB_TYPE_KEY), dbfile=self._cfg.getSettings(self._cfg.DEFAULT_DB_FILE_KEY))
def __init__(self, parent=None, appicon=None, node=None): QtWidgets.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowIcon(appicon) self.appicon = appicon # TODO: profiles are ready to be used. They need to be tested, and # create some default profiles (home, office, public, ...) self.comboProfile.setVisible(False) self.lblProfile.setVisible(False) self.secHighIcon = Icons.new("security-high") self.secMediumIcon = Icons.new("security-medium") self.secLowIcon = Icons.new("security-low") self.lblStatusIcon.setPixmap(self.secHighIcon.pixmap(96, 96)) self._fwrule_dialog = FwRuleDialog(appicon=self.appicon) self._cfg = Config.get() self._fw = Fw.Firewall.instance() self._nodes = Nodes.instance() self._fw_profiles = {} self._notification_callback.connect(self._cb_notification_callback) self._notifications_sent = {} self._nodes.nodesUpdated.connect(self._cb_nodes_updated) self.cmdNewRule.clicked.connect(self._cb_new_rule_clicked) self.cmdExcludeService.clicked.connect( self._cb_exclude_service_clicked) self.comboInput.currentIndexChanged.connect( lambda: self._cb_combo_policy_changed(self.COMBO_IN)) self.comboOutput.currentIndexChanged.connect( lambda: self._cb_combo_policy_changed(self.COMBO_OUT)) self.comboProfile.currentIndexChanged.connect( self._cb_combo_profile_changed) self.sliderFwEnable.valueChanged.connect(self._cb_enable_fw_changed) self.cmdClose.clicked.connect(self._cb_close_clicked) if QtGui.QIcon.hasThemeIcon("document-new"): return closeIcon = Icons.new("window-close") excludeIcon = Icons.new("go-jump") newIcon = Icons.new("document-new") self.cmdClose.setIcon(closeIcon) self.cmdExcludeService.setIcon(excludeIcon) self.cmdNewRule.setIcon(newIcon)
def __init__(self, parent=None, appicon=None): QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint) # Other interesting flags: QtCore.Qt.Tool | QtCore.Qt.BypassWindowManagerHint self._cfg = Config.get() self.setupUi(self) self.setWindowIcon(appicon) self._width = None self._height = None dialog_geometry = self._cfg.getSettings("promptDialog/geometry") if dialog_geometry == QtCore.QByteArray: self.restoreGeometry(dialog_geometry) self.setWindowTitle("OpenSnitch v%s" % version) self._lock = threading.Lock() self._con = None self._rule = None self._local = True self._peer = None self._prompt_trigger.connect(self.on_connection_prompt_triggered) self._timeout_trigger.connect(self.on_timeout_triggered) self._tick_trigger.connect(self.on_tick_triggered) self._tick = int(self._cfg.getSettings( self._cfg.DEFAULT_TIMEOUT_KEY)) if self._cfg.hasKey( self._cfg.DEFAULT_TIMEOUT_KEY) else self.DEFAULT_TIMEOUT self._tick_thread = None self._done = threading.Event() self._timeout_text = "" self._timeout_triggered = False self._apps_parser = LinuxDesktopParser() self.whatIPCombo.setVisible(False) self.checkDstIP.setVisible(False) self.checkDstPort.setVisible(False) self.checkUserID.setVisible(False) self.appDescriptionLabel.setVisible(False) self._ischeckAdvanceded = False self.checkAdvanced.toggled.connect(self._check_advanced_toggled) self.checkAdvanced.clicked.connect(self._button_clicked) self.durationCombo.activated.connect(self._button_clicked) self.whatCombo.activated.connect(self._button_clicked) self.whatIPCombo.activated.connect(self._button_clicked) self.checkDstIP.clicked.connect(self._button_clicked) self.checkDstPort.clicked.connect(self._button_clicked) self.checkUserID.clicked.connect(self._button_clicked) self.allowIcon = Icons.new("emblem-default") denyIcon = Icons.new("emblem-important") rejectIcon = Icons.new("window-close") self._default_action = self._cfg.getInt(self._cfg.DEFAULT_ACTION_KEY) self.allowButton.clicked.connect( lambda: self._on_action_clicked(Config.ACTION_ALLOW_IDX)) self.allowButton.setIcon(self.allowIcon) self._allow_text = QC.translate("popups", "Allow") self._action_text = [ QC.translate("popups", "Deny"), QC.translate("popups", "Allow"), QC.translate("popups", "Reject") ] self._action_icon = [denyIcon, self.allowIcon, rejectIcon] m = QtWidgets.QMenu() m.addAction( denyIcon, self._action_text[Config.ACTION_DENY_IDX]).triggered.connect( lambda: self._on_action_clicked(Config.ACTION_DENY_IDX)) m.addAction( self.allowIcon, self._action_text[Config.ACTION_ALLOW_IDX]).triggered.connect( lambda: self._on_action_clicked(Config.ACTION_ALLOW_IDX)) m.addAction( rejectIcon, self._action_text[Config.ACTION_REJECT_IDX]).triggered.connect( lambda: self._on_action_clicked(Config.ACTION_REJECT_IDX)) self.actionButton.setMenu(m) self.actionButton.setText(self._action_text[Config.ACTION_DENY_IDX]) self.actionButton.setIcon(self._action_icon[Config.ACTION_DENY_IDX]) if self._default_action != Config.ACTION_ALLOW_IDX: self.actionButton.setText(self._action_text[self._default_action]) self.actionButton.setIcon(self._action_icon[self._default_action]) self.actionButton.clicked.connect(self._on_deny_btn_clicked)
def __init__(self, parent=None, appicon=None): QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint) self._themes = Themes.instance() self._saved_theme = "" self._cfg = Config.get() self._nodes = Nodes.instance() self._db = Database.instance() self._notification_callback.connect(self._cb_notification_callback) self._notifications_sent = {} self._desktop_notifications = DesktopNotifications() self.setupUi(self) self.setWindowIcon(appicon) self.dbFileButton.setVisible(False) self.dbLabel.setVisible(False) self.dbType = None self.acceptButton.clicked.connect(self._cb_accept_button_clicked) self.applyButton.clicked.connect(self._cb_apply_button_clicked) self.cancelButton.clicked.connect(self._cb_cancel_button_clicked) self.helpButton.clicked.connect(self._cb_help_button_clicked) self.popupsCheck.clicked.connect(self._cb_popups_check_toggled) self.dbFileButton.clicked.connect(self._cb_file_db_clicked) self.checkUIRules.toggled.connect(self._cb_check_ui_rules_toggled) self.cmdTimeoutUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.SUM)) self.cmdTimeoutDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.REST)) self.cmdDBMaxDaysUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.SUM)) self.cmdDBMaxDaysDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.REST)) self.cmdDBPurgesUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBPurgeInterval, self.SUM)) self.cmdDBPurgesDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBPurgeInterval, self.REST)) self.cmdTestNotifs.clicked.connect(self._cb_test_notifs_clicked) self.radioSysNotifs.clicked.connect(self._cb_radio_system_notifications) self.helpButton.setToolTipDuration(30 * 1000) if QtGui.QIcon.hasThemeIcon("emblem-default"): return saveIcon = Icons.new("document-save") applyIcon = Icons.new("emblem-default") delIcon = Icons.new("edit-delete") closeIcon = Icons.new("window-close") openIcon = Icons.new("document-open") helpIcon = Icons.new("help-browser") addIcon = Icons.new("list-add") delIcon = Icons.new("list-remove") self.applyButton.setIcon(applyIcon) self.cancelButton.setIcon(closeIcon) self.acceptButton.setIcon(saveIcon) self.helpButton.setIcon(helpIcon) self.dbFileButton.setIcon(openIcon) self.cmdTimeoutUp.setIcon(addIcon) self.cmdTimeoutDown.setIcon(delIcon) self.cmdDBMaxDaysUp.setIcon(addIcon) self.cmdDBMaxDaysDown.setIcon(delIcon) self.cmdDBPurgesUp.setIcon(addIcon) self.cmdDBPurgesDown.setIcon(delIcon)
def __init__(self): self._cfg = Config.get() theme = self._cfg.getInt(self._cfg.DEFAULT_THEME, 0)
class DesktopNotifications(): """DesktopNotifications display informative pop-ups using the system D-Bus. The notifications are handled and configured by the system. The notification daemon also decides where to show the notifications, as well as how to group them. The body of a notification supports markup (if the implementation supports it): https://people.gnome.org/~mccann/docs/notification-spec/notification-spec-latest.html#markup Basically: <a>, <u>, <b>, <i> and <img>. New lines can be added with the regular \n. It also support actions (buttons). https://notify2.readthedocs.io/en/latest/ """ _cfg = Config.init() # list of hints: # https://people.gnome.org/~mccann/docs/notification-spec/notification-spec-latest.html#hints HINT_DESKTOP_ENTRY = "desktop-entry" CATEGORY_NETWORK = "network" EXPIRES_DEFAULT = 0 NEVER_EXPIRES = -1 def __init__(self): self.ACTION_ALLOW = QC.translate("popups", "Allow") self.ACTION_DENY = QC.translate("popups", "Deny") self.IS_LIBNOTIFY_AVAILABLE = True self.DOES_SUPPORT_ACTIONS = True try: import notify2 self.ntf2 = notify2 mloop = 'glib' # First try to initialise the D-Bus connection with the given # mainloop. # If it fails, we'll try to initialise it without it. try: self.ntf2.init("opensnitch", mainloop=mloop) except Exception: self.DOES_SUPPORT_ACTIONS = False # usually because dbus mainloop is not initiated, specially # with 'qt' # FIXME: figure out how to init it, or how to connect to an # existing session. print( "DesktopNotifications(): system doesn't support actions. Available capabilities:" ) print(self.ntf2.get_server_caps()) self.ntf2.init("opensnitch") # Example: ['actions', 'action-icons', 'body', 'body-markup', 'icon-static', 'persistence', 'sound'] if ('actions' not in self.ntf2.get_server_caps()): self.DOES_SUPPORT_ACTIONS = False except Exception as e: print( "DesktopNotifications not available (install python3-notify2):", e) self.IS_LIBNOTIFY_AVAILABLE = False def is_available(self): return self.IS_LIBNOTIFY_AVAILABLE def are_enabled(self): return self._cfg.getBool(Config.NOTIFICATIONS_ENABLED, True) def support_actions(self): """Returns true if the notifications daemon support actions(buttons). This depends on 2 factors: - If the notification server actually supports it (get_server_caps()). - If there's a dbus instance running. """ return self.DOES_SUPPORT_ACTIONS def show(self, title, body, icon="dialog-information"): try: ntf = self.ntf2.Notification(title, body, icon) # timeouts seems to be ignored (on Cinnamon at least) timeout = self._cfg.getInt(Config.DEFAULT_TIMEOUT_KEY, 15) # -1 and 0 are special values if timeout > 0: timeout = timeout * 1000 ntf.set_timeout(timeout * 1000) ntf.timeout = timeout * 1000 ntf.set_category(self.CATEGORY_NETWORK) # used to display our app icon an name. ntf.set_hint(self.HINT_DESKTOP_ENTRY, "opensnitch_ui") ntf.show() except Exception as e: print("[notifications] show() exception:", e) # TODO: # - construct a rule with the default configured parameters. # - create a common dialogs/prompt.py:_send_rule(), maybe in utils.py def ask(self, connection, timeout, callback): c = connection title = QC.translate("popups", "New outgoing connection") body = c.process_path + "\n" body = body + QC.translate("popups", "is connecting to <b>%s</b> on %s port %d") % ( \ c.dst_host or c.dst_ip, c.protocol.upper(), c.dst_port ) ntf = self.ntf2.Notification(title, body, "dialog-warning") timeout = self._cfg.getInt(Config.DEFAULT_TIMEOUT_KEY, 15) ntf.set_timeout(timeout * 1000) ntf.timeout = timeout * 1000 if self.DOES_SUPPORT_ACTIONS: ntf.set_urgency(self.ntf2.URGENCY_CRITICAL) ntf.add_action("allow", self.ACTION_ALLOW, callback, connection) ntf.add_action("deny", self.ACTION_DENY, callback, connection) #ntf.add_action("open-gui", QC.translate("popups", "View"), callback, connection) ntf.set_category(self.CATEGORY_NETWORK) ntf.set_hint(self.HINT_DESKTOP_ENTRY, "opensnitch_ui") ntf.show()
"Firewall": "iptables", "Stats": { "MaxEvents": 150, "MaxStats": 50 } } ''' class Connection: protocol = "tcp" src_ip = "127.0.0.1" src_port = "12345" dst_ip = "127.0.0.1" dst_host = "localhost" dst_port = "54321" user_id = 1000 process_id = 9876 process_path = "/bin/cmd" process_cwd = "/tmp" process_args = "/bin/cmd --parm1 test" process_env = [] db = Database.instance() db.initialize() Config.init() nodes = Nodes.instance() nodes._nodes["unix:/tmp/osui.sock"] = {'data': ClientConfig}