This file is indexed.

/usr/lib/python2.7/dist-packages/charmtools/bundles.py is in charm-tools 2.1.2-0ubuntu4.

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
import glob
import os
import re
import yaml

from linter import Linter
import jujubundlelib.validation


charm_url_includes_id = re.compile(r'-\d+$').search


class BundleLinter(Linter):
    def validate(self, data):
        """Supplement jujubundlelib validation with some extra checks.

        """
        if 'series' not in data and 'inherits' not in data:
            self.info("No series defined")

        if 'services' in data:
            for svc, sdata in data['services'].items():
                if 'annotations' not in sdata:
                    self.warn('%s: No annotations found, will render '
                              'poorly in GUI' % svc)
                if ('charm' in sdata and
                        not charm_url_includes_id(sdata['charm'] or '')):
                    self.warn(
                        '%s: charm URL should include a revision' % svc)
        else:
            if 'inherits' not in data:
                self.err("No services defined")

    def proof(self, bundle):
        data = bundle.bundle_file()
        if not bundle.is_v4(data):
            self.err(
                'This bundle format is no longer supported. See '
                'https://jujucharms.com/docs/stable/charms-bundles '
                'for the supported format.')
            return

        readmes = glob.glob(os.path.join(bundle.bundle_path, 'README*'))
        if len(readmes) < 1:
            self.warn('No readme file found')

        errors = jujubundlelib.validation.validate(data)
        for error in errors:
            self.err(error)
        self.validate(data)


class Bundle(object):
    def __init__(self, path, debug=False):
        self.bundle_path = os.path.abspath(path)
        self.supported_files = [
            'bundle.yaml', 'bundle.json',    # v4
            'bundles.yaml', 'bundles.json',  # v3
        ]
        self.debug = debug
        if not self.is_bundle():
            raise Exception('Not a bundle')

    def is_bundle(self):
        for f in self.supported_files:
            if os.path.isfile(os.path.join(self.bundle_path, f)):
                break
        else:
            return False

        if os.path.isfile(os.path.join(self.bundle_path, 'metadata.yaml')):
            return False

        return True

    def is_v4(self, data=None):
        if data is None:
            data = self.bundle_file()
        v4_keys = {'services', 'relations', 'machines', 'series'}
        bundle_keys = set(data.keys())
        return bool(v4_keys & bundle_keys)

    def bundle_file(self, parse=True):
        for f in self.supported_files:
            if os.path.isfile(os.path.join(self.bundle_path, f)):
                with open(os.path.join(self.bundle_path, f)) as d:
                    return yaml.safe_load(d.read()) if parse else d.read()

        raise Exception('No bundle.json or bundle.yaml file found')

    def proof(self):
        lint = BundleLinter(self.debug)
        lint.proof(self)
        return lint.lint, lint.exit_code

    def promulgate(self):
        pass