~launchpad-pqm/launchpad/devel

8687.15.18 by Karl Fogel
Add the copyright header block to files under lib/canonical/.
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
3
4
__metaclass__ = type
5
3691.141.13 by kiko
Modify make_pidfile() in an attempt to make it less racy.
6
import tempfile
7
import os
8
import atexit
9
import sys
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
10
from signal import signal, SIGTERM
3691.141.13 by kiko
Modify make_pidfile() in an attempt to make it less racy.
11
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
12
from canonical.config import config
13
6343.3.9 by Barry Warsaw
Put development pid_dir into /var/tmp
14
def pidfile_path(service_name, use_config=None):
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
15
    """Return the full pidfile path for the given service
16
    """
6343.3.9 by Barry Warsaw
Put development pid_dir into /var/tmp
17
    if use_config is None:
18
        use_config = config
19
    return os.path.join(use_config.canonical.pid_dir, '%s-%s.pid' % (
20
        use_config.instance_name, service_name
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
21
        ))
22
23
24
def make_pidfile(service_name):
25
    """Write the current process id to a PID file.
4785.3.7 by Jeroen Vermeulen
Removed whitespace at ends of lines
26
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
27
    Also installs an atexit handler to remove the file on process termination.
28
29
    Also installs a SIGTERM signal handler to remove the file on SIGTERM.
30
    If you install your own handler, you will want to call remove_pidfile
31
    inside it.
32
    """
33
    pidfile = pidfile_path(service_name)
34
    if os.path.exists(pidfile):
35
        raise RuntimeError("PID file %s already exists. Already running?" %
36
                pidfile)
37
38
    atexit.register(remove_pidfile, service_name)
39
    def remove_pidfile_handler(*ignored):
40
        sys.exit(-1 * SIGTERM)
41
    signal(SIGTERM, remove_pidfile_handler)
42
4330.1.6 by Stuart Bishop
Create PID files in the correct directory
43
    fd, tempname = tempfile.mkstemp(dir=os.path.dirname(pidfile))
3691.141.13 by kiko
Modify make_pidfile() in an attempt to make it less racy.
44
    outf = os.fdopen(fd, 'w')
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
45
    outf.write(str(os.getpid())+'\n')
46
    outf.flush()
47
    outf.close()
3691.141.13 by kiko
Modify make_pidfile() in an attempt to make it less racy.
48
    os.rename(tempname, pidfile)
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
49
50
6343.3.9 by Barry Warsaw
Put development pid_dir into /var/tmp
51
def remove_pidfile(service_name, use_config=None):
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
52
    """Remove the PID file.
53
54
    This should only be needed if you are overriding the default SIGTERM
55
    signal handler.
56
    """
6343.3.9 by Barry Warsaw
Put development pid_dir into /var/tmp
57
    pidfile = pidfile_path(service_name, use_config)
58
    pid = get_pid(service_name, use_config)
59
    if pid is None:
60
        return
61
    if use_config is not None or pid == os.getpid():
62
        os.unlink(pidfile)
63
64
65
def get_pid(service_name, use_config=None):
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
66
    """Return the PID for the given service as an integer, or None
67
68
    May raise a ValueError if the PID file is corrupt.
69
70
    This method will only be needed by service or monitoring scripts.
71
72
    Currently no checking is done to ensure that the process is actually
73
    running, is healthy, or died horribly a while ago and its PID being
74
    used by something else. What we have is probably good enough.
75
    """
6343.3.9 by Barry Warsaw
Put development pid_dir into /var/tmp
76
    pidfile = pidfile_path(service_name, use_config)
1937 by Canonical.com Patch Queue Manager
[r=jamesh] Common PID file handing module
77
    try:
78
        pid = open(pidfile).read()
79
        return int(pid)
80
    except IOError:
81
        return None
82
    except ValueError:
83
        raise ValueError("Invalid PID %s" % repr(pid))