
Code: Select all
pkgl = os.popen('/bin/bash /usr/bin/qpkg -nc -I','r').readlines() Code: Select all
pkgl=[]
for i in os.listdir('/var/db/pkg'):
for j in os.listdir('/var/db/pkg/%s' % (i)):
elem = re.search('^(.*\/.*)-[0-9].*$',"%s/%s" % (i,j)).group(1)
try:
pkgl.index(elem)
except:
pkgl.append(elem)Code: Select all
pkgl = os.popen('/bin/bash /usr/bin/qpkg -nc -I','r').readlines()Code: Select all
pkgl = os.popen('/bin/bash /usr/lib/gentoolkit/qpkg -nc -I','r').readlines()
I can't reproduce your problem. Here's my version of the script:Yonathan wrote:when i add two packets with:
prlock A
prlock B
i can't find A in rsync_excludes, so i have to re-add A manually to rsync_...
This version of the script searches make.conf as requested and checks if the environment variables $PORTDIR or $RSYNC_EXCLUDES are set.Gentree wrote:One fault is that it assumes default portage directories. You should probably read $PORTDIR etc from make.conf and use those values instead.
Equally you check for the presence of rsync_excludes and break if it is not there as the std value. It would be better to read what is there and use it (heck , you've read this line in already , just parse out the filename.)
Code: Select all
#!/usr/bin/python
#
# prlock.py (Portage Rsync Lockdown)
# This script creates a exclude list for portage's rsync. The exclude list
# excludes all but the installed packages (found with qpkg).
# Specify 'branch-name/package-name' arguments to unlock additional packages
# that are not yet installed.
# Remember to edit make.conf and make the dir /etc/portage
#
# *WARNING*
# If you use this script and find yourself wanting to add a new package...
# You MUST either add it to the exclude list (By passing it as an arg to
# prlock) or comment out the exclude list entirly in make.conf.
# Then do a sync
# THEN add the package
# If you don't you will add a package that may be out of date!
#
# Eg.....
# > prlock.py dev-python/wxPython
# This will restrict the rsync to only the installed packages AND wxPython
# All other packages will not be updated.
#
# Nick Fisher prlock@nickdafish.com
#
import os, re, sys
# Quit if an arg that doesn't look like a package is encountered.
for arg in sys.argv[1:]:
if not re.match('[-\w]+/[-\w]+',arg):
print 'Line doesn\'t look like it is a package....\n',arg,'\n','...aborting.'
sys.exit(1)
# Trying to get portage dir and exclude file from environment
excl = os.environ.get('RSYNC_EXCLUDES', '')
portdir = os.environ.get('PORTDIR', '')
# Extract path of exclude file from make.conf
re_excl = re.compile('^\s*RSYNC_EXCLUDEFROM="?(?P<excl>(/[-\w]+)+)"?\s*$')
re_portdir = re.compile('^\s*PORTDIR="?(?P<portdir>(/[-\w]+)+)"?\s$')
for line in open('/etc/make.conf','r').readlines():
if not len(excl):
res = re_excl.match(line)
if res: excl = res.group('excl')
if not len(portdir):
res = re_portdir.match(line)
if res: portdir = res.group('portdir')
if not len(excl):
print 'WARNING! Could not get value of RSYNC_EXCLUDEFROM! Using default...'
excl = '/etc/portage/rsync_excludes'
print 'See make.conf(5) for help on setting the variable'
print 'Portage will not exclude without it!'
if not len(portdir):
portdir = '/usr/portage'
# Check that we will be able to write the file
#print 'Using',portdir,'as portage directory'
if not os.path.isdir(portdir):
print portdir,"does not exist!\nPlease make the dir and try again."
sys.exit(1)
#print 'Using',excl,'as exclude file'
if not os.path.isfile(excl):
print excl,"does not exist!\nPlease make the file and try again."
sys.exit(1)
# Find all the installed packages
pkgl=[]
for i in os.listdir('/var/db/pkg'):
for j in os.listdir('/var/db/pkg/%s' % (i)):
elem = re.search('^(.*\/.*)-[0-9].*$',"%s/%s" % (i,j)).group(1)
try:
pkgl.index(elem)
except:
pkgl.append(elem)
# Add the args
for arg in sys.argv[1:]:
pkgl.append(arg)
print 'Adding package from cmd line ',arg
# Add the branches to list and format
fmt = re.compile(r'[\w|-]*/')
list=[]
for line in pkgl:
m = fmt.search(line)
if not('+ '+m.group()+'\n' in list): list.append('+ '+m.group()+'\n')
if not('+ metadata/cache/'+m.group()+'\n' in list): list.append('+ metadata/cache/'+m.group()+'\n')
# Add the package dir and all subdirs/files to list
for x in range(len(pkgl)):
list.append('+ '+pkgl[x].strip()+'/\n')
list.append('+ '+pkgl[x].strip()+'/**\n')
list.append('+ metadata/cache/'+pkgl[x].strip()+'*\n')
# Append the directives to allow access to the metadata
list.append('+ metadata/\n')
list.append('+ metadata/*\n')
list.append('+ metadata/cache/\n')
list.append('+ metadata/cache/*\n')
# Allow sync for eclasses
# I don't know how I could exclude them well
list.append('+ eclass/\n')
list.append('+ eclass/**\n')
# Allow sync for files
# These shouldn't be excluded
list.append('+ files/\n')
list.append('+ files/**\n')
# Allow sync for libsidplay
# I havn't a clue what this branch is about
list.append('+ libsidplay/\n')
list.append('+ libsidplay/**\n')
# Allow sync for licenses
# Shouldn't be updated that often
list.append('+ licenses/\n')
list.append('+ licenses/**\n')
# Allow sync for packages
# Dunno what this branch is about
# Include for safteys sake
list.append('+ packages/\n')
list.append('+ packages/**\n')
# Allow sync for profiles
# Should smarten this up at some point
list.append('+ profiles/\n')
list.append('+ profiles/**\n')
# Allow sync for scripts
list.append('+ scripts/\n')
list.append('+ scripts/**\n')
# Sort the list for readability
list.sort()
# Add the include all files and exclude everything else
list.append('+ /*\n- *')
# Write the pkg list out to the exclude file
open(excl,'w').writelines(''.join(list))That was fast , nice work.This version of the script searches make.conf as requested and checks if the environment variables $PORTDIR or $RSYNC_EXCLUDES are set.
Code: Select all
sdiff -o rsync_excludes rsync_exludes.old rsync_exludes.new
Code: Select all
emerge X
emerge: there are no ebuilds to satisfy "blah/A".
./prlock.py blah/A
emerge sync
emerge X
emerge: there are no ebuilds to satisfy "blah/B".
./prlock.py blah/B
emerge sync
>>>
>>> Timestamps on the server and in the local repository are the same.
>>> Cancelling all further sync action. You are already up to date.
>>>
Code: Select all
Please note: common gentoo-netiquette says you should not sync more
than once a day. Users who abuse the rsync.gentoo.org rotation
may be added to a temporary ban list.


I do. Yes, I like it. I use it in a virtual server enviro; there are lots of good reasons to use it.Oyarsa wrote:Is anyone out there still using this script and finding it usefull?
Is the Warning part of the docs at the top of script not addressing this for you?Oyarsa wrote:It just seams to create problems for me.
For example: I perform a emerge sync and then try to emerge -u system. I often get error
messages due to missing or ~86 masked packages which are new dependencies to my existing installed
packages. This requires a re-sync without the rsync_excludes file which loads all those ebuilds I was trying
to keep off my machine in the first place. How are folks getting around this?
That's the whole point. If I'm not going to update my system, I have no need to sync in the first place.kernelcowboy wrote:If you are updating the system, you should probably not exclude any of the dependencies unless you really really know what you're doing.

Is the system a server with specific responsibility? I think the idea is, build up the server, when your happy, run this script to reduce the storage requirement. Since it's a server, you probably shouldn't update it too often. If it works, don't fix it. (i'm sure some people will disagree.) of course if a feature or bug fix is available, you'll update. but, probably just update that package. Do it deeply, so you keep things square. I do this in a virtual server environment, so I keep the bandwidth usage down, and disk usage down. two things i pay for. the other virtual users on the box probably benefit too. otherwise, i don't see a need for this script. clearly, it takes a bit of work, but if the benefit is real dollars, it's likely worth it.Oyarsa wrote:That's the whole point. If I'm not going to update my system, I have no need to sync in the first place.kernelcowboy wrote:If you are updating the system, you should probably not exclude any of the dependencies unless you really really know what you're doing.
In that case I might as well get rid of portage altogether.
My understanding is that the purpose of this script is to cut down on the number of files transfered by only
considering packages that are actually installed on the machine. Where I seem to be running into trouble
is when updates to installed packages list new packages as dependencies and the ebuilds for these new
dependencies are out of date or missing altogether. What I don't understand is how this script can be
usefull if this is a common occurence.
I didn't write this script, nor do i really understand python much at all. But, my understanding is this. You run it, it looks at your current install; creates a list to exclude all packages you don't currently have need for. following the rest of the scripts instructions, you'll have updated emerge sync to only consider those packages you care about.Oyarsa wrote:I get the impression from your post that I need to maually edit the
rsync_excludes file that is created and remove the excludes that can potentially cause problems. Is this
correct? Maybe I'm missing something -- do I needing to run the script again after every sync?
Code: Select all
prlock.py dev-python/wxPython 
Code: Select all
#!/bin/sh
# WARNING: Use rsync_excludes at your own risk. Make backups. :-)
# This simple script creates an /etc/portage/rsync_excludes file,
# for only syncing Portage (i.e. emerge --sync) to packages you
# have been interested in. It checks the contents of /var/db/pkg/
# for that. You will get a speed gain and can free some space,
# at the cost of Emerge complaining sooner or later about missing
# ebuilds. Duh, add them manually to your existing rsync_excludes
# file. To make it work, empty your /usr/portage directory (your
# distfiles and packages can stay) or create another dir, and
# use PORTDIR="/your-dir" in /etc/make.conf. Always add
# RSYNC_EXCLUDEFROM="/etc/portage/rsync_excludes" to /etc/make.conf,
# and set your profile and architecture below:
#
# Like in: /usr/portage/profiles/$PROFILE/$ARCH/
PROFILE="default-linux"
ARCH="x86"
#
# Good luck!
# Portage default location for the rsync_excludes file.
OUTPUT="/etc/portage/rsync_excludes"
# Backup existing rsync_excludes.
if [ -e $OUTPUT ]; then
mv $OUTPUT $OUTPUT.old || exit
fi
# Create an empty rsync_excludes.
touch $OUTPUT || exit
# Add the categories/packages in /var/db/pkg/*/* (ebuilds etc.)
for i in /var/db/pkg/*/*; do
CAT="`echo $i|sed 's:/var/db/pkg/\([^ ]*\)/.*:\1:'`"
PKG="`echo $i|sed 's:/var/db/pkg/.*/\([^ ]*\)-[0123456789].*:\1:'`"
grep "$CAT" $OUTPUT > /dev/null || (echo "+ $CAT/" >> $OUTPUT)
echo -e "+ $CAT/$PKG/\n+ $CAT/$PKG/**" >> $OUTPUT
done
# I think we need these...
echo "+ eclass/" >> $OUTPUT
echo "+ eclass/**" >> $OUTPUT
echo "+ metadata/" >> $OUTPUT
echo "+ metadata/*/" >> $OUTPUT
# Add metadata for the categories/packages in /var/db/pkg/*/*
for i in /var/db/pkg/*/*; do
CAT="`echo $i|sed 's:/var/db/pkg/\([^ ]*\)/.*:\1:'`"
PKG="`echo $i|sed 's:/var/db/pkg/.*/\([^ ]*\)-[0123456789].*:\1:'`"
grep "/$CAT" $OUTPUT > /dev/null || (echo "+ metadata/cache/$CAT/" >> $OUTPUT)
echo "+ metadata/cache/$CAT/$PKG-*" >> $OUTPUT
done
# ...and these too.
echo "- metadata/cache/**" >> $OUTPUT
echo "+ metadata/dtd/**" >> $OUTPUT
echo "+ metadata/glsa/**" >> $OUTPUT
echo "+ metadata/*" >> $OUTPUT
echo "+ profiles/" >> $OUTPUT
echo "+ profiles/base/" >> $OUTPUT
echo "+ profiles/base/**" >> $OUTPUT
echo "+ profiles/desc/" >> $OUTPUT
echo "+ profiles/desc/**" >> $OUTPUT
echo "+ profiles/$PROFILE/" >> $OUTPUT
echo "+ profiles/$PROFILE/$ARCH/" >> $OUTPUT
echo "+ profiles/$PROFILE/$ARCH/**" >> $OUTPUT
echo "- profiles/$PROFILE/*/" >> $OUTPUT
echo "+ profiles/$PROFILE/*" >> $OUTPUT
echo "+ profiles/updates/" >> $OUTPUT
echo "+ profiles/updates/**" >> $OUTPUT
echo "- profiles/*/" >> $OUTPUT
echo "+ profiles/*" >> $OUTPUT
echo "+ scripts/" >> $OUTPUT
echo "+ scripts/**" >> $OUTPUT
echo "- **/" >> $OUTPUT
echo "+ *" >> $OUTPUTCode: Select all
>>> Updating Portage cache:
Traceback (most recent call last):
File "/usr/bin/emerge", line 2705, in ?
oldcat = portage.catsplit(cp_list[0])[0]
IndexError: list index out of rangeCode: Select all
!!! ARCH is not set... Are you missing the /etc/make.profile symlink?
!!! Is the symlink correct? Is your portage tree complete?Code: Select all
WARNING: usage of RSYNC_EXCLUDEFROM is deprecated, use PORTAGE_RSYNC_EXTRA_OPTS insteadCode: Select all
PORTAGE_RSYNC_EXTRA_OPTS="--exclude-from=/etc/portage/rsync_excludes"Code: Select all
PORTAGE_RSYNC_EXTRA_OPTS="--exclude-from=/etc/portage/rsync_excludes"
Code: Select all
buren ~ # ls /var/db/pkg/
app-admin dev-java media-libs perl-core x11-base
app-arch dev-lang media-sound sys-apps x11-drivers
[...]
Code: Select all
+ app-admin**
+ app-arch**
Code: Select all
app-**
dev-**
games-**
gnome-**
gnustep-**
kde-**
mail-**
media-**
net-**
perl-**
rox-**
sci-**
sec-**
sys-**
www-**
x11-**
xfce-**
Code: Select all
+ eclass**
+ licenses**
+ profiles**
+ scripts**
+ virtual**
Code: Select all
#important parts of portage
+ eclass**
+ licenses**
+ profiles**
+ scripts**
+ virtual**
#whitelist all used parts of the tree
+ app-admin**
+ app-arch**
+ app-benchmarks**
+ app-crypt**
+ app-editors**
+ app-i18n**
+ app-misc**
+ app-portage**
+ app-shells**
+ app-text**
+ dev-db**
+ dev-java**
+ dev-lang**
+ dev-libs**
+ dev-perl**
+ dev-python**
+ dev-tex**
+ dev-util**
+ kde-base**
+ media-fonts**
+ media-gfx**
+ media-libs**
+ media-sound**
+ media-video**
+ net-analyzer**
+ net-dns**
+ net-firewall**
+ net-ftp**
+ net-libs**
+ net-misc**
+ net-nds**
+ net-print**
+ perl-core**
+ sys-apps**
+ sys-boot**
+ sys-devel**
+ sys-fs**
+ sys-kernel**
+ sys-libs**
+ sys-process**
+ www-client**
+ x11-apps**
+ x11-base**
+ x11-drivers**
+ x11-libs**
+ x11-misc**
+ x11-proto**
+ x11-terms**
+ x11-wm**
#blacklist everything
app-**
dev-**
games-**
gnome-**
gnustep-**
kde-**
mail-**
media-**
net-**
perl-**
rox-**
sci-**
sec-**
sys-**
www-**
x11-**
xfce-**
Code: Select all
mv /usr/portage /usr/portage.full
Code: Select all
rm -r /usr/portage
mv /usr/portage.full /usr/portage


If you want to remove parts from the rsync_excludes file, you should *always* remove them from your Portage tree manually. (ebuilds and metadata). Keeping parts in the Portage tree unupdated is not wise. Portage may reuse outdated ebuilds without warning this way.bur wrote:... Example: I only have ethereal in net-analyzer, so if I unmerge ethereal, I can remove the '+ net-analyzer**' line. You can also delete the specific directory from /usr/portage - in this case 'rm -r /usr/portage/net-analyzer'...
Code: Select all
#!/bin/zsh
#
# generates /etc/portage/rsync_excludes
# comments to asdf@uni-koblenz.de
db=(/var/db/pkg/*)
ex=/etc/portage/rsync_excludes
# remove empty directories in /var/db/pkg/
rmdir $db 2>/dev/null
# whitelist system stuff
cat << EOF > $ex
+ eclass**
+ licenses**
+ profiles**
+ scripts**
+ virtual**
EOF
# whitelist used categories
for i in $db
do
echo `basename $i` | awk '{print "+ "$NF"**"}' >> $ex
done
# blacklist everything else
cat << EOF >> $ex
**
EOF