updating to support configurable delay checking and rsync exit code ignoring
This commit is contained in:
parent
4bdb31541b
commit
bc9a653234
@ -69,16 +69,15 @@
|
||||
<long>links</long>
|
||||
<long>hard-links</long>
|
||||
<long>delete-after</long>
|
||||
<long>perms</long>
|
||||
<long>delay-updates</long>
|
||||
<long>copy-links</long>
|
||||
<long>safe-links</long>
|
||||
<long>delete-excluded</long>
|
||||
<long value=".*">exclude</long>
|
||||
</rsyncArgs>
|
||||
These arguments should be sane for most, if not all, rsync-driven repository mirroring. The last one (exclude) may
|
||||
be removed in future versions.
|
||||
These arguments should be sane for most, if not all, rsync-driven repository mirroring.
|
||||
If arguments are provided, the defaults are overwritten so if you need the above, be sure to specify them.
|
||||
See the rsync man page (rsync(1)) for more details and a listing of supported flags on your system.
|
||||
See the rsync man page (rsync(1)) for more details and a listing of supported flags on your system
|
||||
(§ "OPTION SUMMARY", § "OPTIONS").
|
||||
-->
|
||||
<rsyncArgs>
|
||||
<!--
|
||||
@ -94,7 +93,19 @@
|
||||
A "short" option (single hyphen).
|
||||
-->
|
||||
<short>c</short><!-- checksum -->
|
||||
<!--
|
||||
An option that requires to be enclosed in quotes. (This one excludes hidden files/directories.)
|
||||
-->
|
||||
<long value="".*"">exclude</long>
|
||||
</rsyncArgs>
|
||||
<!--
|
||||
rsyncIgnore is an optional element that ignores certain return codes/exit statuses of rsync (otherwise they are
|
||||
raised as warnings). It consists of a space-separated list of return codes that warnings should be suppressed for.
|
||||
(Return code 0 never raises a warning, as it is success.)
|
||||
See the rsync man page (rsync(1)) for a list of error codes and what they mean (§ "EXIT VALUES"), or refer to:
|
||||
repomirror/fetcher/rsync_returns.py
|
||||
-->
|
||||
<rsyncIgnore returns="23 24"/>
|
||||
<!--
|
||||
Upstreams have an optional attribute, "delayCheck", which is an ISO 8601 duration type.
|
||||
https://en.wikipedia.org/wiki/ISO_8601#Durations
|
||||
|
@ -6,11 +6,11 @@ RSYNC_DEF_ARGS = ['--recursive',
|
||||
'--links',
|
||||
'--hard-links',
|
||||
'--delete-after',
|
||||
'--perms',
|
||||
'--delay-updates',
|
||||
'--copy-links',
|
||||
'--safe-links',
|
||||
'--delete-excluded',
|
||||
'--exclude=.*']
|
||||
'--exclude=".*"']
|
||||
|
||||
# These are needed to convert years/months to timedeltas.
|
||||
# The following are averaged definitions for time units *in days* according to Google Calculator.
|
||||
|
@ -25,6 +25,7 @@ class RSync(_base.BaseFetcher):
|
||||
path,
|
||||
dest,
|
||||
rsync_args = None,
|
||||
rsync_ignores = None,
|
||||
owner = None,
|
||||
log = True,
|
||||
filechecks = None,
|
||||
@ -37,6 +38,7 @@ class RSync(_base.BaseFetcher):
|
||||
else:
|
||||
self.rsync_args = constants.RSYNC_DEF_ARGS[:]
|
||||
_logger.debug('RSync args given: {0}'.format(self.rsync_args))
|
||||
self.rsync_ignores = rsync_ignores[:]
|
||||
if log:
|
||||
# Do I want to do this in subprocess + logging module? Or keep this?
|
||||
# It looks a little ugly in the log but it makes more sense than doing it via subprocess just to write it
|
||||
@ -68,10 +70,10 @@ class RSync(_base.BaseFetcher):
|
||||
stderr = subprocess.PIPE)
|
||||
stdout = cmd.stdout.decode('utf-8').strip()
|
||||
stderr = cmd.stderr.decode('utf-8').strip()
|
||||
rtrn = cmd.returncode
|
||||
if stdout != '':
|
||||
_logger.debug('STDOUT: {0}'.format(stdout))
|
||||
if stderr != '' or cmd.returncode != 0:
|
||||
rtrn = cmd.returncode
|
||||
if stderr != '' or (rtrn != 0 and rtrn not in self.rsync_ignores):
|
||||
err = rsync_returns.returns[rtrn]
|
||||
errmsg = 'Rsync to {0}:{1} returned'.format(self.domain, self.port)
|
||||
debugmsg = 'Rsync command {0} returned'.format(' '.join(cmd_str))
|
||||
@ -100,10 +102,10 @@ class RSync(_base.BaseFetcher):
|
||||
stderr = subprocess.PIPE)
|
||||
stdout = cmd.stdout.decode('utf-8').strip()
|
||||
stderr = cmd.stderr.decode('utf-8').strip()
|
||||
rtrn = cmd.returncode
|
||||
if stdout != '':
|
||||
_logger.debug('STDOUT: {0}'.format(stdout))
|
||||
if stderr != '' or cmd.returncode != 0:
|
||||
rtrn = cmd.returncode
|
||||
if stderr != '' or (rtrn != 0 and rtrn not in self.rsync_ignores):
|
||||
err = rsync_returns.returns[rtrn]
|
||||
errmsg = 'Rsync to {0}:{1} returned'.format(self.domain, self.port)
|
||||
debugmsg = 'Rsync command {0} returned'.format(' '.join(cmd_str))
|
||||
|
@ -35,7 +35,6 @@ _duration_re = re.compile(('^P'
|
||||
'$'))
|
||||
|
||||
|
||||
|
||||
def get_owner(owner_xml):
|
||||
owner = {}
|
||||
user = owner_xml.find('user')
|
||||
@ -154,7 +153,7 @@ class TimestampFile(object):
|
||||
|
||||
|
||||
class Upstream(object):
|
||||
def __init__(self, upstream_xml, dest, rsync_args = None, owner = None, filechecks = None):
|
||||
def __init__(self, upstream_xml, dest, rsync_args = None, owner = None, filechecks = None, rsync_ignores = None):
|
||||
self.xml = upstream_xml
|
||||
# These are required for all upstreams.
|
||||
self.sync_type = self.xml.find('syncType').text.lower()
|
||||
@ -179,6 +178,7 @@ class Upstream(object):
|
||||
self.path,
|
||||
self.dest,
|
||||
rsync_args = rsync_args,
|
||||
rsync_ignores = rsync_ignores,
|
||||
filechecks = self.filechecks,
|
||||
owner = self.owner)
|
||||
else:
|
||||
@ -225,6 +225,7 @@ class Distro(object):
|
||||
'sync': None}}
|
||||
self.timestamps = {}
|
||||
self.rsync_args = None
|
||||
self.rsync_ignores = None
|
||||
self.owner = None
|
||||
self.upstreams = []
|
||||
self.lockfile = '/var/run/repomirror/{0}.lck'.format(self.name)
|
||||
@ -243,12 +244,17 @@ class Distro(object):
|
||||
e = self.xml.find('lastRemote{0}'.format(i))
|
||||
if e is not None:
|
||||
self.filechecks['remote'][i.lower()] = TimestampFile(e)
|
||||
self.rsync_ignores = []
|
||||
rsyncig_xml = self.xml.find('rsyncIgnore')
|
||||
if rsyncig_xml is not None:
|
||||
self.rsync_ignores = [int(i.strip()) for i in rsyncig_xml.attrib['returns'].split()]
|
||||
for u in self.xml.findall('upstream'):
|
||||
self.upstreams.append(Upstream(u,
|
||||
self.dest,
|
||||
rsync_args = self.rsync_args,
|
||||
owner = self.owner,
|
||||
filechecks = self.filechecks))
|
||||
filechecks = self.filechecks,
|
||||
rsync_ignores = self.rsync_ignores))
|
||||
|
||||
def check(self):
|
||||
for k, v in self.filechecks['local'].items():
|
||||
@ -285,11 +291,11 @@ class Distro(object):
|
||||
else:
|
||||
_logger.info('No remote update timestamp; syncing.')
|
||||
u.has_new = True
|
||||
if sync:
|
||||
if sync and u.delay:
|
||||
td = datetime.datetime.utcnow() - sync
|
||||
if td.days > constants.DAYS_WARN:
|
||||
_logger.warning(('Upstream {0} has not synced for {1} or more days; this '
|
||||
'repository may be out of date.').format(u.fetcher.url, constants.DAYS_WARN))
|
||||
if td.days > u.delay:
|
||||
_logger.warning(('Upstream {0} has not synced for {1} or longer; this '
|
||||
'repository may be out of date.').format(u.fetcher.url, u.delay))
|
||||
warnings.warn('Upstream may be out of date')
|
||||
return(None)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user