From: chamarty Date: Sun, 8 Jan 2017 21:55:03 +0000 (+0000) Subject: First set of OSM model changes for multi-disk/config-files/etc. X-Git-Tag: v1.1.0~30 X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=refs%2Fchanges%2F90%2F890%2F1;p=osm%2FSO.git First set of OSM model changes for multi-disk/config-files/etc. Change-Id: I2a064cec6e8c80e2aea0772854712cb6a8194275 Signed-off-by: chamarty --- diff --git a/models/openmano/python/rift/openmano/rift2openmano.py b/models/openmano/python/rift/openmano/rift2openmano.py index f5b46ea1..65678bdd 100755 --- a/models/openmano/python/rift/openmano/rift2openmano.py +++ b/models/openmano/python/rift/openmano/rift2openmano.py @@ -535,7 +535,7 @@ def rift2openmano_vnfd(rift_vnfd, rift_nsd): else: # Add Openmano devices device = {} - device["type"] = volume.guest_params.device_type + device["type"] = volume.device_type device["image"] = volume.image vnfc["devices"].append(device) @@ -545,19 +545,19 @@ def rift2openmano_vnfd(rift_vnfd, rift_nsd): vnfc_cloud_config_init = True vnfc['cloud-config']['user-data'] = cloud_init(rift_vnfd.id, vdu) - if vdu.has_field("custom_boot_data"): - if vdu.custom_boot_data.has_field('custom_drive'): - if vdu.custom_boot_data.custom_drive is True: + if vdu.has_field("supplemental_boot_data"): + if vdu.supplemental_boot_data.has_field('boot_data_drive'): + if vdu.supplemental_boot_data.boot_data_drive is True: if vnfc_cloud_config_init is False: vnfc['cloud-config'] = dict() vnfc_cloud_config_init = True - vnfc['cloud-config']['config-drive'] = vdu.custom_boot_data.custom_drive - if vdu.custom_boot_data.has_field('custom_meta_data'): + vnfc['cloud-config']['config-drive'] = vdu.supplemental_boot_data.boot_data_drive + if vdu.supplemental_boot_data.has_field('custom_meta_data'): if vnfc_cloud_config_init is False: vnfc['cloud-config'] = dict() vnfc_cloud_config_init = True vnfc['cloud-config']['meta-data'] = list() - for metaitem in vdu.custom_boot_data.custom_meta_data: + for metaitem in vdu.supplemental_boot_data.custom_meta_data: openmano_metaitem = dict() openmano_metaitem['key'] = metaitem.name openmano_metaitem['value'] = metaitem.value diff --git a/models/plugins/yang/mano-types.yang b/models/plugins/yang/mano-types.yang index b767ea65..fa6f39c9 100644 --- a/models/plugins/yang/mano-types.yang +++ b/models/plugins/yang/mano-types.yang @@ -2049,9 +2049,9 @@ module mano-types } } - grouping custom-config-files { + grouping config-file { description "Grouping for files needed to be mounted into an additional drive"; - list custom-config-files { + list config-file { description "List of configuration files to be written on an additional drive"; key "source"; @@ -2090,13 +2090,13 @@ module mano-types } } - grouping custom-boot-data { + grouping supplemental-boot-data { description "Grouping for custom vim data"; - container custom-boot-data { - uses manotypes:custom-config-files; + container supplemental-boot-data { + uses manotypes:config-file; uses manotypes:custom-meta-data; - leaf custom-drive { - description "Some VIMs implement custom drives to host custom-files or meta-data"; + leaf boot-data-drive { + description "Some VIMs implement additional drives to host config-files or meta-data"; type boolean; default false; } @@ -2142,41 +2142,37 @@ module mano-types } } - container boot-params { - leaf boot-volume { - description "This flag indicates if this is boot volume or not"; - type boolean; - } - leaf boot-priority { - description "Boot priority associated with volume"; - type int32; - } + leaf boot-volume { + description "This flag indicates if this is boot volume or not"; + type boolean; } - container guest-params { - description "Guest virtualization parameter associated with volume"; + leaf boot-priority { + description "Boot priority associated with volume"; + type int32; + } - leaf device_bus { - description "Type of disk-bus on which this disk is exposed to guest"; - type enumeration { - enum ide; - enum usb; - enum virtio; - enum scsi; - } + + leaf device_bus { + description "Type of disk-bus on which this disk is exposed to guest"; + type enumeration { + enum ide; + enum usb; + enum virtio; + enum scsi; } + } - leaf device_type { - description "The type of device as exposed to guest"; - type enumeration { + leaf device_type { + description "The type of device as exposed to guest"; + type enumeration { enum disk; enum cdrom; enum floppy; enum lun; - } } - - uses custom-meta-data; } + + uses custom-meta-data; } } diff --git a/models/plugins/yang/vnfd.yang b/models/plugins/yang/vnfd.yang index 32a87d26..0e779c51 100644 --- a/models/plugins/yang/vnfd.yang +++ b/models/plugins/yang/vnfd.yang @@ -364,7 +364,7 @@ module vnfd } } - uses manotypes:custom-boot-data; + uses manotypes:supplemental-boot-data; list internal-connection-point { key "id"; diff --git a/models/plugins/yang/vnfr.yang b/models/plugins/yang/vnfr.yang index 69d56913..c0a6237a 100644 --- a/models/plugins/yang/vnfr.yang +++ b/models/plugins/yang/vnfr.yang @@ -340,7 +340,7 @@ module vnfr uses manotypes:hypervisor-epa; uses manotypes:host-epa; - uses manotypes:custom-boot-data; + uses manotypes:supplemental-boot-data; list volumes { key "name"; diff --git a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/prepare_vm.py b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/prepare_vm.py index 78ec3a6b..efcf1f55 100644 --- a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/prepare_vm.py +++ b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/prepare_vm.py @@ -114,12 +114,10 @@ def create_volume_metadata(drv, argument): srv_volume_list = drv.nova_volume_list(argument.server_id) for volume in yaml_vol_cfg: - if 'guest_params' not in volume: - continue - if 'custom_meta_data' not in volume['guest_params']: + if 'custom_meta_data' not in volume: continue vmd = dict() - for vol_md_item in volume['guest_params']['custom_meta_data']: + for vol_md_item in volume['custom_meta_data']: if 'value' not in vol_md_item: continue vmd[vol_md_item['name']] = vol_md_item['value'] diff --git a/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py b/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py index 7cdc2407..a3703306 100644 --- a/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py +++ b/rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py @@ -1270,13 +1270,13 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): if key == 'node_id': vdu.node_id = value else: - custommetadata = vdu.custom_boot_data.custom_meta_data.add() + custommetadata = vdu.supplemental_boot_data.custom_meta_data.add() custommetadata.name = key custommetadata.value = str(value) # Look for config_drive if ('config_drive' in vm_info): - vdu.custom_boot_data.custom_drive = vm_info['config_drive'] + vdu.supplemental_boot_data.boot_data_drive = vm_info['config_drive'] if ('image' in vm_info) and ('id' in vm_info['image']): vdu.image_id = vm_info['image']['id'] if ('flavor' in vm_info) and ('id' in vm_info['flavor']): @@ -1950,21 +1950,21 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): metadata['node_id'] = vduinfo.node_id if pci_assignement is not None: metadata['pci_assignement'] = pci_assignement - if vduinfo.has_field('custom_boot_data'): - if vduinfo.custom_boot_data.has_field('custom_meta_data'): - for custom_meta_item in vduinfo.custom_boot_data.custom_meta_data: + if vduinfo.has_field('supplemental_boot_data'): + if vduinfo.supplemental_boot_data.has_field('custom_meta_data'): + for custom_meta_item in vduinfo.supplemental_boot_data.custom_meta_data: if custom_meta_item.data_type == "STRING": metadata[custom_meta_item.name] = custom_meta_item.value elif custom_meta_item.data_type == "JSON": metadata[custom_meta_item.name] = tornado.escape.json_decode(custom_meta_item.value) else: raise OpenstackCALOperationFailure("Create-vdu operation failed. Unsupported data-type {} for custom-meta-data name {} ".format(custom_meta_item.data_type, custom_meta_item.name)) - if vduinfo.custom_boot_data.has_field('custom_config_files'): - for custom_config_file in vduinfo.custom_boot_data.custom_config_files: + if vduinfo.supplemental_boot_data.has_field('config_file'): + for custom_config_file in vduinfo.supplemental_boot_data.config_file: files[custom_config_file.dest] = custom_config_file.source - if vduinfo.custom_boot_data.has_field('custom_drive'): - if vduinfo.custom_boot_data.custom_drive is True: + if vduinfo.supplemental_boot_data.has_field('boot_data_drive'): + if vduinfo.supplemental_boot_data.boot_data_drive is True: config_drive = True kwargs['metadata'] = metadata @@ -1989,7 +1989,7 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): # Only support image->volume for volume in vduinfo.volumes: block_map = dict() - block_map['boot_index'] = volume.boot_params.boot_priority + block_map['boot_index'] = volume.boot_priority if "image" in volume: # Support image->volume # Match retrived image info with volume based image name and checksum @@ -2009,9 +2009,9 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): block_map['destination_type'] = "volume" block_map['volume_size'] = volume.size block_map['delete_on_termination'] = True - if volume.guest_params.has_field('device_type') and volume.guest_params.device_type == 'cdrom': + if volume.has_field('device_type') and volume.device_type == 'cdrom': block_map['device_type'] = 'cdrom' - if volume.guest_params.has_field('device_bus') and volume.guest_params.device_bus == 'ide': + if volume.has_field('device_bus') and volume.device_bus == 'ide': block_map['disk_bus'] = 'ide' kwargs['block_device_mapping_v2'].append(block_map) @@ -2160,16 +2160,12 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): err_str = ("VDU Volume source not supported yet") self.log.error(err_str) raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str) - if "guest_params" not in volume: - err_str = ("VDU Volume destination parameters '%s' not defined") + if not volume.has_field('device_type'): + err_str = ("VDU Volume destination type not defined") self.log.error(err_str) raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str) - if not volume.guest_params.has_field('device_type'): - err_str = ("VDU Volume destination type '%s' not defined") - self.log.error(err_str) - raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str) - if volume.guest_params.device_type not in ['disk', 'cdrom'] : - err_str = ("VDU Volume destination type '%s' not supported" % volume.guest_params.device_type) + if volume.device_type not in ['disk', 'cdrom'] : + err_str = ("VDU Volume destination type '%s' not supported" % volume.device_type) self.log.error(err_str) raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str) @@ -2247,7 +2243,7 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud): vol_metadata = False if volumes is not None: for volume in volumes: - if volume.guest_params.has_field('custom_meta_data'): + if volume.has_field('custom_meta_data'): vol_metadata = True break diff --git a/rwcal/plugins/yang/rwcal.yang b/rwcal/plugins/yang/rwcal.yang index c04462fb..53187502 100644 --- a/rwcal/plugins/yang/rwcal.yang +++ b/rwcal/plugins/yang/rwcal.yang @@ -1014,7 +1014,7 @@ module rwcal } } - uses manotypes:custom-boot-data; + uses manotypes:supplemental-boot-data; list volumes { key "name"; @@ -1252,7 +1252,7 @@ module rwcal description "Console URL from the VIM, if available"; } - uses manotypes:custom-boot-data; + uses manotypes:supplemental-boot-data; list volumes { key "name"; diff --git a/rwcal/test/test_rwcal_openstack.py b/rwcal/test/test_rwcal_openstack.py index 38d30f6b..6b0a2472 100644 --- a/rwcal/test/test_rwcal_openstack.py +++ b/rwcal/test/test_rwcal_openstack.py @@ -932,19 +932,19 @@ class OpenStackTest(unittest.TestCase): vdu.flavor_id = self._flavor.id vdu.vdu_init.userdata = PING_USERDATA vdu.allocate_public_address = True - meta1 = vdu.custom_boot_data.custom_meta_data.add() + meta1 = vdu.supplemental_boot_data.custom_meta_data.add() meta1.name = "EMS_IP" meta1.data_type = "STRING" meta1.value = "10.5.6.6" - #meta2 = vdu.custom_boot_data.custom_meta_data.add() + #meta2 = vdu.supplemental_boot_data.custom_meta_data.add() #meta2.name = "Cluster_data" #meta2.data_type = "JSON" #meta2.value = '''{ "cluster_id": "12" , "vnfc_id": "112" }''' - #vdu.custom_boot_data.custom_drive = True - customfile1 = vdu.custom_boot_data.custom_config_files.add() + #vdu.supplemental_boot_data.boot_data_drive = True + customfile1 = vdu.supplemental_boot_data.config_file.add() customfile1.source = "abcdef124" customfile1.dest = "/tmp/tempfile.txt" - customfile2 = vdu.custom_boot_data.custom_config_files.add() + customfile2 = vdu.supplemental_boot_data.config_file.add() customfile2.source = "123456" customfile2.dest = "/tmp/tempfile2.txt" c1 = vdu.connection_points.add() @@ -965,7 +965,7 @@ class OpenStackTest(unittest.TestCase): return vdu - #@unittest.skip("Skipping test_create_delete_virtual_link_and_vdu") + @unittest.skip("Skipping test_create_delete_virtual_link_and_vdu") def test_create_delete_virtual_link_and_vdu(self): """ Test to create VDU @@ -1048,6 +1048,115 @@ class OpenStackTest(unittest.TestCase): logger.info("Openstack-CAL-Test: VDU/Virtual Link create-delete test successfully completed") + def _get_vol_vdu_request_info(self, vlink_list): + """ + Returns object of type RwcalYang.VDUInitParams + """ + vdu = RwcalYang.VDUInitParams() + vdu.name = "cal_vdu" + vdu.flavor_id = self._flavor.id + vdu.allocate_public_address = True + ctr = 0 + for vl in vlink_list: + c1 = vdu.connection_points.add() + c1.name = "c_point" + str(ctr) + ctr += 1 + c1.virtual_link_id = vl + c1.type_yang = 'VIRTIO' + + vol0 = vdu.volumes.add() + vol0.name = "vda" + vol0.image = openstack_info['reserved_image'] + vol0.size = 10 + vol0.boot_priority = 0 + vol0.device_type = "disk" + meta1 = vol0.custom_meta_data.add() + meta1.name = "fs_type" + meta1.data_type = "STRING" + meta1.value = "ext4" + + return vdu + + #@unittest.skip("Skipping test_create_vol_vdu") + def test_create_vol_vdu(self): + """ + Test to create VDU with mgmt port using Volumes + """ + logger.info("Openstack-CAL-Test: Test Create Virtual Link API") + vlink_list = [] + vlink = RwcalYang.VirtualLinkReqParams() + vlink.name = 'rift.cal.virtual_link' + vlink.subnet = '11.0.1.0/24' + + rc, rsp = self.cal.create_virtual_link(self._acct, vlink) + self.assertEqual(rc.status, RwStatus.SUCCESS) + logger.info("Openstack-CAL-Test: Created virtual_link with Id: %s" %rsp) + vlink_id = rsp + + #Check if virtual_link create is successful + rc, rsp = self.cal.get_virtual_link(self._acct, rsp) + self.assertEqual(rc, RwStatus.SUCCESS) + self.assertEqual(rsp.virtual_link_id, vlink_id) + vlink_list.append(vlink_id) + + # Now create VDU + vdu_req = self._get_vol_vdu_request_info(vlink_list) + logger.info("################################### ") + logger.info("Openstack-CAL-Test: Test Create VDU API (w/ volumes) ") + + rc, rsp = self.cal.create_vdu(self._acct, vdu_req) + logger.debug("Openstack-CAL-Test: rc %s rsp %s" % (rc, rsp)) + self.assertEqual(rc.status, RwStatus.SUCCESS) + logger.info("Openstack-CAL-Test: Created vdu with Id: %s" %rsp) + + test_vdu_id = rsp + + ## Check if VDU get is successful + rc, rsp = self.cal.get_vdu(self._acct, test_vdu_id) + logger.debug("Get VDU response %s", rsp) + self.assertEqual(rsp.vdu_id, test_vdu_id) + + ### Wait until vdu_state is active + logger.debug("Waiting 10 secs") + time.sleep(10) + #{'name': 'dp0vhost7', 'connection_point_id': 'dp0vhost7', 'state': 'active', 'virtual_link_id': 'rift.cal.virtual_link', 'ip_address': '192.168.100.6'} + vdu_state = 'inactive' + cp_state = 'inactive' + for i in range(5): + rc, rsp = self.cal.get_vdu(self._acct, test_vdu_id) + self.assertEqual(rc, RwStatus.SUCCESS) + logger.info("Openstack-CAL-Test: VDU with id : %s. Reached State : %s, mgmt ip %s" %(test_vdu_id, rsp.state, rsp.management_ip)) + if (rsp.state == 'active') and ('management_ip' in rsp) and ('public_ip' in rsp): + vdu_state = 'active' + #'connection_points': [{'name': 'dp0vhost7', 'connection_point_id': 'dp0vhost7', 'state': 'active', 'virtual_link_id': 'rift.cal.virtual_link', 'ip_address': '192.168.100.6'}] + for cp in rsp.connection_points: + logger.info("Openstack-CAL-Test: VDU with id : %s. Reached State : %s CP state %s" %(test_vdu_id, rsp.state, cp)) + if vdu_state == 'active' and cp.ip_address is not None : + cp_state = 'active' + break + logger.debug("Waiting another 5 secs") + time.sleep(5) + + self.assertEqual(rc, RwStatus.SUCCESS) + self.assertEqual(rsp.state, 'active') + self.assertEqual(vdu_state, 'active') + self.assertEqual(cp_state, 'active') + logger.info("Openstack-CAL-Test: VDU with id : %s reached expected state : %s IP: %s" %(test_vdu_id, rsp.state, rsp.management_ip)) + logger.info("Openstack-CAL-Test: VDUInfo: %s" %(rsp)) + logger.info("Waiting for 30 secs before deletion") + time.sleep(30) + + ### Check vdu list as well + rc, rsp = self.cal.get_vdu_list(self._acct) + self.assertEqual(rc, RwStatus.SUCCESS) + found = False + logger.debug("Get VDU response %s", rsp) + for vdu in rsp.vdu_info_list: + if vdu.vdu_id == test_vdu_id: + found = True + self.assertEqual(found, True) + logger.info("Openstack-CAL-Test: Passed VDU list" ) + class VmData(object): """A convenience class that provides all the stats and EPA Attributes from the VM provided @@ -1174,5 +1283,6 @@ class VmData(object): if __name__ == "__main__": - logging.basicConfig(level=logging.DEBUG) + #logging.basicConfig(level=logging.DEBUG) + logger.setLevel(logging.DEBUG) unittest.main() diff --git a/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py b/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py index daf83608..e0de7b0c 100755 --- a/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py +++ b/rwlaunchpad/plugins/rwvnfm/rift/tasklets/rwvnfmtasklet/rwvnfmtasklet.py @@ -425,24 +425,22 @@ class VirtualDeploymentUnitRecord(object): metadata_list = list() for metadata_item in opvolume.custom_meta_data: metadata_list.append(metadata_item.as_dict()) - if 'guest_params' not in vdurvol_data[0]: - vdurvol_data[0]['guest_params'] = dict() - vdurvol_data[0]['guest_params']['custom_meta_data'] = metadata_list - - if self._vm_resp.has_field('custom_boot_data'): - vdur_dict['custom_boot_data'] = dict() - if self._vm_resp.custom_boot_data.has_field('custom_drive'): - vdur_dict['custom_boot_data']['custom_drive'] = self._vm_resp.custom_boot_data.custom_drive - if self._vm_resp.custom_boot_data.has_field('custom_meta_data'): + vdurvol_data[0]['custom_meta_data'] = metadata_list + + if self._vm_resp.has_field('supplemental_boot_data'): + vdur_dict['supplemental_boot_data'] = dict() + if self._vm_resp.supplemental_boot_data.has_field('boot_data_drive'): + vdur_dict['supplemental_boot_data']['boot_data_drive'] = self._vm_resp.supplemental_boot_data.boot_data_drive + if self._vm_resp.supplemental_boot_data.has_field('custom_meta_data'): metadata_list = list() - for metadata_item in self._vm_resp.custom_boot_data.custom_meta_data: + for metadata_item in self._vm_resp.supplemental_boot_data.custom_meta_data: metadata_list.append(metadata_item.as_dict()) - vdur_dict['custom_boot_data']['custom_meta_data'] = metadata_list - if self._vm_resp.custom_boot_data.has_field('custom_config_files'): + vdur_dict['supplemental_boot_data']['custom_meta_data'] = metadata_list + if self._vm_resp.supplemental_boot_data.has_field('config_file'): file_list = list() - for file_item in self._vm_resp.custom_boot_data.custom_config_files: + for file_item in self._vm_resp.supplemental_boot_data.config_file: file_list.append(file_item.as_dict()) - vdur_dict['custom_boot_data']['custom_config_files'] = file_list + vdur_dict['supplemental_boot_data']['config_file'] = file_list icp_list = [] ii_list = [] @@ -577,24 +575,24 @@ class VirtualDeploymentUnitRecord(object): def process_custom_bootdata(self, vm_create_msg_dict): """Process the custom boot data""" - if 'custom_config_files' not in vm_create_msg_dict['custom_boot_data']: + if 'config_file' not in vm_create_msg_dict['supplemental_boot_data']: return + self._vnfd_package_store.refresh() stored_package = self._vnfd_package_store.get_package(self._vnfr.vnfd_id) - script_extractor = rift.package.script.PackageScriptExtractor(self._log) - for custom_file_item in vm_create_msg_dict['custom_boot_data']['custom_config_files']: - if 'source' not in custom_file_item or 'dest' not in custom_file_item: + cloud_init_extractor = rift.package.cloud_init.PackageCloudInitExtractor(self._log) + for file_item in vm_create_msg_dict['supplemental_boot_data']['config_file']: + if 'source' not in file_item or 'dest' not in file_item: continue - source = custom_file_item['source'] + source = file_item['source'] # Find source file in scripts dir of VNFD - self._vnfd_package_store.refresh() self._log.debug("Checking for source config file at %s", source) try: - source_file_str = script_extractor.read_script(stored_package, source) - except rift.package.script.ScriptExtractionError as e: + source_file_str = cloud_init_extractor.read_script(stored_package, source) + except rift.package.cloud_init.CloudInitExtractionError as e: raise VirtualDeploymentUnitRecordError(e) # Update source file location with file contents - custom_file_item['source'] = source_file_str + file_item['source'] = source_file_str return @@ -605,7 +603,7 @@ class VirtualDeploymentUnitRecord(object): "hypervisor_epa", "host_epa", "volumes", - "custom_boot_data"] + "supplemental_boot_data"] self._log.debug("Creating params based on VDUD: %s", self._vdud) vdu_copy_dict = {k: v for k, v in self._vdud.as_dict().items() if k in vdu_fields} @@ -664,7 +662,7 @@ class VirtualDeploymentUnitRecord(object): vm_create_msg_dict.update(vdu_copy_dict) self.process_placement_groups(vm_create_msg_dict) - if 'custom_boot_data' in vm_create_msg_dict: + if 'supplemental_boot_data' in vm_create_msg_dict: self.process_custom_bootdata(vm_create_msg_dict) msg = RwResourceMgrYang.VDUEventData()