This file is indexed.

/usr/lib/python2.7/dist-packages/deployer/vcs.py is in juju-deployer 0.6.4-0ubuntu1.

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
import subprocess
import os
import re

from bzrlib.workingtree import WorkingTree

from .utils import ErrorExit


class Vcs(object):

    err_update = (
        "Could not update branch %(path)s from %(branch_url)s\n\n %(output)s")
    err_branch = "Could not branch %(branch_url)s to %(path)s\n\n %(output)s"
    err_is_mod = "Couldn't determine if %(path)s was modified\n\n %(output)s"
    err_pull = (
        "Could not pull branch @ %(branch_url)s to %(path)s\n\n %(output)s")
    err_cur_rev = (
        "Could not determine current revision %(path)s\n\n %(output)s")

    def __init__(self, path, origin, log):
        self.path = path
        self.log = log
        self.extended_options = self.get_extended_options(origin)

        if self.extended_options:
            self.origin = origin.split("#")[0]
        else:
            self.origin = origin

    def _call(self, args, error_msg, cwd=None, stderr=()):
        try:
            if stderr is not None and not stderr:
                stderr = subprocess.STDOUT
            output = subprocess.check_output(
                args, cwd=cwd or self.path, stderr=stderr)
        except subprocess.CalledProcessError, e:
            self.log.error(error_msg % self.get_err_msg_ctx(e))
            raise ErrorExit()
        return output.strip()

    def get_err_msg_ctx(self, e):
        return {
            'path': self.path,
            'branch_url': self.origin,
            'exit_code': e.returncode,
            'output': e.output,
            'vcs': self.__class__.__name__.lower()}

    def get_extended_options(self, origin):
        regexp = re.compile(r"[\?#&](?P<name>[^&=]+)=(?P<value>[^&=]+)")
        matched = regexp.findall(origin)

        if matched:
            ret = dict()
            for option in matched:
                (name, value) = option
                if name in ret:
                    raise Exception("%s option already defined" % name)
                ret[name] = value
            return ret
        return {}

    def get_cur_rev(self):
        raise NotImplementedError()

    def update(self, rev=None):
        raise NotImplementedError()

    def branch(self):
        raise NotImplementedError()

    def pull(self):
        raise NotImplementedError()

    def is_modified(self):
        raise NotImplementedError()

    # upstream missing revisions?


class Bzr(Vcs):

    def get_cur_rev(self):
        params = ["bzr", "revno", "--tree"]
        return self._call(params, self.err_cur_rev, stderr=None)

    def update(self, rev=None):
        params = ["bzr", "up"]
        if rev:
            params.extend(["-r", str(rev)])
        self._call(params, self.err_update)

    def branch(self):
        params = ["bzr", "co", "--lightweight", self.origin, self.path]
        cwd = os.path.dirname(os.path.dirname(self.path))
        if not cwd:
            cwd = "."
        self._call(params, self.err_branch, cwd)

    def is_modified(self):
        # To replace with bzr cli, we need to be able to detect
        # changes to a wc @ a rev or @ trunk.
        tree = WorkingTree.open(self.path)
        return tree.has_changes()


class Git(Vcs):

    def get_cur_rev(self):
        params = ["git", "rev-parse", "HEAD"]
        return self._call(params, self.err_cur_rev)

    def update(self, rev=None):
        params = ["git", "reset", "--merge"]
        if rev:
            params.append(rev)
        self._call(params, self.err_update)

    def branch(self):
        params = ["git", "clone", "--depth", "1"]
        # Deal with branches in the format
        # <repository-url>;<branch>
        components = self.origin.split(';')
        if len(components) == 2:
            params += ["--branch", components[1],
                       components[0], self.path]
        else:
            params += [self.origin, self.path]
        cwd = os.path.dirname(os.path.dirname(self.path))
        if not cwd:
            cwd = "."

        self._call(params, self.err_branch, cwd)

        change_ref = self.extended_options.get('changeref', None)
        if change_ref:
            change_ref = 'refs/changes/{}/{}'.format(
                change_ref.split("/")[0][-2:], change_ref)

            self._call(["git", "fetch", "--depth", "1",
                        self.origin, change_ref],
                       self.err_branch, self.path)
            self._call(["git", "checkout", "FETCH_HEAD"], self.err_branch,
                       self.path)

    def is_modified(self):
        params = ["git", "status", "-s"]
        return bool(self._call(params, self.err_is_mod).strip())

    def get_remote_origin(self):
        params = ["git", "config", "--get", "remote.origin.url"]
        return self._call(params, "")