This file is indexed.

/usr/lib/python2.7/dist-packages/maasserver/models/bootimage.py is in python-django-maas 1.5.4+bzr2294-0ubuntu1.2.

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
161
162
163
164
165
166
167
168
# Copyright 2012-2014 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Registration of available boot images."""

from __future__ import (
    absolute_import,
    print_function,
    unicode_literals,
    )

str = None

__metaclass__ = type
__all__ = [
    'BootImage',
    ]


from django.db.models import (
    CharField,
    ForeignKey,
    Manager,
    )
from maasserver import DefaultMeta
from maasserver.models.nodegroup import NodeGroup
from maasserver.models.timestampedmodel import TimestampedModel
from maasserver.utils.orm import get_first


class BootImageManager(Manager):
    """Manager for model class.

    Don't import or instantiate this directly; access as `BootImage.objects`.
    """

    def get_by_natural_key(self, nodegroup, architecture, subarchitecture,
                           release, purpose, label):
        """Look up a specific image."""
        return self.get(
            nodegroup=nodegroup, architecture=architecture,
            subarchitecture=subarchitecture, release=release,
            purpose=purpose, label=label)

    def register_image(self, nodegroup, architecture, subarchitecture,
                       release, purpose, label):
        """Register an image if it wasn't already registered."""
        self.get_or_create(
            nodegroup=nodegroup, architecture=architecture,
            subarchitecture=subarchitecture, release=release,
            purpose=purpose, label=label)

    def have_image(self, nodegroup, architecture, subarchitecture, release,
                   purpose, label=None):
        """Is an image for the given kind of boot available?"""
        if label is None:
            label = "release"
        try:
            self.get_by_natural_key(
                nodegroup=nodegroup, architecture=architecture,
                subarchitecture=subarchitecture, release=release,
                purpose=purpose, label=label)
            return True
        except BootImage.DoesNotExist:
            return False

    def get_default_arch_image_in_nodegroup(self, nodegroup, series, purpose):
        """Return any image for the given nodegroup, series, and purpose.

        Prefers `i386` images if available.  Returns `None` if no images match
        requirements.
        """
        images = BootImage.objects.filter(
            release=series, nodegroup=nodegroup, purpose=purpose)
        for image in images:
            # Prefer i386, any available subarchitecture (usually just
            # "generic").  It will work for most cases where we don't know
            # the actual architecture.
            if image.architecture == 'i386':
                return image
        images = images.order_by('architecture')
        return get_first(images)

    def _get_bootable_architectures(self, nodegroup, purpose):
        """Return architecture/subarchitecture pairs with boot images.

        :param nodegroup: The `NodeGroup` whose boot images should be queried.
        :param purpose: Boot purpose, e.g. `install` or `commissioning`.
            Only consider architectures for which `nodegroup` has images whose
            `purpose` matches.
        :return: A set of architecture names, in `arch/subarch` format.
        """
        query = BootImage.objects.filter(nodegroup=nodegroup, purpose=purpose)
        arch_pairs = query.values_list('architecture', 'subarchitecture')
        return {'%s/%s' % pair for pair in arch_pairs}

    def get_usable_architectures(self, nodegroup):
        """Return the list of usable architectures for a nodegroup.

        Return the architectures for which the nodegroup has at least one
        commissioning image and at least one install image.
        """
        arches_commissioning = self._get_bootable_architectures(
            nodegroup, 'commissioning')
        arches_install = self._get_bootable_architectures(
            nodegroup, 'install')
        return arches_commissioning & arches_install

    def get_latest_image(self, nodegroup, architecture, subarchitecture,
                         release, purpose):
        """Return the latest image for a set of criteria."""
        return BootImage.objects.filter(
            nodegroup=nodegroup, architecture=architecture,
            subarchitecture=subarchitecture, release=release,
            purpose=purpose).order_by('id').last()


class BootImage(TimestampedModel):
    """Available boot image (i.e. kernel and initrd).

    Each `BootImage` represents a type of boot for which a boot image is
    available.  The `maas-import-pxe-files` script imports these, and the
    TFTP server provides them to booting nodes.

    If a boot image is missing, that may mean that the import script has not
    been run yet, or has failed; or that it was not configured to provide
    that particular image.

    Fields correspond directly to values used in the `tftppath` module.
    """

    class Meta(DefaultMeta):
        unique_together = (
            ('nodegroup', 'architecture', 'subarchitecture', 'release',
             'purpose', 'label'),
            )

    objects = BootImageManager()

    # Nodegroup (cluster controller) that has the images.
    nodegroup = ForeignKey(NodeGroup, null=False, editable=False, unique=False)

    # System architecture (e.g. "i386") that the image is for.
    architecture = CharField(max_length=255, blank=False, editable=False)

    # Sub-architecture, e.g. a particular type of ARM machine that needs
    # different treatment.  (For architectures that don't need these
    # such as i386 and amd64, we use "generic").
    subarchitecture = CharField(max_length=255, blank=False, editable=False)

    # Ubuntu release (e.g. "precise") that the image boots.
    release = CharField(max_length=255, blank=False, editable=False)

    # Boot purpose (e.g. "commissioning" or "install") that the image is for.
    purpose = CharField(max_length=255, blank=False, editable=False)

    # "Label" as in simplestreams parlance. (e.g. "release", "beta-1")
    label = CharField(
        max_length=255, blank=False, editable=False, default="release")

    def __repr__(self):
        return "<BootImage %s/%s-%s-%s-%s>" % (
            self.architecture,
            self.subarchitecture,
            self.release,
            self.purpose,
            self.label,
            )