def test_bcache_update_with_boot_disk(self): node = factory.make_Node(with_boot_disk=False) boot_disk = factory.make_PhysicalBlockDevice(node=node) cache_set = factory.make_CacheSet(node=node) filesystems = [ factory.make_Filesystem( partition=factory.make_PartitionTable( block_device=factory.make_PhysicalBlockDevice( node=node)).add_partition(), fstype=FILESYSTEM_TYPE.BCACHE_BACKING, ) ] bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_set=cache_set, filesystems=filesystems, ) form = UpdateBcacheForm(bcache=bcache, data={"backing_device": boot_disk.id}) self.assertTrue(form.is_valid(), form.errors) bcache = form.save() boot_partition = boot_disk.get_partitiontable().partitions.first() self.assertEqual( boot_partition.get_effective_filesystem(), bcache.filesystems.get(fstype=FILESYSTEM_TYPE.BCACHE_BACKING), )
def test_bcache_with_invalid_block_device_fails(self): """Tests allowable device list validation.""" node = factory.make_Node() cache_set = factory.make_CacheSet(node=node) filesystems = [ factory.make_Filesystem( partition=factory.make_PartitionTable( block_device=factory.make_PhysicalBlockDevice( node=node)).add_partition(), fstype=FILESYSTEM_TYPE.BCACHE_BACKING, ) ] backing_device = factory.make_PhysicalBlockDevice() bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_set=cache_set, filesystems=filesystems, ) form = UpdateBcacheForm(bcache=bcache, data={"backing_device": backing_device.id}) self.assertFalse(form.is_valid(), form.errors) self.assertIn("Select a valid choice.", form.errors["backing_device"][0]) self.assertIn( "is not one of the available choices.", form.errors["backing_device"][0], )
def update(self, request, system_id, id): """Update bcache on a machine. :param name: Name of the Bcache. :param uuid: UUID of the Bcache. :param cache_set: Cache set to replace current one. :param backing_device: Backing block device to replace current one. :param backing_partition: Backing partition to replace current one. :param cache_mode: Cache mode (writeback, writethrough, writearound). Specifying both a device and a partition for a given role (cache or backing) is not allowed. Returns 404 if the machine or the bcache is not found. Returns 409 if the machine is not Ready. """ bcache = Bcache.objects.get_object_or_404( system_id, id, request.user, NodePermission.admin) node = bcache.get_node() if node.status != NODE_STATUS.READY: raise NodeStateViolation( "Cannot update Bcache because the machine is not Ready.") form = UpdateBcacheForm(bcache, data=request.data) if form.is_valid(): create_audit_event( EVENT_TYPES.NODE, ENDPOINT.API, request, system_id, "Updated bcache.") return form.save() else: raise MAASAPIValidationError(form.errors)
def update(self, request, system_id, id): """@description-title Update a bcache @description Update bcache on a machine. Specifying both a device and a partition for a given role (cache or backing) is not allowed. @param (string) "{system_id}" [required=true] The machine's system_id. @param (string) "{id}" [required=true] The bcache id. @param (string) "name" [required=false] Name of the Bcache. @param (string) "uuid" [required=false] UUID of the Bcache. @param (string) "cache_set" [required=false] Cache set to replace current one. @param (string) "backing_device" [required=false] Backing block device to replace current one. @param (string) "backing_partition" [required=false] Backing partition to replace current one. @param (string) "cache_mode" [required=false] Cache mode: ``WRITEBACK``, ``WRITETHROUGH``, ``WRITEAROUND``. @success (http-status-code) "server-success" 200 @success (json) "success-json" A JSON object containing the new bcache device. @success-example "success-json" [exkey=bcache-placeholder] placeholder text @error (http-status-code) "404" 404 @error (content) "not-found" The requested id or system_id is not found. @error-example "not-found" Not Found @error (http-status-code) "409" 409 @error (content) "not-ready" The requested machine is not ready. """ bcache = Bcache.objects.get_object_or_404(system_id, id, request.user, NodePermission.admin) node = bcache.get_node() if node.status != NODE_STATUS.READY: raise NodeStateViolation( "Cannot update Bcache because the machine is not Ready.") form = UpdateBcacheForm(bcache, data=request.data) if form.is_valid(): create_audit_event( EVENT_TYPES.NODE, ENDPOINT.API, request, system_id, "Updated bcache.", ) return form.save() else: raise MAASAPIValidationError(form.errors)
def test_bcache_update_with_invalid_mode(self): """Tests the mode field validation.""" node = factory.make_Node() cache_set = factory.make_CacheSet(node=node) filesystems = [ factory.make_Filesystem(partition=factory.make_PartitionTable( block_device=factory.make_PhysicalBlockDevice( node=node)).add_partition(), fstype=FILESYSTEM_TYPE.BCACHE_BACKING) ] bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_set=cache_set, filesystems=filesystems) form = UpdateBcacheForm(bcache=bcache, data={'cache_mode': 'Writeonly'}) self.assertFalse(form.is_valid(), form.errors) self.assertIn('Select a valid choice.', form.errors['cache_mode'][0]) self.assertIn('is not one of the available choices.', form.errors['cache_mode'][0])
def test_choices_are_being_populated_correctly(self): node = factory.make_Node(with_boot_disk=False) device_size = 1 * 1000**4 # Make 10 block devices. bds = [ factory.make_PhysicalBlockDevice(node=node, size=device_size) for _ in range(10) ] # Make 3 cache sets. cache_sets = [factory.make_CacheSet(node=node) for _ in range(3)] cache_set_choices = [cache_set.id for cache_set in cache_sets ] + [cache_set.name for cache_set in cache_sets] # Partition the last 5 devices with a single partition. partitions = [ factory.make_PartitionTable(block_device=bd).add_partition() for bd in bds[5:] ] partition_choices = [p.id for p in partitions ] + [p.name for p in partitions] # Get the chocies of the non-partitioned devices. block_device_choices = [ bd.id for bd in bds if bd.get_partitiontable() is None ] + [bd.name for bd in bds if bd.get_partitiontable() is None] # Use one of the cache sets and one of the backing devices. filesystems = [ factory.make_Filesystem(partition=partitions[0], fstype=FILESYSTEM_TYPE.BCACHE_BACKING) ] bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_set=cache_sets[0], filesystems=filesystems, ) form = UpdateBcacheForm(bcache=bcache, data={}) # Should allow all devices and partitions, including the ones currently # allocated for bcache. self.assertItemsEqual( cache_set_choices, [k for (k, v) in form.fields["cache_set"].choices], ) self.assertItemsEqual( block_device_choices, [k for (k, v) in form.fields["backing_device"].choices], ) self.assertItemsEqual( partition_choices, [k for (k, v) in form.fields["backing_partition"].choices], )