def _mount_config_destination(self): """Mounts the destination specified in configuration and modifies the target value in configuration accordingly. """ error = None try: _dest = self.get_destination() _eff_path = self.__mount_uri(_dest) if _eff_path is None: self._eff_path = _dest else: self._eff_path = _eff_path if (self._eff_path is None) or (not self._eff_path.startswith( local_file_utils.PATHSEP)): raise exceptions.FileAccessException("Unable to mount target") if not local_file_utils.path_exists(self._eff_path): raise exceptions.FileAccessException( "Unable to mount target: Path does not exist") except SBException as error: self._logger.error( "Error in mount callback function. Overwriting previous errors." ) if self._initialize_callback is None: raise if self._initialize_callback is not None: self._logger.debug( "Calling additional callback in fuse_fam._mount_cb: %s" % self._initialize_callback) self._initialize_callback(error) if error is None: self._is_initialized = True
def __get_configuration(self): _configfile_hdl = ConfigurationFileHandler() _config = None _configfile = _configfile_hdl.get_conffile() if local_file_utils.path_exists(_configfile): _config = ConfigManager(_configfile) else: _config = ConfigManager() return _config
def __prepare_lock_dir(self): _dir = os.path.dirname(self.__lockfile) if not local_file_utils.path_exists(_dir): try: os.mkdir(_dir) os.chmod(_dir, 0777) except (OSError, IOError), error: self.__logger.error("Unable to make lock directory: %s" % error) raise exceptions.ApplicationLockError
def dest_path_exists(self): """The effective path denotes the local mountpoint of the actual remote or local target. It is required in order to give it to TAR as parameter (tar does not support gio). It is checked using GIO and native access functions. """ _path = self.query_mount_uri() assert _path != "" assert _path is not None assert _path.startswith(local_file_utils.PATHSEP) _res_gio = local_file_utils.path_exists(_path) return _res_gio
def __force_unsetlock(self): """Remove lockfile. """ if local_file_utils.path_exists(self.__lockfile): try: local_file_utils.delete(self.__lockfile) self.__logger.debug("Lock file '%s' removed." % self.__lockfile) except (OSError, IOError), _exc: self.__logger.error( _("Unable to remove lock file: %s") % str(_exc))
def unlock(self): """Remove lockfile. """ if local_file_utils.path_exists(self.__lockfile): if self.__is_lock_owned(): try: local_file_utils.delete(self.__lockfile) self.__logger.debug("Lock file '%s' removed." % self.__lockfile) except (OSError, IOError), _exc: self.__logger.error( _("Unable to remove lock file: %s") % str(_exc)) else: self.__logger.debug( "Unable to remove lock: not owned by this process.")
def __is_lock_owned(self): owned = False if local_file_utils.path_exists(self.__lockfile): # the lockfile exists, is it valid? try: last_sb_pid = local_file_utils.readfile(self.__lockfile) last_sb_pid = int(last_sb_pid) except (OSError, IOError, ValueError), error: self.__logger.error("Error while reading lockfile: %s" % str(error)) last_sb_pid = None if last_sb_pid is not None: if last_sb_pid == self.__pid: owned = True
def __is_lock_valid(self): valid = False if local_file_utils.path_exists(self.__lockfile): # the lockfile exists, is it valid? try: last_pid = local_file_utils.readfile(self.__lockfile) last_pid = int(last_pid) except (OSError, IOError, ValueError), error: self.__logger.error("Error while reading lockfile: %s" % str(error)) last_pid = None if last_pid is not None: if system.pid_exists(pid=str(last_pid), processname=self.__processname): valid = True
def __retrieve_confm(self, force_conffile): """Factory method that retrieves the appropriate configuration managers for the existing profiles. Super-user rights are taken into account. The created configuration managers are stored in member variable 'self.__confm'. :todo: Place the path names in class `ConfigStaticData`. """ self.__confm = [] # default profile config file and the config directory is determined conffile_hdl = ConfigurationFileHandler() if force_conffile is None: conffile = conffile_hdl.get_conffile() else: # conffile given on commandline is treated as default profile's config conffile = force_conffile confdir = conffile_hdl.get_profilesdir(conffile) # create config manager for the default profile and set as current if local_file_utils.path_exists(conffile): confm = ConfigManager(conffile) self.__profilename = confm.getProfileName() self.__confm.append( confm) # store the created ConfigManager in a collection else: errmsg = _( "Critical Error: No configuration file for the default profile was found!\n\nNow continue processing remaining profiles." ) self.__errors.append(errmsg) if force_conffile is None: # search for alternate configuration files only if no config file was given for _prof in get_profiles(confdir).values(): _prof_path = _prof[0] _prof_enable = _prof[1] if _prof_enable: confm = ConfigManager(_prof_path) self.__confm.append(confm)
def lock(self): """Sets a lock file. In 0.3 following changes take effect: * use fixed location (users and superusers); ignore settings in configuration files * existence of directory `sbackup` with mode 777 is assumed (no sticky bit set) """ self.__prepare_lock_dir() if local_file_utils.path_exists(self.__lockfile): if self.__is_lock_valid() is True: raise exceptions.InstanceRunningError(\ _("Another application instance is already running.")) else: self.__logger.info( _("Invalid lock file found. Is being removed.")) self.__force_unsetlock() try: local_file_utils.writetofile(self.__lockfile, str(self.__pid)) self.__logger.debug("Created lockfile `%s` with info `%s`." % (self.__lockfile, str(self.__pid))) except (OSError, IOError), error: self.__logger.error("Unable to create lock: %s" % error) raise exceptions.ApplicationLockError
def path_exists(cls, path): return local_file_utils.path_exists(path)
def parse_cmdline(self): """Parses the given commandline options and sets specific attributes. It must be considered that the DBus service can be used without the tray GUI but in contrast the tray GUI cannot be used without the DBus service. The method uses the commandline arguments given to class' constructor. :todo: An option '--dry-run' would be nice! """ usage = "Usage: %prog [options] (use -h or --help for more infos)" version = "%prog " + Infos.VERSION prog = constants.BACKUP_COMMAND parser = optparse.OptionParser(usage=usage, version=version, prog=prog) parser.add_option( "--no-indicator", action="store_false", dest="use_indicator", default=True, help="don't use the graphical indicator application (status icon)") parser.add_option("--no-dbus", action = "store_false", dest = "use_dbus", default = True, help = "don't launch the DBus service and "\ "don't use it (implies --no-indicator)") parser.add_option("--config-file", dest="configfile", metavar="FILE", default=None, help="set the configuration file to use") parser.add_option( "--legacy-indicator", action="store_true", dest="legacy_appindicator", default=False, help="use legacy status icon instead of `libappindicator`") parser.add_option("--full", action="store_true", dest="full_snapshot", default=False, help="create full snapshot") (options, args) = parser.parse_args(self.__argv[1:]) if len(args) > 0: parser.error("You must not provide any non-option argument") if options.configfile: if not local_file_utils.path_exists(options.configfile): parser.error("Given configuration file does not exist") self.__configfile = options.configfile self.__options_given = options if self.__options_given.use_dbus == True: self.__use_indicator = options.use_indicator else: self.__use_indicator = False
def __sendEmail(self): """Checks if the sent of emails is set in the config file then send an email with the report :todo: Transfer this functionality to a specialized class! """ self.logger.debug("Send email report") if self.__bprofilehdl.config.has_option("report", "from"): _from = self.__bprofilehdl.config.get("report", "from") else: hostname = socket.gethostname() if "." in hostname: mailsuffix = hostname else: mailsuffix = hostname + ".ext" _from = _("SBackup Daemon <%(login)s@%(hostname)s>")\ % {'login' : str(system.get_user_from_env()), 'hostname': mailsuffix} _to = self.__bprofilehdl.config.get("report", "to") _title = _("[SBackup] [%(profile)s] Report of %(date)s")\ % { 'profile':self.__profilename, 'date': datetime.datetime.now() } logf = self.__bprofilehdl.config.get_current_logfile() if logf is None: _content = _("No log file specified.") else: if local_file_utils.path_exists(logf): _content = local_file_utils.readfile(logf) else: _content = _("Unable to find log file.") server = smtplib.SMTP() if self.logger.isEnabledFor(10): server.set_debuglevel(True) msg = MIMEMultipart() msg['Subject'] = _title msg['From'] = _from msg['To'] = _to msg.preamble = _title msg_content = MIMEText(_content) # Set the filename parameter msg_content.add_header('Content-Disposition', 'attachment', filename="sbackup.log") msg.attach(msg_content) # getting the connection if self.__bprofilehdl.config.has_option("report", "smtpserver"): if self.__bprofilehdl.config.has_option("report", "smtpport"): server.connect( self.__bprofilehdl.config.get("report", "smtpserver"), self.__bprofilehdl.config.get("report", "smtpport")) else: server.connect( self.__bprofilehdl.config.get("report", "smtpserver")) if self.__bprofilehdl.config.has_option("report", "smtptls") and\ self.__bprofilehdl.config.get("report", "smtptls") == "1": if self.__bprofilehdl.config.has_option("report", "smtpcert") and\ self.__bprofilehdl.config.has_option("report", "smtpkey"): server.starttls( self.__bprofilehdl.config.get("report", "smtpkey"), self.__bprofilehdl.config.get("report", "smtpcert")) else: server.starttls() if self.__bprofilehdl.config.has_option("report", "smtpuser") and\ self.__bprofilehdl.config.has_option("report", "smtppassword"): server.login( self.__bprofilehdl.config.get("report", "smtpuser"), self.__bprofilehdl.config.get("report", "smtppassword")) # send and close connection server.sendmail(_from, _to, msg.as_string()) server.close()
def mount(self, source, mountbase): """ Mount the source intor the mountbase dir . This method should create a mount point to mount the source. The name of the mount point should be very expressive so that we avoid collision with other mount points @param source: The remote path @param mountbase: The mount points base dir @return: The mount point complete path """ exp = re.compile(ssh_url_re) match = exp.search(source) if not match: raise FuseFAMException( _("Error matching the schema 'ssh://*****:*****@example.com/home/' with '%s' (The '/' after server is mandatory)" ) % source) else: remoteSource = "ssh://" + match.group(1) if match.group(3): remoteSource += ":" + match.group(3) remoteSource += "@" + match.group(4) if match.group(6): remoteSource += ":" + match.group(6) remoteSource += "/" user = match.group(1) mountpoint = local_file_utils.joinpath( mountbase, self._defineMountDirName(source)) if match.group(7): pathinside = match.group(7) else: pathinside = "" #If the path is already mounted No need to retry if self.checkifmounted(source, mountbase): return (remoteSource, mountpoint, pathinside) cmd = "sshfs " + user + "@" + match.group(4) + ":/" cmd = cmd + " " + mountpoint port = match.group(6) if port: cmd += " -p " + port if not local_file_utils.path_exists(mountpoint): local_file_utils.makedir(mountpoint) if system.is_superuser(): cmd += " -o allow_root" self.logger.debug("Spawning: " + cmd) password = match.group(3) sshfsp = pexpect.spawn(cmd) i = sshfsp.expect(['(yes/no)', 'password:'******'Password:'******'yes') i = sshfsp.expect( ['(yes/no)', 'password:'******'Password:'******'(yes/no)', 'password:'******'Password:'******'%(command)s' didn't perform normally. Output => %(erroroutput)s " ) % { "command": cmd, "erroroutput": result }) return (remoteSource, mountpoint, pathinside)