201 lines
5.2 KiB
Python
Executable file
201 lines
5.2 KiB
Python
Executable file
#! /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 +'*'
|
|
|