80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import argparse
|
||
|
import datetime
|
||
|
import os
|
||
|
import subprocess
|
||
|
|
||
|
mirror = 'rsync://mirror.wdc1.us.leaseweb.net/archlinux' # must be an rsync mirror; base path
|
||
|
dest = {'mount':'/mnt/raidbox', 'path':'/mnt/raidbox/repos/arch'}
|
||
|
bwlimit = 7000 # in Kilobyte/s by default; set to 0 to disable bandwidth throttling
|
||
|
# currently not used:
|
||
|
repos = ['core',
|
||
|
'extra',
|
||
|
'community',
|
||
|
'multilib',
|
||
|
'iso/latest']
|
||
|
# Rsync options
|
||
|
opts = [
|
||
|
'--recursive', # recurse into directories
|
||
|
'--times', # preserve modification times
|
||
|
'--links', # copy symlinks as symlinks
|
||
|
'--hard-links', # preserve hard links
|
||
|
'--quiet', # suppress non-error messages
|
||
|
'--delete-after', # receiver deletes after transfer, not during
|
||
|
'--delay-updates', # put all updated files into place at end
|
||
|
'--copy-links', # transform symlink into referent file/dir
|
||
|
'--safe-links', # ignore symlinks that point outside the tree
|
||
|
#'--max-delete', # don't delete more than NUM files
|
||
|
'--delete-excluded', # also delete excluded files from dest dirs
|
||
|
'--exclude=.*' # exclude files matching PATTERN
|
||
|
]
|
||
|
|
||
|
if bwlimit >= 1:
|
||
|
opts.insert(10, '--bwlimit=' + str(bwlimit)) # limit socket I/O bandwidth
|
||
|
|
||
|
lockfile = '/var/run/repo-sync.lck'
|
||
|
logfile = '/var/log/arch.repo.sync'
|
||
|
|
||
|
def sync():
|
||
|
# TODO: safer file creation etc. - make sure parent dirs exist.
|
||
|
# TODO: check that destination is mounted first.
|
||
|
paths = os.environ['PATH'].split(':')
|
||
|
rsync = '/usr/bin/' # set the default
|
||
|
for p in paths:
|
||
|
testpath = os.path.join(p, 'rsync')
|
||
|
if os.path.isfile(testpath):
|
||
|
rsync = testpath # in case rsync isn't in /usr/bin/rsync
|
||
|
break
|
||
|
cmd = [rsync] # the path to the binary
|
||
|
cmd.extend(opts) # the arguments
|
||
|
cmd.append(os.path.join(mirror, '.')) # the path on the remote mirror
|
||
|
cmd.append(os.path.join(dest['path'], '.')) # the local destination
|
||
|
if os.path.isfile(lockfile):
|
||
|
with open(lockfile, 'r') as f:
|
||
|
existingpid = f.read().strip()
|
||
|
exit('!! A repo synchronization seems to already be running (PID: {0}). Quitting. !!'.format(existingpid))
|
||
|
else:
|
||
|
with open(lockfile, 'w') as f:
|
||
|
f.write(str(os.getpid()))
|
||
|
with open(logfile, 'a') as log:
|
||
|
try:
|
||
|
subprocess.call(cmd, stdout = log, stderr = subprocess.STDOUT)
|
||
|
now = int(datetime.datetime.timestamp(datetime.datetime.utcnow()))
|
||
|
with open(os.path.join(dest['path'], 'lastsync'), 'w') as f:
|
||
|
f.write(str(now) + '\n')
|
||
|
os.remove(lockfile)
|
||
|
except:
|
||
|
os.remove(lockfile)
|
||
|
exit('!! The rsync has failed. See {0} for more details. !!'.format(logfile))
|
||
|
return()
|
||
|
|
||
|
def parseArgs():
|
||
|
pass
|
||
|
|
||
|
def main():
|
||
|
sync()
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|