To facilitate repository creation by Windows users on
a Linux SVN server, without requiring user access to
the Linux box, I created the attached python program
and associated start script for /etc/init.d. The
python program monitors a give directory for
(sub-)directory creation, and creates a subversion
repository on the newly created directory. The start
script starts and stops the python script with the
user-specified SVNRepoRoot, and logs to a
user-specified directory.
The python script is based on the test script which
comes with python-fam, which handles signals real
nicely. It could be revised to clean up the messages
that end up in the log file.
Hope this helps someone else, and feedback regarding
improvements is always welcome.
Cheers,
Murthy
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
#!/usr/bin/python
#
# FN: ReposCreateLite.py
# DT: 2004/07/29 18:19:00
# AU: S. Murthy Kambhampaty
# AB: Monitors a given directory for object creation,
# - If a directory is created, creates a subversion repository in it
# - If the created object is other than a directory, it is deleted!!!
#
MonitorMan="SysAdmin@myDN"
MXDN="@myDN" # Mail exchanger's domain name
import commands, errno, _fam, getopt, os, signal \
, select, smtplib, string, sys, time
from time import localtime, strftime
if len(sys.argv) != 2:
print 'usage: %s <directory>' % sys.argv[0]
sys.exit(1)
# Get the name of the repository root and make sure that it exists
RepoRoot=sys.argv[1]
if not(os.path.isdir(RepoRoot)):
print >> sys.stderr, "The given path \"" +RepoRoot +"\" is not a directory. Exiting ..."
sys.exit(2)
else:
os.chdir(RepoRoot)
# Get the repository owner's name, uid, and gid; ; BTW, python
# does not do usernames
RRUser=commands.getoutput(r'stat -c %U "' +RepoRoot +r'"')
RRStat=os.stat(RepoRoot)
# Define some signal handlers
def handle_stop(signum, frame):
global suspend
print 'Suspended!'
suspend=1
def handle_cont(signum, frame):
global cont
print 'Resumed!'
signal.signal(signal.SIGCONT, handle_cont)
cont=1
def handle_int(signum, frame):
global intr
print 'Interrupted!'
signal.signal(signal.SIGINT, handle_int)
intr=1
def handle_usr1(signum, frame):
global usr1
print 'Got USR1!'
signal.signal(signal.SIGUSR1, handle_usr1)
usr1=1
def handle_usr2(signum, frame):
global usr2
print 'Got USR2!'
signal.signal(signal.SIGUSR2, handle_usr2)
usr2=1
signal.signal(signal.SIGTSTP, handle_stop)
signal.signal(signal.SIGCONT, handle_cont)
signal.signal(signal.SIGINT, handle_int)
signal.signal(signal.SIGUSR1, handle_usr1)
signal.signal(signal.SIGUSR2, handle_usr2)
suspend = None
cont = None
intr = None
usr1 = None
usr2 = None
# Define the action to be taken on folder creation
def MakeSVNRepo(fev):
"""Convert newly created directories into subversion repositories
If the newly created object is not a directory, it is deleted.
Also, Windows gives new folders a defaul name of "New Folder"
until a real name is assigned. Simply screening "New Folder"
seems to solve this. It may be preferable to match all names
"New Folder*", but as this script is stopped and started with
the host operating system in the present application, it is not
necessary.
"""
#global MonitorMan, MXDN, RRUser, RRStat
_FAMEvtCode, _RName=(fev.code2str(), str(fev.filename))
if _FAMEvtCode != "created": return
if _RName == "New Folder": return
if os.path.isdir(_RName) == False:
# This is a little cold, but only directories belong here
# so delete non-directories
_PTime=strftime("%x %X", localtime())
os.remove(_RName)
print >> sys.stderr, "%s: Removing non-directory \"%s\"" % (_PTime, _RName)
sys.stderr.flush()
return
# If the altered object clears all of the above tests it's
# ready to become a directory. This is not totally failsafe
# but mostly works.
# Get some info about the altered object
_RUser=commands.getoutput(r'stat -c %U "' +_RName +r'"')
_Rstat=os.stat(_RName)
_PTime=strftime("%x %X", localtime(_Rstat.st_ctime))
# Change ownership to the repository root's user
os.chown(_RName, RRStat.st_uid, RRStat.st_gid)
# Now create the repository
_RC=commands.getoutput(r'su - ' +RRUser +r' -c "umask 002; svnadmin create \"' +_RName +r'\""')
# _RV=commands.getoutput(r'su - ' +RRUser +r' -c "svnadmin verify \"' +_RName +r'\""')
# Prepare and send an e-mail notifying the folder creator
# that her repository was created
_toAddr=_RUser +MXDN
_theMsg=("Subject: SVN repository created\n\n%s: The repository \"%s\" was created for \"%s\"" % (_PTime, _RName, _RUser))
_MailSVR=smtplib.SMTP('localhost')
_MailSVR.sendmail(MonitorMan, _toAddr, _theMsg)
_MailSVR.quit()
print >> sys.stdout, "%s: Created repository \"%s\" for \"%s\"" % (_PTime, _RName, _RUser)
sys.stdout.flush()
# Get started
conn=_fam.open()
fReq=conn.monitorDirectory(RepoRoot, None)
# Here's where the action begins, but it comes after
# a long list of signal response instructions
while True:
if suspend:
fReq.suspendMonitor()
print >> sys.stdout, 'Suspended monitoring of request %i' % fReq.requestID()
suspend=None
signal.signal(signal.SIGTSTP, handle_stop)
sys.stdout.flush()
if cont:
fReq.resumeMonitor()
print >> sys.stdout, 'Resumed monitoring of request %i' % fReq.requestID()
cont=None
sys.stdout.flush()
if intr:
# The dealloc methods of all objects should handle
# FAMCancelMonitor and FAMClose
sys.exit(0)
if usr1:
# Cancel all requests, close the connection, and reopen it.
# This makes sure long-lived clients can connect, monitor, and
# disconnect repeatedly without leaking.
usr1 = None
sleeptime = 1
print >> sys.stdout, 'Cancelling monitoring of request %i' % fReq.requestID()
fReq.cancelMonitor()
conn.close()
print >> sys.stdout, 'Closed connection, sleeping %d...' % sleeptime
time.sleep(sleeptime)
conn=_fam.open()
fReq=conn.monitorDirectory(RepoRoot, None)
sys.stdout.flush()
if usr2:
# Clean things up like a well-behaved client and exit.
print >> sys.stdout, 'Cancelling monitoring of request %i' % fReq.requestID()
fReq.cancelMonitor()
conn.close()
print >> sys.stdout, 'Closed connection'
sys.exit(0)
try:
ri, ro, re=select.select([conn], [], [])
except select.error, er:
errnumber, strerr=er
if errnumber == errno.EINTR:
continue
else:
print strerr
sys.exit(1)
while conn.pending():
fev=conn.nextEvent()
MakeSVNRepo(fev)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tortoisesvn.tigris.org
For additional commands, e-mail: dev-help@tortoisesvn.tigris.org
Received on Mon Aug 9 20:43:16 2004