~allenap/maas/xxx-a-thon

« back to all changes in this revision

Viewing changes to src/maasserver/api/blockdevices.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:
1
 
# Copyright 2015 Canonical Ltd.  This software is licensed under the
 
1
# Copyright 2015-2016 Canonical Ltd.  This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
3
 
4
4
"""API handlers: `BlockDevice`."""
22
22
from maasserver.forms import (
23
23
    CreatePhysicalBlockDeviceForm,
24
24
    FormatBlockDeviceForm,
25
 
    MountFilesystemForm,
26
25
    UpdatePhysicalBlockDeviceForm,
27
26
    UpdateVirtualBlockDeviceForm,
28
27
)
 
28
from maasserver.forms_filesystem import MountFilesystemForm
29
29
from maasserver.models import (
30
30
    BlockDevice,
31
31
    Machine,
61
61
        node, user, operation):
62
62
    if node.status not in [NODE_STATUS.READY, NODE_STATUS.ALLOCATED]:
63
63
        raise NodeStateViolation(
64
 
            "Cannot %s block device because the node is not Ready "
 
64
            "Cannot %s block device because the machine is not Ready "
65
65
            "or Allocated." % operation)
66
66
    if node.status == NODE_STATUS.READY and not user.is_superuser:
67
67
        raise PermissionDenied(
68
68
            "Cannot %s block device because you don't have the "
69
 
            "permissions on a Ready node." % operation)
 
69
            "permissions on a Ready machine." % operation)
70
70
 
71
71
 
72
72
class BlockDevicesHandler(OperationsHandler):
73
 
    """Manage block devices on a node."""
 
73
    """Manage block devices on a machine."""
74
74
    api_doc_section_name = "Block devices"
75
75
    replace = update = delete = None
76
76
    fields = DISPLAYED_BLOCKDEVICE_FIELDS
80
80
        return ('blockdevices_handler', ["system_id"])
81
81
 
82
82
    def read(self, request, system_id):
83
 
        """List all block devices belonging to node.
 
83
        """List all block devices belonging to a machine.
84
84
 
85
85
        Returns 404 if the machine is not found.
86
86
        """
113
113
 
114
114
 
115
115
class BlockDeviceHandler(OperationsHandler):
116
 
    """Manage a block device on a node."""
 
116
    """Manage a block device on a machine."""
117
117
    api_doc_section_name = "Block device"
118
118
    create = replace = None
119
119
    model = BlockDevice
203
203
    def read(self, request, system_id, device_id):
204
204
        """Read block device on node.
205
205
 
206
 
        Returns 404 if the node or block device is not found.
 
206
        Returns 404 if the machine or block device is not found.
207
207
        """
208
208
        return BlockDevice.objects.get_block_device_or_404(
209
209
            system_id, device_id, request.user, NODE_PERMISSION.VIEW)
210
210
 
211
211
    def delete(self, request, system_id, device_id):
212
 
        """Delete block device on node.
 
212
        """Delete block device on a machine.
213
213
 
214
 
        Returns 404 if the node or block device is not found.
 
214
        Returns 404 if the machine or block device is not found.
215
215
        Returns 403 if the user is not allowed to delete the block device.
216
 
        Returns 409 if the node is not Ready.
 
216
        Returns 409 if the machine is not Ready.
217
217
        """
218
218
        device = BlockDevice.objects.get_block_device_or_404(
219
219
            system_id, device_id, request.user, NODE_PERMISSION.ADMIN)
220
220
        node = device.get_node()
221
221
        if node.status != NODE_STATUS.READY:
222
222
            raise NodeStateViolation(
223
 
                "Cannot delete block device because the node is not Ready.")
 
223
                "Cannot delete block device because the machine is not Ready.")
224
224
        device.delete()
225
225
        return rc.DELETED
226
226
 
227
227
    def update(self, request, system_id, device_id):
228
 
        """Update block device on node.
 
228
        """Update block device on a machine.
229
229
 
230
230
        Fields for physical block device:
231
231
        :param name: Name of the block device.
243
243
        :param size: Size of the block device. (Only allowed for logical \
244
244
            volumes.)
245
245
 
246
 
        Returns 404 if the node or block device is not found.
 
246
        Returns 404 if the machine or block device is not found.
247
247
        Returns 403 if the user is not allowed to update the block device.
248
 
        Returns 409 if the node is not Ready.
 
248
        Returns 409 if the machine is not Ready.
249
249
        """
250
250
        device = BlockDevice.objects.get_block_device_or_404(
251
251
            system_id, device_id, request.user, NODE_PERMISSION.ADMIN)
252
252
        node = device.get_node()
253
253
        if node.status != NODE_STATUS.READY:
254
254
            raise NodeStateViolation(
255
 
                "Cannot update block device because the node is not Ready.")
 
255
                "Cannot update block device because the machine is not Ready.")
256
256
        if device.type == 'physical':
257
257
            form = UpdatePhysicalBlockDeviceForm(
258
258
                instance=device, data=request.data)
269
269
 
270
270
    @operation(idempotent=True)
271
271
    def add_tag(self, request, system_id, device_id):
272
 
        """Add a tag to block device on node.
 
272
        """Add a tag to block device on a machine.
273
273
 
274
274
        :param tag: The tag being added.
275
275
 
276
 
        Returns 404 if the node or block device is not found.
 
276
        Returns 404 if the machine or block device is not found.
277
277
        Returns 403 if the user is not allowed to update the block device.
278
 
        Returns 409 if the node is not Ready.
 
278
        Returns 409 if the machine is not Ready.
279
279
        """
280
280
        device = BlockDevice.objects.get_block_device_or_404(
281
281
            system_id, device_id, request.user, NODE_PERMISSION.ADMIN)
282
282
        node = device.get_node()
283
283
        if node.status != NODE_STATUS.READY:
284
284
            raise NodeStateViolation(
285
 
                "Cannot update block device because the node is not Ready.")
 
285
                "Cannot update block device because the machine is not Ready.")
286
286
        device.add_tag(get_mandatory_param(request.GET, 'tag'))
287
287
        device.save()
288
288
        return device
289
289
 
290
290
    @operation(idempotent=True)
291
291
    def remove_tag(self, request, system_id, device_id):
292
 
        """Remove a tag from block device on node.
 
292
        """Remove a tag from block device on a machine.
293
293
 
294
294
        :param tag: The tag being removed.
295
295
 
296
 
        Returns 404 if the node or block device is not found.
 
296
        Returns 404 if the machine or block device is not found.
297
297
        Returns 403 if the user is not allowed to update the block device.
298
 
        Returns 409 if the node is not Ready.
 
298
        Returns 409 if the machine is not Ready.
299
299
        """
300
300
        device = BlockDevice.objects.get_block_device_or_404(
301
301
            system_id, device_id, request.user, NODE_PERMISSION.ADMIN)
302
302
        node = device.get_node()
303
303
        if node.status != NODE_STATUS.READY:
304
304
            raise NodeStateViolation(
305
 
                "Cannot update block device because the node is not Ready.")
 
305
                "Cannot update block device because the machine is not Ready.")
306
306
        device.remove_tag(get_mandatory_param(request.GET, 'tag'))
307
307
        device.save()
308
308
        return device
316
316
 
317
317
        Returns 403 when the user doesn't have the ability to format the \
318
318
            block device.
319
 
        Returns 404 if the node or block device is not found.
320
 
        Returns 409 if the node is not Ready or Allocated.
 
319
        Returns 404 if the machine or block device is not found.
 
320
        Returns 409 if the machine is not Ready or Allocated.
321
321
        """
322
322
        device = BlockDevice.objects.get_block_device_or_404(
323
323
            system_id, device_id, request.user, NODE_PERMISSION.EDIT)
338
338
            or part of a filesystem group.
339
339
        Returns 403 when the user doesn't have the ability to unformat the \
340
340
            block device.
341
 
        Returns 404 if the node or block device is not found.
342
 
        Returns 409 if the node is not Ready or Allocated.
 
341
        Returns 404 if the machine or block device is not found.
 
342
        Returns 409 if the machine is not Ready or Allocated.
343
343
        """
344
344
        device = BlockDevice.objects.get_block_device_or_404(
345
345
            system_id, device_id, request.user, NODE_PERMISSION.EDIT)
349
349
        filesystem = device.get_effective_filesystem()
350
350
        if filesystem is None:
351
351
            raise MAASAPIBadRequest("Block device is not formatted.")
352
 
        if filesystem.mount_point:
 
352
        if filesystem.is_mounted:
353
353
            raise MAASAPIBadRequest(
354
354
                "Filesystem is mounted and cannot be unformatted. Unmount the "
355
355
                "filesystem before unformatting the block device.")
368
368
        """Mount the filesystem on block device.
369
369
 
370
370
        :param mount_point: Path on the filesystem to mount.
 
371
        :param mount_options: Options to pass to mount(8).
371
372
 
372
373
        Returns 403 when the user doesn't have the ability to mount the \
373
374
            block device.
374
 
        Returns 404 if the node or block device is not found.
375
 
        Returns 409 if the node is not Ready or Allocated.
 
375
        Returns 404 if the machine or block device is not found.
 
376
        Returns 409 if the machine is not Ready or Allocated.
376
377
        """
377
378
        device = BlockDevice.objects.get_block_device_or_404(
378
379
            system_id, device_id, request.user, NODE_PERMISSION.EDIT)
394
395
            mounted.
395
396
        Returns 403 when the user doesn't have the ability to unmount the \
396
397
            block device.
397
 
        Returns 404 if the node or block device is not found.
398
 
        Returns 409 if the node is not Ready or Allocated.
 
398
        Returns 404 if the machine or block device is not found.
 
399
        Returns 409 if the machine is not Ready or Allocated.
399
400
        """
400
401
        device = BlockDevice.objects.get_block_device_or_404(
401
402
            system_id, device_id, request.user, NODE_PERMISSION.EDIT)
405
406
        filesystem = device.get_effective_filesystem()
406
407
        if filesystem is None:
407
408
            raise MAASAPIBadRequest("Block device is not formatted.")
408
 
        if not filesystem.mount_point:
 
409
        if not filesystem.is_mounted:
409
410
            raise MAASAPIBadRequest("Filesystem is already unmounted.")
410
411
        filesystem.mount_point = None
411
412
        filesystem.mount_options = None
414
415
 
415
416
    @operation(idempotent=False)
416
417
    def set_boot_disk(self, request, system_id, device_id):
417
 
        """Set this block device as the boot disk for the node.
 
418
        """Set this block device as the boot disk for the machine.
418
419
 
419
420
        Returns 400 if the block device is a virtual block device.
420
 
        Returns 404 if the node or block device is not found.
 
421
        Returns 404 if the machine or block device is not found.
421
422
        Returns 403 if the user is not allowed to update the block device.
422
 
        Returns 409 if the node is not Ready or Allocated.
 
423
        Returns 409 if the machine is not Ready or Allocated.
423
424
        """
424
425
        device = BlockDevice.objects.get_block_device_or_404(
425
426
            system_id, device_id, request.user, NODE_PERMISSION.ADMIN)
426
427
        node = device.get_node()
427
428
        if node.status != NODE_STATUS.READY:
428
429
            raise NodeStateViolation(
429
 
                "Cannot set as boot disk because the node is not Ready.")
 
430
                "Cannot set as boot disk because the machine is not Ready.")
430
431
        if not isinstance(device, PhysicalBlockDevice):
431
432
            raise MAASAPIBadRequest(
432
433
                "Cannot set a %s block device as the boot disk." % device.type)