From a533b50648ca7c746194ae3c5c03dba56175efa3 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Mon, 12 Sep 2016 12:03:04 -0400 Subject: [PATCH] Add extended Glance Image properties Glance has a number of properties on the Image resource that aren't documented with the rest of the API docs, so this change adds them Change-Id: I0566f47e1995221cf15f4fda0afb3cbb9a7dc2ed Closes-Bug: 1622557 --- openstack/image/v2/image.py | 88 +++++++++++++++++++++ openstack/tests/unit/image/v2/test_image.py | 65 ++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/openstack/image/v2/image.py b/openstack/image/v2/image.py index e6b270b7..c1008cf1 100644 --- a/openstack/image/v2/image.py +++ b/openstack/image/v2/image.py @@ -118,6 +118,94 @@ class Image(resource2.Resource): #: The location metadata. metadata = resource2.Body('metadata', type=dict) + # Additional Image Properties + # http://docs.openstack.org/developer/glance/common-image-properties.html + # http://docs.openstack.org/cli-reference/glance-property-keys.html + #: The CPU architecture that must be supported by the hypervisor. + architecture = resource2.Body("architecture") + #: The hypervisor type. Note that qemu is used for both QEMU and + #: KVM hypervisor types. + hypervisor_type = resource2.Body("hypervisor-type") + #: Optional property allows created servers to have a different bandwidth + #: cap than that defined in the network they are attached to. + instance_type_rxtx_factor = resource2.Body("instance_type_rxtx_factor", + type=float) + # For snapshot images, this is the UUID of the server used to + #: create this image. + instance_uuid = resource2.Body('instance_uuid') + #: Specifies whether the image needs a config drive. + #: `mandatory` or `optional` (default if property is not used). + needs_config_drive = resource2.Body('img_config_drive') + #: The ID of an image stored in the Image service that should be used + #: as the kernel when booting an AMI-style image. + kernel_id = resource2.Body('kernel_id') + #: The common name of the operating system distribution in lowercase + os_distro = resource2.Body('os_distro') + #: The operating system version as specified by the distributor. + os_version = resource2.Body('os_version') + #: Secure Boot is a security standard. When the instance starts, + #: Secure Boot first examines software such as firmware and OS by + #: their signature and only allows them to run if the signatures are valid. + needs_secure_boot = resource2.Body('os_secure_boot') + #: The ID of image stored in the Image service that should be used as + #: the ramdisk when booting an AMI-style image. + ramdisk_id = resource2.Body('ramdisk_id') + #: The virtual machine mode. This represents the host/guest ABI + #: (application binary interface) used for the virtual machine. + vm_mode = resource2.Body('vm_mode') + #: The preferred number of sockets to expose to the guest. + hw_cpu_sockets = resource2.Body('hw_cpu_sockets', type=int) + #: The preferred number of cores to expose to the guest. + hw_cpu_cores = resource2.Body('hw_cpu_cores', type=int) + #: The preferred number of threads to expose to the guest. + hw_cpu_threads = resource2.Body('hw_cpu_threads', type=int) + #: Specifies the type of disk controller to attach disk devices to. + #: One of scsi, virtio, uml, xen, ide, or usb. + hw_disk_bus = resource2.Body('hw_disk_bus') + #: Adds a random-number generator device to the image's instances. + hw_rng_model = resource2.Body('hw_rng_model') + #: For libvirt: Enables booting an ARM system using the specified + #: machine type. + #: For Hyper-V: Specifies whether the Hyper-V instance will be a + #: generation 1 or generation 2 VM. + hw_machine_type = resource2.Body('hw_machine_type') + #: Enables the use of VirtIO SCSI (virtio-scsi) to provide block device + #: access for compute instances; by default, instances use VirtIO Block + #: (virtio-blk). + hw_scsi_model = resource2.Body('hw_scsi_model') + #: Specifies the count of serial ports that should be provided. + hw_serial_port_count = resource2.Body('hw_serial_port_count', type=int) + #: The video image driver used. + hw_video_model = resource2.Body('hw_video_model') + #: Maximum RAM for the video image. + hw_video_ram = resource2.Body('hw_video_ram', type=int) + #: Enables a virtual hardware watchdog device that carries out the + #: specified action if the server hangs. + hw_watchdog_action = resource2.Body('hw_watchdog_action') + #: The kernel command line to be used by the libvirt driver, instead + #: of the default. + os_command_line = resource2.Body('os_command_line') + #: Specifies the model of virtual network interface device to use. + hw_vif_model = resource2.Body('hw_vif_model') + #: If true, this enables the virtio-net multiqueue feature. + #: In this case, the driver sets the number of queues equal to the + #: number of guest vCPUs. This makes the network performance scale + #: across a number of vCPUs. + is_hw_vif_multiqueue_enabled = resource2.Body('hw_vif_multiqueue_enabled', + type=bool) + #: If true, enables the BIOS bootmenu. + is_hw_boot_menu_enabled = resource2.Body('hw_boot_menu', type=bool) + #: The virtual SCSI or IDE controller used by the hypervisor. + vmware_adaptertype = resource2.Body('vmware_adaptertype') + #: A VMware GuestID which describes the operating system installed + #: in the image. + vmware_ostype = resource2.Body('vmware_ostype') + #: If true, the root partition on the disk is automatically resized + #: before the instance boots. + has_auto_disk_config = resource2.Body('auto_disk_config', type=bool) + #: The operating system installed on the image. + os_type = resource2.Body('os_type') + def _action(self, session, action): """Call an action on an image ID.""" url = utils.urljoin(self.base_path, self.id, 'actions', action) diff --git a/openstack/tests/unit/image/v2/test_image.py b/openstack/tests/unit/image/v2/test_image.py index 70608fb4..c45c8d49 100644 --- a/openstack/tests/unit/image/v2/test_image.py +++ b/openstack/tests/unit/image/v2/test_image.py @@ -43,7 +43,37 @@ EXAMPLE = { 'path': '18', 'value': '19', 'url': '20', - 'metadata': {'21': '22'} + 'metadata': {'21': '22'}, + 'architecture': '23', + 'hypervisor-type': '24', + 'instance_type_rxtx_factor': 25.1, + 'instance_uuid': '26', + 'img_config_drive': '27', + 'kernel_id': '28', + 'os_distro': '29', + 'os_version': '30', + 'os_secure_boot': '31', + 'ramdisk_id': '32', + 'vm_mode': '33', + 'hw_cpu_sockets': 34, + 'hw_cpu_cores': 35, + 'hw_cpu_threads': 36, + 'hw_disk_bus': '37', + 'hw_rng_model': '38', + 'hw_machine_type': '39', + 'hw_scsi_model': '40', + 'hw_serial_port_count': 41, + 'hw_video_model': '42', + 'hw_video_ram': 43, + 'hw_watchdog_action': '44', + 'os_command_line': '45', + 'hw_vif_model': '46', + 'hw_vif_multiqueue_enabled': True, + 'hw_boot_menu': True, + 'vmware_adaptertype': '47', + 'vmware_ostype': '48', + 'auto_disk_config': True, + 'os_type': '49', } @@ -95,6 +125,39 @@ class TestImage(testtools.TestCase): self.assertEqual(EXAMPLE['value'], sot.value) self.assertEqual(EXAMPLE['url'], sot.url) self.assertEqual(EXAMPLE['metadata'], sot.metadata) + self.assertEqual(EXAMPLE['architecture'], sot.architecture) + self.assertEqual(EXAMPLE['hypervisor-type'], sot.hypervisor_type) + self.assertEqual(EXAMPLE['instance_type_rxtx_factor'], + sot.instance_type_rxtx_factor) + self.assertEqual(EXAMPLE['instance_uuid'], sot.instance_uuid) + self.assertEqual(EXAMPLE['img_config_drive'], sot.needs_config_drive) + self.assertEqual(EXAMPLE['kernel_id'], sot.kernel_id) + self.assertEqual(EXAMPLE['os_distro'], sot.os_distro) + self.assertEqual(EXAMPLE['os_version'], sot.os_version) + self.assertEqual(EXAMPLE['os_secure_boot'], sot.needs_secure_boot) + self.assertEqual(EXAMPLE['ramdisk_id'], sot.ramdisk_id) + self.assertEqual(EXAMPLE['vm_mode'], sot.vm_mode) + self.assertEqual(EXAMPLE['hw_cpu_sockets'], sot.hw_cpu_sockets) + self.assertEqual(EXAMPLE['hw_cpu_cores'], sot.hw_cpu_cores) + self.assertEqual(EXAMPLE['hw_cpu_threads'], sot.hw_cpu_threads) + self.assertEqual(EXAMPLE['hw_disk_bus'], sot.hw_disk_bus) + self.assertEqual(EXAMPLE['hw_rng_model'], sot.hw_rng_model) + self.assertEqual(EXAMPLE['hw_machine_type'], sot.hw_machine_type) + self.assertEqual(EXAMPLE['hw_scsi_model'], sot.hw_scsi_model) + self.assertEqual(EXAMPLE['hw_serial_port_count'], + sot.hw_serial_port_count) + self.assertEqual(EXAMPLE['hw_video_model'], sot.hw_video_model) + self.assertEqual(EXAMPLE['hw_video_ram'], sot.hw_video_ram) + self.assertEqual(EXAMPLE['hw_watchdog_action'], sot.hw_watchdog_action) + self.assertEqual(EXAMPLE['os_command_line'], sot.os_command_line) + self.assertEqual(EXAMPLE['hw_vif_model'], sot.hw_vif_model) + self.assertEqual(EXAMPLE['hw_vif_multiqueue_enabled'], + sot.is_hw_vif_multiqueue_enabled) + self.assertEqual(EXAMPLE['hw_boot_menu'], sot.is_hw_boot_menu_enabled) + self.assertEqual(EXAMPLE['vmware_adaptertype'], sot.vmware_adaptertype) + self.assertEqual(EXAMPLE['vmware_ostype'], sot.vmware_ostype) + self.assertEqual(EXAMPLE['auto_disk_config'], sot.has_auto_disk_config) + self.assertEqual(EXAMPLE['os_type'], sot.os_type) def test_deactivate(self): sot = image.Image(**EXAMPLE)