Setting up a Perforce proxy server on Ubuntu

by Julian on January 15th, 2007

One of the more important things I’ve been wanting to do, is to set up a perforce proxy to connect to the work server.

That way, it can sit in the background periodically updating itself (not quite but see below), and when I want to sync, it should be nice and fast. In theory. In reality I suspect it won’t be so clear cut.

Running a perforce proxy is easy, it’s just a case of choosing a root for the cache, telling it what port to listen on, and what the target server is:

p4p -p 1667 -t workserver:1666 -r /perforce/p4p/cache -L /perforce/p4p/p4p.log

That’s nice, but I want this to start automatically when I boot up, and an easy way to quickly stop and start it. I need a script in /etc/init.d. Here’s mine:

#! /bin/sh
# p4pinit
# Startup script for Perforce Proxy server.
# Check out the man page for start-stop-daemon. Notice
# I use -b to run p4p in the background. p4p has a similar
# option, but I didn't have as much success.

DAEMON=/usr/local/bin/p4p
P4P_NAME=p4p
P4P_DESC="Perforce Proxy"
P4P_CACHE=/perforce/p4p/cache
P4P_PORT=1667
P4P_TARGET=workserver.somewhere.co.uk:1666
P4P_LOG=/perforce/p4p/p4p.log

# Check p4p exists
test -x $DAEMON || exit 0

case "$1" in

  start)
	echo -n "Starting $P4P_DESC: "
	start-stop-daemon --start -b -m \
                --pidfile /var/run/$P4P_NAME.pid \
                --exec $DAEMON \
                -- -p $P4P_PORT -t $P4P_TARGET \
                -r $P4P_CACHE -L $P4P_LOG
	echo "$P4P_NAME."
	;;

  stop)
	echo -n "Stopping $P4P_DESC: "
	start-stop-daemon --stop \
                --pidfile /var/run/$P4P_NAME.pid \
                --signal KILL \
                --exec $DAEMON \
                --oknodo
	echo "$P4P_NAME."
	;;

  *)
	echo "Usage: $0 {start|stop}"
	exit 1
	;;
esac

exit 0

Once you’ve done this, you need to call update-rc.d p4pinit defaults. This will ensure that p4p is started when you boot up. This will create symlinks to p4pinit in the directories /etc/rcX.d etc…

Now synching is just a case of pointing the client at homeserver:1667, rather than the default :-) However, you need to pre-load the cache and ideally keep it synched regularly after that.

Unfortunately this is where Perforce falls down, as the proxy has no means to do this itself; You’re required to set up another client spec, and use that to sync and fill the proxy’s cache. This could mean double the files on your server, which isn’t great.

What you can do, rather cunningly, is set your client root to /dev/null. When you sync you’ll get errors that it can’t write the file/create the directory, but by that point the file has been downloaded to the cache. To quote Tim O’Mahony of Perforce support:

…The errors mean that you can’t write anything to db.have for those files, but by this time you already have downloaded them to the proxy. That means that every time you then run a p4 sync on this client it is the same as running a full “p4 sync”. Files that aren’t on the proxy will simply be got from the server…

In other words, if you sync later, p4 will want to re-grab those files. However it will take them from the proxy, so it will only download genuinely new files. If you don’t want the output in your logs (like me), then you can run p4 flush immediately after the sync, to convince the server that you really do have those files:

p4 sync //depot/something/to/sync/...
p4 flush //depot/something/to/sync/...

Hope this helps someone.

Since writing, I found that in some situations (that I’ve yet to fathom) the proxy server delivers files from the server rather than itself. To see where your files are coming from, you can use the -Zproxyverbose flag to your p4 command.

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS