blob: 9f0069bc7ebb11f117faed480749a1031e3e04c8 [file] [log] [blame]
#! /usr/bin/python
#
# repcacheman ver 0.44
#
# Cache Manager for Http-Replicator
# deletes duplicate files in PORTDIR.
# imports authenticated (checksum + listed in portage)
# files from PORTDIR to replicator's cache directory.
#
# Uses portage to perform checksum and database functions.
# All else, Copyright(C)2004-2007 Tom Poplawski (poplawtm@earthlink.net)
# Distributed under the terms of the GNU General Public License v2
#
# This program 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 portage.manifest
import portage.checksum
import portage.exception
import portage
import string
import os
import pwd,sys,optparse
if os.getuid():
print"Must be root"
sys.exit(1)
# Parse Options
parser = optparse.OptionParser()
parser.add_option('-d', '--dir', type='string', default="/var/cache/http-replicator", help='http-replicators cache DIR')
parser.add_option('-u','--user', type='string', default="portage", help='http-replicator USER')
options, args = parser.parse_args() # parse command line
if options.user:
try:
uid=pwd.getpwnam(options.user)[2]
gid=pwd.getpwnam(options.user)[3]
except:
print "User \'" + options.user + "\' Doesn't exist on system - edit config or add user to system."
sys.exit(1)
else:
print "Error\n\tunable to get USER from /etc/http-replicator.conf"
sys.exit(1)
# dir is replicator's cache directory
dir=options.dir+"/"
if os.path.isdir(dir) :
newdir=0
else :
print"\n\nBegin Http-Replicator Setup...."
try:
os.makedirs(dir)
print "\tcreated " + dir
newdir=1
except:
print "\tcreate " + dir + " failed"
print '\terror:', sys.exc_info()[1]
sys.exit(1)
try:
os.chown(dir,uid,gid)
print "\tchanged owner of " + dir + " to " + options.user
except:
print "\tchange owner " + dir + " to " + options.user + " failed:"
print '\terror:', sys.exc_info()[1]
print "\n\nReplicator's cache directory: " + dir
# Import Portage settings
distdir=portage.settings["DISTDIR"]+"/"
if distdir:
print "Portage's DISTDIR: " + distdir
else:
print"Unable to get Portage's DISTDIR"
sys.exit(1)
# Start Work
print "\nComparing directories...."
# Create filecmp object
import filecmp
dc=filecmp.dircmp (distdir,dir,['cvs-src','git-src','hg-src','.locks'])
print "Done!"
dupes=dc.common
deleted=0
if dupes:
print "\nDeleting duplicate file(s) in " + distdir
for s in dupes:
print s
try:
os.remove(distdir + s )
deleted +=1
except:
print "\tdelete " + distdir + s + " failed:"
print '\terror:', sys.exc_info()[1]
print "Done!"
newfiles=dc.left_only
nf=len(dc.left_only)
if nf:
print "\nNew files in DISTDIR:"
for s in newfiles:
print s
print"\nChecking authenticity and integrity of new files..."
added=0
errors=0
badsum=0
# search all packages
for mycp in portage.db["/"]["porttree"].dbapi.cp_all():
manifest = portage.manifest.Manifest("/usr/portage/" + mycp , distdir)
if manifest == None:
portage.writemsg("Missing manifest: %s\n" % mycpv)
remove=[]
for file in newfiles:
if manifest.hasFile("DIST",file):
try:
myok, myreason = manifest.checkFileHashes("DIST",file)
try:
os.rename(distdir+file,dir+file)
added += 1
except:
try:
import shutil
shutil.copyfile(distdir+file,dir+file)
added += 1
os.remove(distdir+file)
except:
print "\tmove/copy " + file + " failed:"
print '\terror:', sys.exc_info()[1]
errors+=1
try:
os.chown(dir+file,uid,gid)
except:
print "\tchown " + file + " failed:"
print '\terror:', sys.exc_info()[1]
errors +=1
remove.append( file )
except portage.exception.DigestException, e:
print("\n!!! Digest verification failed:")
print("!!! %s" % e.value[0])
print("!!! Reason: %s" % e.value[1])
print("!!! Got: %s" % e.value[2])
print("!!! Expected: %s" % e.value[3])
badsum+=1
if remove:
for rf in remove:
newfiles.remove ( rf )
print "\nSUMMARY:"
print "Found " + str(len(dupes)) + " duplicate file(s)"
if deleted:
print "\tDeleted " + str(deleted) + " dupe(s)"
if nf:
print "Found " + str(nf) + " new file(s)"
print "\tAdded " + str(added) + " of those file(s) to the cache"
print "Rejected " +str(len(newfiles)) + " File(s) - ",
print str(badsum) + " failed checksum(s)"
for s in newfiles:
print "\t%s" %s
if errors:
print "Encountered " +str(errors) + " errors"
# if badsum:
# print str(badsum) + " partial/corrupted file(s)"
if newdir:
print"\n\nexecute:\n/etc/init.d/http-replicator start"
print"to run http-replicator.\n\nexecute:\nrc-update add http-replicator default"
print"to make http-replicator start at boot"
print"\n\nexecute:\n/usr/bin/repcacheman\nafter emerge's on the server to delete"
print"dup files and add new files to the cache"
print "\n\nHTTP-Replicator requires you delete any partial downloads in " + distdir
print "run rm -rf " + distdir +'*'