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