def do_create(self, params=None): """ create database with role-assigment and tables """ if len(params) >= 1: db_name = params[0] else: db_name = cfg.read_param("database_name", "Please provide the database to create") logger.debug("db_name: '%s'", db_name) admin_url = self.get_admin_db_url(db_name) if not admin_url: return -1 admin_db = self.get_db(admin_url, db_name) if not admin_db: return -1 if self.create_db(db_name, admin_url, admin_db) < 0: return -1 db_url = self.get_db_url(db_name) if not db_url: return -1 if self.ensure_user(db_url, db_name, admin_db) < 0: return -1 if self.create_tables(db_name, db_url, admin_db) < 0: return -1 admin_db.destroy() return 0
def do_delete(self, params=None): if len(params) < 1: name = cfg.read_param( None, "Please provide the username you want to delete") if not name: logger.warning("no username to delete!") return -1 else: name = params[0] username, domain = self.user_get_domain(name) db = self.user_db_connect() delete_dict = {USER_NAME_COL: username, USER_DOMAIN_COL: domain} # check if the user already exists if not db.entry_exists(USER_TABLE, delete_dict): logger.warning("User {}@{} does not exist".format( username, domain)) return -1 db.delete(USER_TABLE, delete_dict) logger.debug( "User's {}@{} password has been been successfully deleted".format( username, domain)) db.destroy() return True
def parse_params(self, cmd, params): # first, we check to see if we have only named parameters nparams = self.get_params_set(params) if nparams is not None: logger.debug("named parameters are used") new_params = {} for p in params: s = p.split("=", 1) value = "" if len(s) == 1 else s[1] # check to see if we have to split them in array or not if cmd in MI_ARRAY_PARAMS_COMMANDS and \ MI_ARRAY_PARAMS_COMMANDS[cmd][1] == s[0]: new_params[s[0]] = shlex.split(value) else: new_params[s[0]] = value else: # old style positional parameters logger.debug("positional parameters are used") # if the command is not in MI_ARRAY_PARAMS_COMMANDS, return the # parameters as they are if not cmd in MI_ARRAY_PARAMS_COMMANDS: return params # build params based on their index new_params = params[0:MI_ARRAY_PARAMS_COMMANDS[cmd][0]] new_params.append(params[MI_ARRAY_PARAMS_COMMANDS[cmd][0]:]) return new_params
def create(self, db_name=None): """ create a database object """ if db_name is None: db_name = self.db_name # TODO: do this only for SQLAlchemy if not self.__conn: raise osdbError("connection not available") logger.debug("Create Database '%s' for dialect '%s' ...", self.db_name, self.dialect) # all good - it's time to create the database if self.dialect == "postgres": self.__conn.connection.connection.set_isolation_level(0) try: self.__conn.execute("CREATE DATABASE {}".format(self.db_name)) self.__conn.connection.connection.set_isolation_level(1) except sqlalchemy.exc.OperationalError as se: logger.error("cannot create database: {}!".format(se)) else: self.__conn.execute("CREATE DATABASE {}".format(self.db_name)) logger.debug("success") return True
def connect(self, db_name=None): """ connect to database """ if db_name is not None: self.db_name = db_name # TODO: do this only for SQLAlchemy try: if self.dialect == "postgres": self.db_url = self.set_url_db(self.db_url, self.db_name) if sqlalchemy_utils.database_exists(self.db_url) is True: engine = sqlalchemy.create_engine( self.db_url, isolation_level='AUTOCOMMIT') if self.__conn: self.__conn.close() self.__conn = engine.connect() # connect the Session object to our engine self.Session.configure(bind=self.__engine) # instanciate the Session object self.session = self.Session() logger.debug("connected to database URL '%s'", self.db_url) else: self.__conn.execute("USE {}".format(self.db_name)) except Exception as e: logger.error("failed to connect to %s", self.db_url) logger.error(e) return False return True
def run_command(self, module, cmd, params): """ run a module command with given parameters """ try: mod = self.modules[module] except (AttributeError, KeyError): if module in self.excluded_errs: for err_msg in self.excluded_errs[module]: logger.error(err_msg) return -1 else: logger.error("no module '{}' loaded".format(module)) return -1 # if the module does not return any methods (returned None) # we simply call the module's name method if not mod[1]: if params is not None: params.insert(0, cmd) cmd = mod[0].__module__ if cmd.startswith("opensipscli.modules."): cmd = cmd[20:] elif not cmd and '' not in mod[1]: logger.error( "module '{}' expects the following commands: {}".format( module, ", ".join(mod[1]))) return -1 elif cmd and not cmd in mod[1]: logger.error("no command '{}' in module '{}'".format(cmd, module)) return -1 logger.debug("running command '{}' '{}'".format(cmd, params)) return mod[0].__invoke__(cmd, params)
def valid(): opensips_fifo = cfg.get('fifo_file') if not os.path.exists(opensips_fifo): msg = "fifo file {} does not exist!".format(opensips_fifo) logger.debug(msg) return (False, [msg, 'Is OpenSIPS running?']) return (True, None)
def cmdloop(self, intro=None): """ command loop, catching SIGINT """ if self.execute: if len(self.command) < 1: logger.error("no modules to run specified!") return -1 if len(self.command) < 2: logger.debug("no method to in '{}' run specified!". format(self.command[0])) command = None params = None else: command = self.command[1] params = self.command[2:] logger.debug("running in non-interactive mode '{}'".format(self.command)) ret = self.run_command(self.command[0], command, params) # assume that by default it exists with success if ret is None: ret = 0 return ret while True: try: super(OpenSIPSCLIShell, self).cmdloop(intro='') break except KeyboardInterrupt: print('^C') # any other commands exits with negative value return -1
def get_admin_db_url(self, db_name): engine = osdb.get_db_engine() if not engine: return None if cfg.exists('database_admin_url'): admin_url = cfg.get("database_admin_url") if engine == "postgres": admin_url = osdb.set_url_db(admin_url, 'postgres') else: if engine == 'postgres': if getuser() != "postgres": logger.error("Command must be run as 'postgres' user: "******"sudo -u postgres opensips-cli ...") return None """ For PG, do the initial setup using 'postgres' as role + DB """ admin_url = "postgres://postgres@localhost/postgres" else: admin_url = "{}://root@localhost".format(engine) if osdb.get_url_pswd(admin_url) is None: pswd = getpass("Password for admin {} user ({}): ".format( osdb.get_url_driver(admin_url, capitalize=True), osdb.get_url_user(admin_url))) logger.debug("read password: '******'", pswd) admin_url = osdb.set_url_password(admin_url, pswd) logger.debug("admin DB URL: '{}'".format(admin_url)) return admin_url
def grant_db_options(self, role_name="opensips", role_options="ALL PRIVILEGES"): """ assign attibutes to a role object (PostgreSQL specific) """ # TODO: is any other dialect using the "role" concept? if self.dialect != "postgres": return False # TODO: do this only for SQLAlchemy if not self.__conn: raise osdbError("connection not available") return False logger.debug("Role '%s' will be granted with options '%s' on database '%s'", role_name, role_options, self.db_name) sqlcmd = "GRANT {} ON DATABASE {} TO {}".format(role_options, self.db_name, role_name) try: result = self.__conn.execute(sqlcmd) if result: logger.info("granted options '%s' to role '%s' on database '%s'", role_options, role_name, self.db_name) except: logger.error("granting options '%s' to role '%s' on database '%s' failed", role_options, role_name, self.db_name) return False return
def do_trap(self, params): self.pids = [] self.gdb_outputs = {} self.process_info = "" trap_file = cfg.get("trap_file") logger.info("Trapping {} in {}".format(PROCESS_NAME, trap_file)) if params and len(params) > 0: self.pids = params else: thread = Thread(target=self.get_pids) thread.start() thread.join(timeout=1) if len(self.pids) == 0: logger.warning("could not get OpenSIPS pids through MI!") try: ps_pids = subprocess.check_output(["pidof",PROCESS_NAME]) self.pids = ps_pids.decode().split() except: logger.warning("could not find any OpenSIPS running!") self.pids = [] if len(self.pids) < 1: logger.error("could not find OpenSIPS' pids") return -1 logger.debug("Dumping PIDs: {}".format(", ".join(self.pids))) threads = [] for pid in self.pids: thread = Thread(target=self.get_gdb_output, args=(pid,)) thread.start() threads.append(thread) for thread in threads: thread.join() if len(self.gdb_outputs) == 0: logger.error("could not get output of gdb") return -1 with open(trap_file, "w") as tf: tf.write(self.process_info) for pid in self.pids: if pid not in self.gdb_outputs: logger.warning("No output from pid {}".format(pid)) continue try: procinfo = subprocess.check_output( ["ps", "--no-headers", "-ww", "-fp", pid]).decode()[:-1] except: procinfo = "UNKNOWN" tf.write("\n\n---start {} ({})\n{}". format(pid, procinfo, self.gdb_outputs[pid])) print("Trap file: {}".format(trap_file))
def do_migrate(self, params): if len(params) < 3: print( "Usage: database migrate <flavour> <old-database> <new-database>" ) return 0 flavour = params[0].lower() old_db = params[1] new_db = params[2] if flavour not in DB_MIGRATIONS: logger.error("unsupported migration flavour: {}".format(flavour)) return -1 admin_url = self.get_admin_db_url(new_db) if not admin_url: return -1 db = self.get_db(admin_url, new_db) if not db: return -1 if db.dialect != "mysql": logger.error("'migrate' is only available for MySQL right now! :(") return -1 if not db.exists(old_db): logger.error( "the source database ({}) does not exist!".format(old_db)) return -2 print("Creating database {}...".format(new_db)) if self.create_db(new_db, admin_url, db) < 0: return -1 if self.create_tables(new_db, admin_url, db) < 0: return -1 backend = osdb.get_url_driver(admin_url) # obtain the DB schema files for the in-use backend schema_path = self.get_schema_path(backend) if schema_path is None: return -1 migrate_scripts = self.get_migrate_scripts_path(backend) if migrate_scripts is None: logger.debug("migration scripts for %s not found", backend) return -1 else: logger.debug("found migration scripts for %s", backend) logger.info("Migrating all matching OpenSIPS tables...") db.migrate( flavour.replace('.', '_').upper(), migrate_scripts, old_db, new_db, DB_MIGRATIONS[flavour]) db.destroy() return True
def update_instance(self, instance): # first of all, let's handle logging self.current_instance = instance self.update_logger() # Update the intro and prompt self.intro = cfg.get('prompt_intro') self.prompt = '(%s): ' % cfg.get('prompt_name') # initialize communcation handler self.handler = comm.initialize() # remove all loaded modules self.modules = {} if not self.execute: print(self.intro) # add the built-in modules and commands list for mod in ['clear', 'help', 'history', 'exit', 'quit']: self.modules[mod] = (self, None) if not cfg.exists('skip_modules'): skip_modules = [] else: skip_modules = cfg.get('skip_modules') available_modules = { key[20:]: sys.modules[key] for key in sys.modules.keys() if key.startswith("opensipscli.modules.") and key[20:] not in skip_modules } for name, module in available_modules.items(): m = importlib.import_module("opensipscli.modules.{}".format(name)) if not hasattr(m, "Module"): logger.debug( "Skipping module '{}' - does not extend Module".format( name)) continue if not hasattr(m, name): logger.debug( "Skipping module '{}' - module implementation not found". format(name)) continue mod = getattr(module, name) if not hasattr(mod, '__exclude__') or not hasattr( mod, '__get_methods__'): logger.debug( "Skipping module '{}' - module does not implement Module". format(name)) continue if mod.__exclude__(mod): logger.debug( "Skipping module '{}' - excluded on purpose".format(name)) continue logger.debug("Loaded module '{}'".format(name)) imod = mod() self.modules[name] = (imod, mod.__get_methods__(imod))
def migrate(self, migrate_scripts, old_db, new_db, tables=[]): if self.dialect != "mysql": logger.error("Table data migration is only supported for MySQL!") return """ migrate from source to destination database using SQL schema files """ self.connect(old_db) try: ret = self.find('mysql.proc', "count(*)", { 'db': old_db, 'name': 'OSIPS_DB_MIGRATE_2_4_TO_3_0' }) if ret and ret.first()[0] != 0: self.__conn.execute( sqlalchemy.sql.text( "DROP PROCEDURE IF EXISTS OSIPS_DB_MIGRATE_2_4_TO_3_0" ).execution_options(autocommit=True)) ret = self.find('mysql.proc', "count(*)", { 'db': old_db, 'name': 'OSIPS_TB_COPY_2_4_TO_3_0' }) if ret and ret.first()[0] != 0: self.__conn.execute( sqlalchemy.sql.text( "DROP PROCEDURE IF EXISTS OSIPS_TB_COPY_2_4_TO_3_0"). execution_options(autocommit=True)) except Exception as e: logger.exception(e) logger.error("Failed to re-create migration stored procedures!") for ms in migrate_scripts: logger.debug("Importing {}...".format(ms)) self.exec_sql_file(ms) if tables: for tb in tables: print("Migrating {} data... ".format(tb), end='') try: self.__conn.execute( sqlalchemy.sql.text( "CALL {}.OSIPS_TB_COPY_2_4_TO_3_0('{}', '{}', '{}')" .format(old_db, old_db, new_db, tb))) except Exception as e: logger.exception(e) logger.error( "Failed to migrate '{}' table data, ".format(tb) + "see above errors!") else: try: self.__conn.execute( sqlalchemy.sql.text( "CALL {}.OSIPS_DB_MIGRATE_2_4_TO_3_0('{}', '{}')". format(old_db, old_db, new_db))) except Exception as e: logger.exception(e) logger.error("Failed to migrate database!")
def preloop(self): history_file = cfg.get('history_file') if readline and os.path.exists(history_file): readline.read_history_file(history_file) logger.debug("using history file {}".format(history_file)) readline.set_history_length(int(cfg.get('history_file_size'))) if not self.registered_atexit: atexit.register(self.history_write)
def history_write(self): """ save history file """ history_file = cfg.get('history_file') logger.debug("saving history in {}".format(history_file)) os.makedirs(os.path.expanduser(os.path.dirname(history_file)), exist_ok=True) readline.write_history_file(os.path.expanduser(history_file))
def migrate(self, proc_suffix, migrate_scripts, old_db, new_db, tables=[]): """ migrate from source to destination database using SQL schema files @flavour: values should resemble: '2.4_to_3.0', '3.0_to_3.1' @sp_suffix: stored procedure name suffix, specific to each migration """ if self.dialect != "mysql": logger.error("Table data migration is only supported for MySQL!") return proc_db_migrate = 'OSIPS_DB_MIGRATE_{}'.format(proc_suffix) proc_tb_migrate = 'OSIPS_TB_COPY_{}'.format(proc_suffix) self.connect(old_db) # separately drop DB/table migration stored procedures if already # present, since there are issues with multiple statements in 1 import try: self.__conn.execute( sqlalchemy.sql.text("DROP PROCEDURE IF EXISTS {}".format( proc_db_migrate)).execution_options(autocommit=True)) self.__conn.execute( sqlalchemy.sql.text("DROP PROCEDURE IF EXISTS {}".format( proc_tb_migrate)).execution_options(autocommit=True)) except: logger.exception("Failed to drop migration stored procedures!") for ms in migrate_scripts: logger.debug("Importing {}...".format(ms)) self.exec_sql_file(ms) if tables: for tb in tables: logger.info("Migrating {} data... ".format(tb)) try: self.__conn.execute( sqlalchemy.sql.text( "CALL {}.{}('{}', '{}', '{}')".format( old_db, proc_tb_migrate, old_db, new_db, tb))) except Exception as e: logger.exception(e) logger.error( "Failed to migrate '{}' table data, ".format(tb) + "see above errors!") else: try: self.__conn.execute( sqlalchemy.sql.text("CALL {}.{}('{}', '{}')".format( old_db, proc_db_migrate, old_db, new_db))) except Exception as e: logger.exception(e) logger.error("Failed to migrate database!") print("Finished copying OpenSIPS table data " + "into database '{}'!".format(new_db))
def get_db_url(self, db_name=cfg.get('database_name')): engine = osdb.get_db_engine() if not engine: return None # make sure to inherit the 'database_admin_url' engine db_url = osdb.set_url_driver(cfg.get("database_url"), engine) logger.debug("DB URL: '{}'".format(db_url)) return db_url
def preloop(self): history_file = cfg.get('history_file') logger.debug("using history file {}".format(history_file)) try: readline.read_history_file(os.path.expanduser(history_file)) except FileNotFoundError: pass readline.set_history_length(int(cfg.get('history_file_size'))) if not self.registered_atexit: atexit.register(self.history_write)
def do_migrate(self, params): if len(params) < 2: print("Usage: database migrate <old-database> <new-database>") return 0 old_db = params[0] new_db = params[1] db_url = self.ask_db_url() if db_url is None: return -1 # create an object store database instance db = self.get_db(db_url, old_db) if db is None: return -1 if not db.exists(old_db): logger.error( "the source database ({}) does not exist!".format(old_db)) return -2 print("Creating database {}...".format(new_db)) if self._do_create_db([new_db], db_url=db_url) < 0: return -1 if self.create_tables(new_db, db_url=db_url) < 0: return -1 # get schema path for active database dialect db_schema = db.db_url.split(":")[0] schema_path = self.get_schema_path(db_schema) if schema_path is None: return -1 # get schema scripts for active database dialect db_schema = db.db_url.split(":")[0] migrate_scripts = self.get_migrate_scripts_path(db_schema) if migrate_scripts is None: logger.debug("migration scripts for db_schema '%s' not found", db_schema) return -1 else: logger.debug("migration scripts for db_schema: '%s'", migrate_scripts) print("Migrating all matching OpenSIPS tables...") db.migrate(migrate_scripts, old_db, new_db, MIGRATE_TABLES_24_TO_30) print("Finished copying OpenSIPS table data " + "into database '{}'!".format(new_db)) db.destroy() return True
def migrate(self, migrate_scripts, old_db, new_db): self.use(old_db) for ms in migrate_scripts: logger.debug("Importing {}...".format(ms)) self.exec_sql_file(ms) self.__conn.execute( sqlalchemy.sql.text( "CALL {}.OSIPS_DB_MIGRATE_2_4_TO_3_0('{}', '{}')".format( old_db, old_db, new_db)).execution_options(autocommit=True))
def do_migrate(self, params): if len(params) < 2: print("Usage: database migrate <old-database> <new-database>") return 0 old_db = params[0] new_db = params[1] admin_url = self.get_admin_db_url(new_db) if not admin_url: return -1 db = self.get_db(admin_url, new_db) if not db: return -1 if db.dialect != "mysql": logger.error("'migrate' is only available for MySQL right now! :(") return -1 if not db.exists(old_db): logger.error( "the source database ({}) does not exist!".format(old_db)) return -2 print("Creating database {}...".format(new_db)) if self.create_db(new_db, admin_url, db) < 0: return -1 if self.create_tables(new_db, db, admin_url) < 0: return -1 backend = osdb.get_url_driver(admin_url) # obtain the DB schema files for the in-use backend schema_path = self.get_schema_path(backend) if schema_path is None: return -1 migrate_scripts = self.get_migrate_scripts_path(backend) if migrate_scripts is None: logger.debug("migration scripts for %s not found", backend) return -1 else: logger.debug("migration scripts for %s", migrate_scripts) print("Migrating all matching OpenSIPS tables...") db.migrate(migrate_scripts, old_db, new_db, MIGRATE_TABLES_24_TO_30) print("Finished copying OpenSIPS table data " + "into database '{}'!".format(new_db)) db.destroy() return True
def history_write(self): """ save history file """ history_file = cfg.get('history_file') logger.debug("saving history in {}".format(history_file)) os.makedirs(os.path.expanduser(os.path.dirname(history_file)), exist_ok=True) try: readline.write_history_file(os.path.expanduser(history_file)) except PermissionError: logger.warning("failed to write CLI history to {} " + "(no permission)".format(history_file))
def do_create_module(self, module_name): """ create database table for given module """ db_url = cfg.read_param( "database_url", "Please provide the URL to connect to the database") if db_url is None: print() logger.error("no URL specified: aborting!") return -1 db_name = cfg.read_param("database_name", "Please provide the database name", DEFAULT_DB_NAME) if db_name is None: logger.error("no URL specified: aborting!") return -1 # create an object store database instance db = self.get_db(db_url, db_name) if db is None: return -1 # connect to the database db.connect(db_name) # create table from schema-file for given module name module = ' '.join(module_name) logger.debug("module_name: '%s'", module) #re.sub('\ |\[|\'|\]', '', module) #module_name.strip('[']') db_schema = db_url.split(":")[0] schema_path = self.get_schema_path(db_schema) if schema_path is None: return -1 module_schema_file = os.path.join(schema_path, "{}-create.sql".format(module)) try: db.create_module(module_schema_file) logger.info( "database tables for module '%s' has been successfully created.", module_name) except osdbError as ex: logger.error("cannot import: {}".format(ex)) # terminate active database connection db.destroy() return True
def exists_role(self, role_name=None): """ check for existence of a role object (PostgreSQL specific) """ # TODO: is any other dialect using the "role" concept? if self.dialect != "postgres": return False # TODO: do this only for SQLAlchemy if not self.__conn: raise osdbError("connection not available") return False if role_name is None: role_name = 'opensips' filter_args = {'rolname': role_name} logger.debug("filter argument: '%s'", filter_args) role_count = self.__session.query(Roles).\ filter_by(**filter_args).\ count() logger.debug("Number of matching role instances: '%s'", role_count) if role_count >= 1: logger.debug("Role instance '%s' exists", role_name) return True else: logger.debug("Role instance '%s' does not exist", role_name) return False
def __init__(self, db_url, db_name): """ constructor """ self.db_url = db_url self.db_name = db_name self.dialect = osdb.get_dialect(db_url) self.Session = sessionmaker() self.__engine = None self.__conn = None # TODO: do this only for SQLAlchemy try: if self.dialect == "postgresql": self.__engine = sqlalchemy.create_engine(db_url, isolation_level='AUTOCOMMIT') else: self.__engine = sqlalchemy.create_engine(db_url) logger.debug("connecting to %s", db_url) self.__conn = self.__engine.connect().\ execution_options(autocommit=True) # connect the Session object to our engine self.Session.configure(bind=self.__engine) # instanciate the Session object self.__session = self.Session() except sqlalchemy.exc.OperationalError as se: if self.dialect == "mysql": try: if int(se.args[0].split(",")[0].split("(")[2]) in [ 2006, # MySQL 1044, # MariaDB 1045, # MariaDB ]: raise osdbAccessDeniedError except osdbAccessDeniedError: raise except: logger.error("unexpected parsing exception") elif self.dialect == "postgres" and \ (("authentication" in se.args[0] and "failed" in se.args[0]) or \ ("no password supplied" in se.args[0])): raise osdbAccessDeniedError raise osdbError("unable to connect to the database") except sqlalchemy.exc.NoSuchModuleError: raise osdbError("cannot handle {} dialect". format(self.dialect)) except sqlalchemy.exc.ArgumentError: raise osdbArgumentError("bad DB URL: {}".format( self.db_url))
def drop(self): """ drop a database object """ # TODO: do this only for SQLAlchemy if not self.__conn: raise osdbError("connection not available") database_url = self.set_url_db(self.db_url, self.db_name) try: sqlalchemy_utils.drop_database(database_url) logger.debug("database '%s' dropped", self.db_name) return True except sqlalchemy.exc.NoSuchModuleError as me: logger.error("cannot check if database {} exists: {}". format(self.db_name, me)) raise osdbError("cannot handle {} dialect". format(self.dialect)) from None
def get_gdb_output(self, pid): if os.path.islink("/proc/{}/exe".format(pid)): # get process line of pid process = os.readlink("/proc/{}/exe".format(pid)) else: logger.error("could not find OpenSIPS process {} running on local machine".format(pid)) return -1 # Check if process is opensips (can be different if CLI is running on another host) path, filename = os.path.split(process) if filename != PROCESS_NAME: logger.error("process ID {} is not OpenSIPS process".format(pid)) return -1 logger.debug("Dumping backtrace for {} pid {}".format(process, pid)) cmd = ["gdb", process, pid, "-batch", "--eval-command", "bt full"] out = subprocess.check_output(cmd) if len(out) != 0: self.gdb_outputs[pid] = out.decode()
def preloop(self): """ preload a history file """ history_file = cfg.get('history_file') logger.debug("using history file {}".format(history_file)) try: readline.read_history_file(os.path.expanduser(history_file)) except PermissionError: logger.warning("failed to read CLI history from {} " + "(no permission)".format(history_file)) except FileNotFoundError: pass readline.set_history_length(int(cfg.get('history_file_size'))) if not self.registered_atexit: atexit.register(self.history_write)
def __init__(self, options): """ contructor for OpenSIPS-Cli """ self.debug = options.debug self.execute = options.execute self.command = options.command self.modules_dir_inserted = None if self.debug: logger.setLevel("DEBUG") if not options.config: cfg_file = None for f in defaults.CFG_PATHS: if os.path.isfile(f) and os.access(f, os.R_OK): # found a valid config file cfg_file = f break else: cfg_file = options.config if not cfg_file: logger.debug("no config file found in any of {}".format(", ".join( defaults.CFG_PATHS))) else: logger.debug("using config file {}".format(cfg_file)) # __init__ of the configuration file cfg.parse(cfg_file) if not cfg.has_instance(options.instance): logger.warning( "Unknown instance '{}'! Using default instance '{}'!".format( options.instance, defaults.DEFAULT_SECTION)) instance = defaults.DEFAULT_SECTION else: instance = options.instance cfg.set_instance(instance) cfg.set_custom_options(options.extra_options) if not self.execute: # __init__ of cmd.Cmd module cmd.Cmd.__init__(self) # Opening the current working instance self.update_instance(cfg.current_instance)