~allenap/maas/xxx-a-thon

« back to all changes in this revision

Viewing changes to src/maasserver/models/filesystem.py

  • Committer: LaMont Jones
  • Date: 2016-03-07 23:20:52 UTC
  • mfrom: (4657.1.84 maas)
  • mto: (4657.1.93 maas)
  • mto: This revision was merged to the branch mainline in revision 4660.
  • Revision ID: lamont@canonical.com-20160307232052-rgfxbq7dujj6s093
MergeĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
        on the deployed operating system.
62
62
    """
63
63
 
 
64
    # All filesystem types.
 
65
    TYPES = frozenset(
 
66
        fstype for fstype, _ in FILESYSTEM_TYPE_CHOICES)
 
67
 
 
68
    # Filesystem types that expect to be mounted into the host's filesystem.
 
69
    # Essentially this means all filesystems except swap.
 
70
    TYPES_REQUIRING_MOUNT_POINT = frozenset(
 
71
        fstype for fstype, _ in FILESYSTEM_TYPE_CHOICES
 
72
        if fstype != FILESYSTEM_TYPE.SWAP)
 
73
 
 
74
    # Filesystem types that require storage on a block special device, i.e. a
 
75
    # block device or partition.
 
76
    TYPES_REQUIRING_STORAGE = frozenset(
 
77
        fstype for fstype, _ in FILESYSTEM_TYPE_CHOICES
 
78
        if fstype != FILESYSTEM_TYPE.RAMFS and fstype != FILESYSTEM_TYPE.TMPFS)
 
79
 
64
80
    class Meta(DefaultMeta):
65
81
        """Needed for South to recognize this model."""
66
82
        unique_together = (
83
99
    block_device = ForeignKey(
84
100
        BlockDevice, unique=False, null=True, blank=True)
85
101
 
 
102
    node = ForeignKey(
 
103
        "Node", unique=False, null=True, blank=True)
 
104
 
86
105
    # XXX: For CharField, why allow null *and* blank? Would
87
106
    # CharField(null=False, blank=True, default="") not work better?
88
107
    label = CharField(
167
186
        Swap partitions, for example, are not mounted at a particular point in
168
187
        the host's filesystem.
169
188
        """
170
 
        return self.fstype != FILESYSTEM_TYPE.SWAP
 
189
        return self.fstype in self.TYPES_REQUIRING_MOUNT_POINT
 
190
 
 
191
    @property
 
192
    def uses_storage(self):
 
193
        """True if this filesystem expects a block special device.
 
194
 
 
195
        ramfs and tmpfs, for example, exist only in memory.
 
196
        """
 
197
        return self.fstype in self.TYPES_REQUIRING_STORAGE
171
198
 
172
199
    def clean(self, *args, **kwargs):
173
200
        super(Filesystem, self).clean(*args, **kwargs)
174
 
 
175
 
        # You have to specify either a partition or a block device.
176
 
        if self.partition is None and self.block_device is None:
177
 
            raise ValidationError(
178
 
                # XXX: Message leaks implementation details ("block_device").
179
 
                "One of partition or block_device must be specified.")
180
 
 
181
 
        # You can have only one of partition or block device; not both.
182
 
        if self.partition is not None and self.block_device is not None:
183
 
            raise ValidationError(
184
 
                # XXX: Message leaks implementation details ("block_device").
185
 
                "Only one of partition or block_device can be specified.")
 
201
        parents = self.partition, self.block_device, self.node
 
202
 
 
203
        # You have to specify either a partition, block device, or node.
 
204
        if parents.count(None) == len(parents):
 
205
            if self.uses_storage:
 
206
                raise ValidationError(
 
207
                    "One of partition or block device must be specified.")
 
208
            else:
 
209
                raise ValidationError(
 
210
                    "A node must be specified.")
 
211
 
 
212
        # You can have only one of partition, block device, or node.
 
213
        if len(parents) - parents.count(None) > 1:
 
214
            raise ValidationError(
 
215
                "Only one of partition, block device, or node can "
 
216
                "be specified.")
186
217
 
187
218
        # If fstype is for a bcache as a cache device it needs to be in a
188
219
        # cache_set.
215
246
                    "Create a partition on the boot disk first and then "
216
247
                    "format the partition.")
217
248
 
 
249
        # Only ramfs and tmpfs can have a node as a parent.
 
250
        if self.fstype in self.TYPES_REQUIRING_STORAGE:
 
251
            if self.node is not None:
 
252
                raise ValidationError(
 
253
                    "A %s filesystem must be placed on a "
 
254
                    "block device or partition." % self.fstype)
 
255
        else:
 
256
            if self.node is None:
 
257
                raise ValidationError(
 
258
                    "RAM-backed filesystems cannot be placed on "
 
259
                    "block devices or partitions.")
 
260
 
218
261
    def save(self, *args, **kwargs):
219
262
        if not self.uuid:
220
263
            self.uuid = uuid4()