P4dctl
From PDWiki
| ||||||||||||
Contents |
About p4dctl
I was always frustrated by how hard it was to get a good (init) script for starting and stopping Perforce Services: one that worked on most UNIX platforms, and allowed for the fact that while the servers wouldn't run as root, both root and non-root users could start and stop them. Then there's the issue of 'pidfiles': if your startup script creates a pidfile owned by root, the pidfile can become stale if another user (perhaps 'perforce') stops and restarts the server; often the permissions on these files mean that even if the other user wants to do the right thing, they can be thwarted.
Most Perforce sites will also run more than one type of Perforce server (P4D/P4Web/P4FTPD etc.), and the problem is compounded the more servers you run.
So I wrote p4dctl. It allows the administrator to specify all the Perforce services running on a machine in a single, simple text file and allows root and non-root users to start and stop the services. Naturally, non-root users can only affect servers they own. Since p4dctl is a setuid root executable, it uses its root privileges to manage the pid files (for security reasons, it drops these privileges for all other actions), so even if a non-root user is restarting a service, the pidfile will be correctly maintained. This is important for those services that must be stopped using a SIGTERM.
Recent Changes
- Change 6319 on 2008/04/21 by tony_smith@tony_smith-blast-public
- Fix to segfault on bad command syntax. If someone ran almost any
command without specifying either the -a flag, or a server name
then p4dctl would segfault. This changes reworks the command line
handling to throw a usage-message in that case - Change 6285 on 2008/03/18 by tony_smith@tony_smith-barney-public
- Add support for starting arbitrary daemons through this framework
using configuration entries like this:
other <name>
{
Execute = <binary>
Owner = <username>
[ Port = <listen port (if any)> ]
[ Umask = <umask> ]
PATH = "/usr/bin: etc. etc."
} - Change 6240 on 2008/02/27 by tony_smith@tony_smith-home
- Correct copyright dates in LICENSE file.
- Change 6184 on 2008/02/12 by tony_smith@tony_smith-finbar
- Some minor changes to debugging output
- Change 6152 on 2008/01/21 by tony_smith@tony_smith-barney-public
- Add support for configuring the umask with which Perforce
services should run to p4dctl. If unspecified, the default umask
is 022.
Features
- Common interface for root and non-root users
- Non-root users limited to services they own
- Central configuration of all services
- Bulk start/stop of services
- all services
- all services of a particular type
- all services by name
- Easy way to check status of all services
- Maintains pidfiles under /var/run
- Sets process name intelligently (e.g. 'p4d [main/1666]' )
- Designed to be a secure setuid root executable
Configuration
For security reasons, the configuration file path is hard-coded into p4dctl: /etc/p4d.conf. This ensures that only a privileged user can create or edit the file.
A sample configuration looks like this:
#-------------------------------------------------------------------------------
# Global environment variables - passed to ALL services
#-------------------------------------------------------------------------------
P4DEBUG = server=3
P4LOG = log
P4CONFIG = .p4config
#-------------------------------------------------------------------------------
# Server specifications
#-------------------------------------------------------------------------------
p4d main
{
Owner = perforce
Execute = /usr/local/bin/p4d
Umask = 077
P4ROOT = /home/perforce/p4-main
P4JOURNAL = journal
P4PORT = 1666
PATH = /bin:/usr/bin:/usr/local/bin
}
p4web main
{
Owner = perforce
Execute = /usr/local/bin/p4web
Args = "-b"
P4WEBPORT = 8080
P4PORT = 1666
P4CLIENT = p4webclient
PATH = /bin:/usr/bin:/usr/local/bin
}
Notice that the service is given a name (in this case both services use 'main'), and an owner. The idea is that only root, and the user 'perforce' can manipulate the main servers, and the environments of the servers are tightly controlled.
Support
This software is not an officially supported Perforce product. Please contact me directly for help.
Example Usage
Using the configuration file above, here are some example commands showing how p4dctl can be used:
Starting All Servers by Name
p4dctl start main
Note that the example above would start both the P4D and P4Web servers - quite a simple way of managing groups of servers.
Sample Init Script
This is where it all started, so there wouldn't be much point in doing this if I didn't show you how to use this in an init script! Here's the one I use on Debian boxes:
PROG=/usr/local/bin/p4dctl
[ -x $PROG ] || exit 0
case "$1" in
start) log_begin_msg "Starting Perforce services..."
$PROG -q start -a
log_end_msg $?
;;
stop) log_begin_msg "Stopping Perforce services..."
$PROG -q stop -a
log_end_msg $?
;;
restart) log_begin_msg "Restarting Perforce servicesa..."
$PROG -q restart -a
log_end_msg $?
;;
*) log_success_msg "Usage: /etc/init.d/p4d start|stop|restart"
exit 1
;;
esac
exit 0
Obviously there's some Debian-specific stuff in there, but the main point is that the simple act of starting and stopping all services is reduced to a one-liner.
Downloads
Most people should build p4dctl from the source. To do so, you'll need the Perforce C++ API for your platform, a suitable C++ compiler, and Perforce Jam.
There are a couple of Linux binaries available from the Public Depot that people are welcome to use. If other platforms are required, please contact me.
Command Line Syntax
Global Syntax
p4dctl [global options] <command> [options] [<service name>] Where 'global options' are: -c <path> Path to configuration file (/etc/p4d.conf) -p <pid path> Path to pid file directory (/var/run) -q Quiet mode -v Verbose output Recognised commands are: start Start specified servers stop Stop specified servers restart Restart specified servers status Check the status of specified servers checkpoint Checkpoint specified P4D servers journal Rotate journals of specified P4D servers
Start Command Syntax
p4dctl [global options] start [options] [<name>] Where [options] are: -a Start all servers -t <type> Start only servers of specified type
If <name> is specified, then the operation is limited to servers with that name.
Stop Command Syntax
p4dctl [global options] stop [options] [<name>] Where [options] are: -a Stop all servers -t <type> Stop only servers of specified type
If <name> is specified, then the operation is limited to servers with that name.
Restart Command Syntax
p4dctl [global options] restart [options] [<name>] Where [options] are: -a Restart all servers -t <type> Restart only servers of specified type
If <name> is specified, then the operation is limited to servers with that name.
Status Command Syntax
p4dctl [global options] status [options] [<name>] Where [options] are: -a Check status of all servers -t <type> Check only servers of specified type
If <name> is specified, then the operation is limited to servers with that name.
LICENSE
Copyright (c) Perforce Software, Inc., 1997-2008. All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE
SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
