def upgrade_db(self): """ Call C{specturm --check-db-version} to see if the schema version of the database is up to date. If not, call C{spectrum --upgrade-db} and try to upgrade the schema. @raise RuntimeError: If any of the launched commands fail. """ path = os.path.abspath(self.config_path) # fork and drop privileges: pid = os.fork() if pid: # we are the parent! pid, status = os.waitpid(pid, 0) status = (status & 0xff00) >> 8 if status == 0: return elif status == 1: raise RuntimeError("db_version table does not exist", 1) elif status == 3: raise RuntimeError("Error connecting to the database", 1) elif status == 100: raise RuntimeError("Could not find spectrum binary", 1) elif status == 101: raise RuntimeError( "Exception thrown, please contact the maintainers", 1) elif status == 102: raise RuntimeError("Username does not exist", 1) else: raise RuntimeError("Child exited with unknown exit status", 1) else: exit_code = 0 try: # drop privileges: try: env.drop_privs(env.get_uid(), env.get_gid()) except RuntimeError, e: os._exit(102) check_cmd = [self.get_binary(), '--check-db-version', path] process = Popen(check_cmd, stdout=PIPE) process.communicate() if process.returncode == 2: update_cmd = ['spectrum', '--upgrade-db', path] process = Popen(update_cmd, stdout=PIPE) process.communicate() os._exit(process.returncode) else: os._exit(process.returncode) except OSError, e: os._exit(100) # spectrum wasn't found
def upgrade_db(self): """ Call C{specturm --check-db-version} to see if the schema version of the database is up to date. If not, call C{spectrum --upgrade-db} and try to upgrade the schema. @raise RuntimeError: If any of the launched commands fail. """ path = os.path.abspath(self.config_path) # fork and drop privileges: pid = os.fork() if pid: # we are the parent! pid, status = os.waitpid(pid, 0) status = (status & 0xFF00) >> 8 if status == 0: return elif status == 1: raise RuntimeError("db_version table does not exist", 1) elif status == 3: raise RuntimeError("Error connecting to the database", 1) elif status == 100: raise RuntimeError("Could not find spectrum binary", 1) elif status == 101: raise RuntimeError("Exception thrown, please contact the maintainers", 1) elif status == 102: raise RuntimeError("Username does not exist", 1) else: raise RuntimeError("Child exited with unknown exit status", 1) else: exit_code = 0 try: # drop privileges: try: env.drop_privs(env.get_uid(), env.get_gid()) except RuntimeError, e: os._exit(102) check_cmd = [self.get_binary(), "--check-db-version", path] process = subprocess.Popen(check_cmd, stdout=subprocess.PIPE) process.communicate() if process.returncode == 2: update_cmd = ["spectrum", "--upgrade-db", path] process = subprocess.Popen(update_cmd, stdout=subprocess.PIPE) process.communicate() os._exit(process.returncode) else: os._exit(process.returncode) except OSError, e: os._exit(100) # spectrum wasn't found
def check_environment(self): """ This function is used to do tight checks on the environment when starting the spectrum instance. @return: A tuple of type (int, str) with the return value (0 means success, 1 indicates an error) and a human-readable string of what happened. @rtype: tuple @todo: The return value of this method is actually not used anymore. @raise RuntimeError: If anything (file permissions/ownership, ... ) is not as expected. """ # check if spectrum user exists: if os.name == 'posix': try: user = pwd.getpwuid(env.get_uid()) except KeyError: raise RuntimeError(env.get_uid(), 'UID does not exist') else: # on windows, there is no real way to get the info that # we need return 0, "ok" # we must be root if os.getuid() != 0: raise RuntimeError("User", "Must be root to start spectrum") # check permissions for config-file: env.check_ownership(self.config_path, 0) # we don't care about user permissions, group MUST be read-only env.check_permissions(self.config_path, [stat.S_IRGRP], [stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR]) # config_interface: config_interface = self.config.get('service', 'config_interface') if config_interface: # on some old (pre 0.1) installations config_interface does not exist dir = os.path.dirname(config_interface) try: env.check_exists(dir, typ='dir') env.check_writable(dir) except ExistsError: env.create_dir(dir) # filetransfer cache filetransfer_cache = self.config.get('service', 'filetransfer_cache') try: env.check_exists(filetransfer_cache, 'dir') except ExistsError: env.create_dir(filetransfer_cache) # pid_file: pid_file = self.config.get('service', 'pid_file') pid_dir = os.path.dirname(pid_file) try: env.check_exists(pid_dir, typ='dir') env.check_writable(pid_dir) except ExistsError: env.create_dir(pid_dir) # log file log_file = self.config.get('logging', 'log_file') try: # does not exist upon first startup: if not env.is_named_pipe(log_file): env.check_exists(log_file) env.check_ownership(log_file, gid=-1) env.check_permissions( log_file, # rw-r----- [stat.S_IRUSR, stat.S_IWUSR, stat.S_IRGRP]) except ExistsError: log_dir = os.path.dirname(log_file) try: env.check_exists(log_dir, typ='dir') except ExistsError: env.create_dir(log_dir) # sqlite database if self.config.get('database', 'type') == 'sqlite': db_file = self.config.get('database', 'database') try: # might not exist upon first startup: env.check_exists(db_file) env.check_ownership(db_file) env.check_permissions( db_file, # rw-r----- [stat.S_IRUSR, stat.S_IWUSR, stat.S_IRGRP]) except ExistsError: db_dir = os.path.dirname(db_file) try: env.check_exists(db_dir, typ='dir') env.check_ownership(db_dir) env.check_permissions( db_dir, # rwxr-x--- [ stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR, stat.S_IRGRP, stat.S_IXGRP ]) except ExistsError: env.create_dir(os.path.dirname(db_file)) # purple userdir userdir = self.config.get('purple', 'userdir') try: env.check_exists(userdir, 'dir') env.check_ownership(userdir) env.check_permissions( userdir, # rwxr-x--- [ stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR, stat.S_IRGRP, stat.S_IXGRP ]) except ExistsError: env.create_dir(userdir) return 0, 'ok'
raise RuntimeError("Error connecting to the database", 1) elif status == 100: raise RuntimeError("Could not find spectrum binary", 1) elif status == 101: raise RuntimeError( "Exception thrown, please contact the maintainers", 1) elif status == 102: raise RuntimeError("Username does not exist", 1) else: raise RuntimeError("Child exited with unknown exit status", 1) else: exit_code = 0 try: # we are the child try: env.drop_privs(env.get_uid(), env.get_gid()) except RuntimeError, e: os._exit(102) # get the absolute path of the config file path = os.path.abspath(self.config_path) # check if database is at current version: check_cmd = [self.get_binary(), '--check-db-version', path] process = Popen(check_cmd, stdout=PIPE) process.communicate() if process.returncode != 0: os._exit(process.returncode) # finally start spectrum: cmd = [self.get_binary()]
def check_environment(self): """ This function is used to do tight checks on the environment when starting the spectrum instance. @return: A tuple of type (int, str) with the return value (0 means success, 1 indicates an error) and a human-readable string of what happened. @rtype: tuple @todo: The return value of this method is actually not used anymore. @raise RuntimeError: If anything (file permissions/ownership, ... ) is not as expected. """ # check if spectrum user exists: if os.name == "posix": try: user = pwd.getpwuid(env.get_uid()) except KeyError: raise RuntimeError(env.get_uid(), "UID does not exist") else: # on windows, there is no real way to get the info that # we need return 0, "ok" # we must be root if os.getuid() != 0: raise RuntimeError("User", "Must be root to start spectrum") # check permissions for config-file: env.check_ownership(self.config_path, 0) # we don't care about user permissions, group MUST be read-only env.check_permissions(self.config_path, [stat.S_IRGRP], [stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR]) # config_interface: config_interface = self.config.get("service", "config_interface") if config_interface: # on some old (pre 0.1) installations config_interface does not exist dir = os.path.dirname(config_interface) try: env.check_exists(dir, typ="dir") env.check_writable(dir) except ExistsError: env.create_dir(dir) # filetransfer cache filetransfer_cache = self.config.get("service", "filetransfer_cache") try: env.check_exists(filetransfer_cache, "dir") env.check_ownership(filetransfer_cache) env.check_permissions( filetransfer_cache, [stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR, stat.S_IRGRP, stat.S_IXGRP] # rwxr-x--- ) except ExistsError: env.create_dir(filetransfer_cache) # pid_file: pid_file = self.config.get("service", "pid_file") pid_dir = os.path.dirname(pid_file) try: env.check_exists(pid_dir, typ="dir") env.check_writable(pid_dir) except ExistsError: env.create_dir(pid_dir) # log file log_file = self.config.get("logging", "log_file") try: # does not exist upon first startup: if not env.is_named_pipe(log_file): env.check_exists(log_file) env.check_ownership(log_file, gid=-1) env.check_permissions(log_file, [stat.S_IRUSR, stat.S_IWUSR, stat.S_IRGRP]) # rw-r----- except ExistsError: log_dir = os.path.dirname(log_file) try: env.check_exists(log_dir, typ="dir") except ExistsError: env.create_dir(log_dir) # sqlite database if self.config.get("database", "type") == "sqlite": db_file = self.config.get("database", "database") try: # might not exist upon first startup: env.check_exists(db_file) env.check_ownership(db_file) env.check_permissions(db_file, [stat.S_IRUSR, stat.S_IWUSR, stat.S_IRGRP]) # rw-r----- except ExistsError: db_dir = os.path.dirname(db_file) try: env.check_exists(db_dir, typ="dir") env.check_ownership(db_dir) env.check_permissions( db_dir, [stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR, stat.S_IRGRP, stat.S_IXGRP] # rwxr-x--- ) except ExistsError: env.create_dir(os.path.dirname(db_file)) # purple userdir userdir = self.config.get("purple", "userdir") try: env.check_exists(userdir, "dir") env.check_ownership(userdir) env.check_permissions( userdir, [stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR, stat.S_IRGRP, stat.S_IXGRP] # rwxr-x--- ) except ExistsError: env.create_dir(userdir) return 0, "ok"
elif status == 3: raise RuntimeError("Error connecting to the database", 1) elif status == 100: raise RuntimeError("Could not find spectrum binary", 1) elif status == 101: raise RuntimeError("Exception thrown, please contact the maintainers", 1) elif status == 102: raise RuntimeError("Username does not exist", 1) else: raise RuntimeError("Child exited with unknown exit status", 1) else: exit_code = 0 try: # we are the child try: env.drop_privs(env.get_uid(), env.get_gid()) except RuntimeError, e: os._exit(102) # get the absolute path of the config file path = os.path.abspath(self.config_path) # check if database is at current version: check_cmd = [self.get_binary(), "--check-db-version", path] process = subprocess.Popen(check_cmd, stdout=subprocess.PIPE) process.communicate() if process.returncode != 0: os._exit(process.returncode) # finally start spectrum: cmd = [self.get_binary()]