diff --git a/zvmconnector/restclient.py b/zvmconnector/restclient.py index a3f842954..594ab5ddb 100644 --- a/zvmconnector/restclient.py +++ b/zvmconnector/restclient.py @@ -338,6 +338,12 @@ def req_guest_get_adapters_info(start_index, *args, **kwargs): return url, body +def req_guest_get_disks_info(start_index, *args, **kwargs): + url = '/guests/%s/disks' + body = None + return url, body + + def req_guest_create_nic(start_index, *args, **kwargs): url = '/guests/%s/nic' body = {'nic': {}} @@ -916,6 +922,11 @@ def req_vswitch_set_vlan_id_for_user(start_index, *args, **kwargs): 'args_required': 2, 'params_path': 1, 'request': req_guest_config_minidisks}, + 'guest_get_disks_info': { + 'method': 'GET', + 'args_required': 1, + 'params_path': 1, + 'request': req_guest_get_disks_info}, 'volume_attach': { 'method': 'POST', 'args_required': 1, diff --git a/zvmsdk/api.py b/zvmsdk/api.py index e74f9e425..97ffcedf5 100755 --- a/zvmsdk/api.py +++ b/zvmsdk/api.py @@ -251,6 +251,18 @@ def guest_get_adapters_info(self, userid): with zvmutils.log_and_reraise_sdkbase_error(action): return self._vmops.get_adapters_info(userid) + def guest_get_disks_info(self, userid): + """Get the disks information of a virtual machine. + + :param str userid: the id of the virtual machine + + :returns: Dictionary contains: + TODO + """ + action = "get disks info of guest '%s'" % userid + with zvmutils.log_and_reraise_sdkbase_error(action): + return self._vmops.get_disks_info(userid) + def guest_get_user_direct(self, userid): """Get user direct of the specified guest vm diff --git a/zvmsdk/sdkwsgi/handler.py b/zvmsdk/sdkwsgi/handler.py index c99ef5da7..da5d63a09 100644 --- a/zvmsdk/sdkwsgi/handler.py +++ b/zvmsdk/sdkwsgi/handler.py @@ -116,6 +116,7 @@ 'POST': guest.guest_create_disks, 'DELETE': guest.guest_delete_disks, 'PUT': guest.guest_config_disks, + 'GET': guest.guest_get_disks_info, }), ('/smapi-healthy', { 'GET': healthy.healthy, diff --git a/zvmsdk/sdkwsgi/handlers/guest.py b/zvmsdk/sdkwsgi/handlers/guest.py index fdc3512a1..7542f01ce 100644 --- a/zvmsdk/sdkwsgi/handlers/guest.py +++ b/zvmsdk/sdkwsgi/handlers/guest.py @@ -115,6 +115,11 @@ def get_adapters(self, req, userid): info = self.client.send_request('guest_get_adapters_info', userid) return info + @validation.query_schema(guest.userid_list_query) + def get_disks(self, req, userid): + info = self.client.send_request('guest_get_disks_info', userid) + return info + @validation.query_schema(guest.userid_list_query) def get_definition_info(self, req, userid): info = self.client.send_request('guest_get_definition_info', userid) @@ -566,6 +571,25 @@ def _guest_get_adapters_info(req, userid): return req.response +@util.SdkWsgify +@tokens.validate +def guest_get_disks_info(req): + + def _guest_get_disks_info(req, userid): + action = get_handler() + return action.get_disks(req, userid) + + userid = util.wsgi_path_item(req.environ, 'userid') + info = _guest_get_disks_info(req, userid) + + info_json = json.dumps(info) + req.response.status = util.get_http_code_from_sdk_return(info, + additional_handler=util.handle_not_found) + req.response.body = utils.to_utf8(info_json) + req.response.content_type = 'application/json' + return req.response + + @util.SdkWsgify @tokens.validate def guest_get(req): diff --git a/zvmsdk/smtclient.py b/zvmsdk/smtclient.py index 88f67c794..3059a462c 100644 --- a/zvmsdk/smtclient.py +++ b/zvmsdk/smtclient.py @@ -384,6 +384,47 @@ def get_adapters_info(self, userid): found_mac = False return adapters_info + def get_disks_info(self, userid): + rd = "SMAPI %s API Image_Query_DM" % userid + results = None + action = "get info of userid '%s'" % userid + with zvmutils.log_and_reraise_smt_request_failed(action): + results = self._request(rd) + ret = results['response'] + disks_info = [] + for line in ret: + if line.startswith('MDISK'): + vdev = line.split(' ')[1] + rd = ' '.join(( + "SMAPI %s API Image_Disk_Query" % userid, + "--operands", + "-k 'vdasd_id=%s'" % vdev)) + results = None + action = "get disk info of disk '%s'" % vdev + with zvmutils.log_and_reraise_smt_request_failed(action): + results = self._request(rd) + ret2 = results['response'] + disk = dict() + for line2 in ret2: + key = line2.split(':')[0].strip() + value = line2.split(':')[-1].strip() + if key == 'DASD VDEV': + disk['vdev'] = value + if key == 'RDEV': + disk['rdev'] = value + if key == 'Access type': + disk['access_type'] = value + if key == 'Device type': + disk['device_type'] = value + if key == 'Device size': + disk['device_size'] = int(value) + if key == 'Device units': + disk['device_units'] = value + if key == 'Device volume label': + disk['volume_label'] = value + disks_info.append(disk) + return disks_info + def _parse_vswitch_inspect_data(self, rd_list): """ Parse the Virtual_Network_Vswitch_Query_Byte_Stats data to get inspect data. diff --git a/zvmsdk/tests/unit/test_smtclient.py b/zvmsdk/tests/unit/test_smtclient.py index 77fba6fdf..64abd5bb5 100644 --- a/zvmsdk/tests/unit/test_smtclient.py +++ b/zvmsdk/tests/unit/test_smtclient.py @@ -1326,6 +1326,11 @@ def test_get_image_disk_type_failed(self, image_info): self.assertEqual(self._smtclient._get_image_disk_type(image_info), None) + # IN PROGRESS + # @mock.patch.object(smtclient.SMTClient, '_request') + # def test_get_disks_info(self, request): + # userid = 'FakeID' + @mock.patch.object(smtclient.SMTClient, '_request') def test_get_adapters_info(self, request): userid = 'FakeID' diff --git a/zvmsdk/tests/unit/test_vmops.py b/zvmsdk/tests/unit/test_vmops.py index a000a7092..59aae1e10 100644 --- a/zvmsdk/tests/unit/test_vmops.py +++ b/zvmsdk/tests/unit/test_vmops.py @@ -222,6 +222,21 @@ def test_get_info_get_uid_failed(self, gps, gipi, ggbu, gud): self.assertRaises(exception.ZVMVirtualMachineNotExist, self.vmops.get_info, 'fakeid') + @mock.patch("zvmsdk.smtclient.SMTClient.get_disks_info") + def test_get_disks_info(self, get_disks_info): + minidisks = [{'vdev': '0100', + 'rdev': '6018', + 'access_type': 'R/W', + 'device_type': '3390', + 'device_size': 29128, + 'device_units': 'Cylinders', + 'volume_label': 'VM6018'}] + get_disks_info.return_value = minidisks + ret = self.vmops.get_disks_info('fakeid') + print('Eric') + print(ret) + self.assertEqual(ret[0]['vdev'], '0100') + @mock.patch("zvmsdk.smtclient.SMTClient.get_adapters_info") def test_get_adapters_info(self, adapters_info): adapters = [{u'lan_owner': u'SYSTEM', diff --git a/zvmsdk/vmops.py b/zvmsdk/vmops.py index 7eaf3174e..3a9022f55 100755 --- a/zvmsdk/vmops.py +++ b/zvmsdk/vmops.py @@ -149,6 +149,14 @@ def get_adapters_info(self, userid): raise exception.SDKInternalError(msg=msg, modID='guest') return {'adapters': adapters_info} + def get_disks_info(self, userid): + disks_info = self._smtclient.get_disks_info(userid) + if not disks_info: + msg = 'Get disks information failed on: %s' % userid + LOG.error(msg) + raise exception.SDKInternalError(msg=msg, modID='guest') + return {'minidisks': disks_info} + def instance_metadata(self, instance, content, extra_md): pass