This file is indexed.

/usr/share/pyshared/juju/lib/service.py is in juju-0.7 0.7-0ubuntu2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from twisted.internet.defer import inlineCallbacks
from twisted.internet.threads import deferToThread

from juju.errors import ServiceError

import os
import subprocess


def _check_call(args, env=None, output_path=None):
    if not output_path:
        output_path = os.devnull

    with open(output_path, "a") as f:
        return subprocess.check_call(
            args,
            stdout=f.fileno(), stderr=f.fileno(),
            env=env)


def _cat(filename, use_sudo=False):
    args = ("cat", filename)
    if use_sudo and not os.access(filename, os.R_OK):
        args = ("sudo",) + args

    p = subprocess.Popen(
        args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout_data, _ = p.communicate()
    r = p.returncode
    return (r, stdout_data)


class TwistedDaemonService(object):
    """Manage the starting and stopping of an Agent.

    This manager tracks the agent via its --pidfile. The pidfile argument
    specifies the location of the pid file that is used to track this service.

    """
    def __init__(self, name, pidfile, use_sudo=False):
        self._name = name
        self._use_sudo = use_sudo
        self._description = None
        self._environ = None
        self._command = None
        self._daemon = True
        self._output_path = None

        self._pid_path = pidfile
        self._pid = None

    @property
    def output_path(self):
        if self._output_path is not None:
            return self._output_path
        return "/tmp/%s.output" % self._name

    @output_path.setter
    def output_path(self, path):
        self._output_path = path

    def set_description(self, description):
        self._description = description

    def set_daemon(self, value):
        self._daemon = bool(value)

    def set_environ(self, environ):
        for k, v in environ.items():
            environ[k] = str(v)
        self._environ = environ

    def set_command(self, command):
        if self._daemon:
            if "--pidfile" not in command:
                command += ["--pidfile", self._pid_path]
            else:
                # pid file is in command (consume it for get_pid)
                idx = command.index("--pidfile")
                self._pid_path = command[idx+1]

        self._command = command

    @inlineCallbacks
    def _trash_output(self):
        if os.path.exists(self.output_path):
            # Just using os.unlink will fail when we're running TEST_SUDO
            # tests which hit this code path (because root will own
            # self.output_path)
            yield self._call("rm", "-f", self.output_path)

        if os.path.exists(self._pid_path):
            yield self._call("rm", "-f", self._pid_path)

    def _call(self, *args, **kwargs):
        if self._use_sudo:
            if self._environ:
                _args = ["%s=%s" % (k, v) for k, v in self._environ.items()]
            else:
                _args = []
            _args.insert(0, "sudo")
            _args.extend(args)
            args = _args

        return deferToThread(_check_call, args, env=self._environ,
                             output_path=self.output_path)

    def install(self):
        if self._command is None:
            raise ServiceError("Cannot manage agent: %s no command set" % (
                self._name))

    @inlineCallbacks
    def start(self):
        if (yield self.is_running()):
            raise ServiceError(
                "%s already running: pid (%s)" % (
                    self._name, self.get_pid()))

        if not self.is_installed():
            yield self.install()

        yield self._trash_output()
        yield self._call(*self._command, output_path=self.output_path)

    @inlineCallbacks
    def destroy(self):
        if (yield self.is_running()):
            yield self._call("kill", self.get_pid())
        yield self._trash_output()

    def get_pid(self):
        if self._pid != None:
            return self._pid

        if not os.path.exists(self._pid_path):
            return None
        r, data = _cat(self._pid_path, use_sudo=self._use_sudo)
        if r != 0:
            return None

        # verify that pid is a number but leave
        # it as a string suitable for passing to kill
        if not data.strip().isdigit():
            return None
        pid = data.strip()
        self._pid = pid
        return self._pid

    def is_running(self):
        pid = self.get_pid()
        if not pid:
            return False
        proc_file = "/proc/%s" % pid
        if not os.path.exists(proc_file):
            return False
        return True

    def is_installed(self):
        return False