#******************************************************************** # # Copyright (C) 2005-2006 Hari Krishna Dara # # This file is part of p4admin. # # p4admin is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # p4admin is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # #******************************************************************* import re import logging import config import notify import utils log = logging.getLogger(__name__) rsyncDaemonStarted = False def rsyncDaemonRunning(host): moduleList = utils.execute('rsync rsync://'+host, verbosity=1) if utils.shell_error == 0: # We want the daemon with right configuration. if not re.search(config.rsyncRootModuleName, moduleList) or \ not re.search(config.rsyncJnlModuleName, moduleList): notify.sendError('Rsync daemon is running on host: '+host+ ', but it is not configured properly') # There is no use attempting to start another server on the same # port, so return True. #return False log.debug('rsync daemon is running on %s with the module list:\n%s', host, moduleList) return True else: return False def startupRsyncDaemon(host): """Ensure that an rsync daemon is running on this given host""" global rsyncDaemonStarted if rsyncDaemonStarted: return 0 # First check if the rsync is running or not. if not rsyncDaemonRunning(host): log.debug('rsync daemon is not started, attempting to start') if not config.packageInPerforce: log.info('Copying the rsync configuration file') if config.remoteShell == 'rsh': rcpCmd = 'rcp' elif config.remoteShell == 'ssh': rcpCmd = 'scp' else: notify.sendError('Unknown remoteShell: '+config.remoteShell) return 1 result = utils.execute(rcpCmd+' '+' '+ config.rsyncConfigFileName+ ' '+config.p4HostRemote+':'+config.rsyncRemoteConfig) if utils.shell_error != 0: notify.sendError('Error in remote-copying: '+result) # Attempt to start it up now. rsyncCmd = 'rsync --daemon --config='+config.rsyncRemoteConfig if config.rsyncPort: rsyncCmd += ' --port='+config.rsyncPort result = utils.execute(config.remoteShell+' '+host+' '+rsyncCmd) if utils.shell_error != 0: notify.sendError('Error starting up remote rsync daemon: ' + result) return 1 # Check once more if the daemon has started up. if not rsyncDaemonRunning(host): notify.sendError("Attempt to startup rsync daemon didn't seem to work") return 1 rsyncDaemonStarted = True return 0 def rsyncFile(remoteHost, module, remoteFile, localRoot, localFile, additionalRsyncOpts, delete=True, ignoreMissingSrc=False): """remoteFile can be a directory or file and can contain wildcards.""" # Ensure rsync daemon is running. rsyncOpts = config.rsyncOpts if config.rsyncConfigFileName: if startupRsyncDaemon(remoteHost) != 0: return 1 remoteDir = 'rsync://'+remoteHost if config.rsyncPort: remoteDir += ':'+config.rsyncPort remoteDir += '/'+module+'/'+remoteFile else: rsyncOpts += ' --rsh '+config.remoteShell remoteDir = remoteHost+':/'+config.rsyncModulePathLookup[module]+'/'+\ remoteFile localDir = localRoot+'/'+localFile #if remoteDir[-1] == '/': # localDir = localRoot+'/'+localFile #else: # localDir = localRoot # rsync --rsh=ssh -av scallop:/cygdrive/e/Perforce/appsprod/depot/ /cygdrive/d/Perforce/appsprod/depot # rsync -av rsync://scallop/perforceroot/depot/ /cygdrive/d/Perforce/appsprod/depot result = utils.execute('rsync '+ rsyncOpts+' '+additionalRsyncOpts+ # Python doesn't have a ternary operator (' --delete ', ' ')[not delete]+ remoteDir+' '+localDir) if utils.shell_error != 0: if not ignoreMissingSrc or not re.search(r'(ckp|jnl)\.\*.*: No such ' 'file', result): notify.sendError('rsync failed to synchronize: ' + result) return 1 else: log.debug('ignoring errors because ignoreMissingSrc?%s' ' and the output matches safe pattern', ignoreMissingSrc) return 0