Skip to content

Commit 49be506

Browse files
committed
update iscsi.py module
- Add a new class to supporting iscsi with the multi targets. - Update the create_iSCSI function. Signed-off-by: Houqi (Nick) Zuo <hzuo@redhat.com>
1 parent 567b3b3 commit 49be506

1 file changed

Lines changed: 202 additions & 1 deletion

File tree

virttest/iscsi.py

Lines changed: 202 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from __future__ import division
1111

12+
import ast
1213
import logging
1314
import os
1415
import re
@@ -833,5 +834,205 @@ def create_iSCSI(params, root_dir=data_dir.get_tmp_dir()):
833834
)
834835
iscsi_instance = IscsiTGT(params, root_dir)
835836
else:
836-
iscsi_instance = IscsiLIO(params, root_dir)
837+
iscsi_instance = (
838+
MultiTargetsIscsiLIO(params, root_dir)
839+
if not params.get("target") and params.get("targets_luns")
840+
else IscsiLIO(params, root_dir)
841+
)
837842
return iscsi_instance
843+
844+
845+
class MultiTargetsIscsiLIO(IscsiLIO):
846+
"""
847+
Iscsi class supporting multi-targets for the LIO backend used in RHEL7.
848+
"""
849+
850+
def __init__(self, params, root_dir):
851+
"""
852+
Init the object based on the params and root_dir.
853+
Note: 'iscsi_targets_luns' in params is introduced at this class.
854+
The structure of 'iscsi_targets_luns':
855+
iscsi_targets_luns =
856+
{
857+
${target01}: {
858+
${lun01} : {"emulated_image": ..., ...},
859+
${lun02} : {"emulated_image": ..., ...},
860+
},
861+
${target02}: {
862+
${lun01} : {"emulated_image": ..., ...},
863+
${lun02} : {"emulated_image": ..., ...},
864+
},
865+
...
866+
}
867+
For example:
868+
{
869+
"iqn.2019-12.com.redhat:target01": {
870+
"lun0": { "emulated_image": "images/basefile1",
871+
"emulated_image_size": "40G",
872+
"portal_ip": "127.0.0.1",
873+
...
874+
},
875+
"lun1": { "emulated_image": "images/basefile2",
876+
"emulated_image_size": "10G",
877+
"portal_ip": "127.0.0.1",
878+
...
879+
},
880+
},
881+
"iqn.2019-12.com.redhat:target02": {
882+
"lun0": { "emulated_image": "images/basefile3",
883+
"emulated_image_size": "20G",
884+
"portal_ip": "127.0.0.1",
885+
...
886+
},
887+
"lun1": { "emulated_image": "images/basefile4",
888+
"emulated_image_size": "30G",
889+
"portal_ip": "127.0.0.1",
890+
...
891+
},
892+
},
893+
}
894+
If there's only one lun without any special assigned requests,
895+
lun should be set to "default_lun", for example:
896+
iscsi_targets_luns = {
897+
"iqn.2019-12.com.redhat:target01": {
898+
"default_lun": {
899+
"emulated_image": "images/basefile",
900+
"emulated_image_size": "40G",
901+
"portal_ip": "127.0.0.1",
902+
...
903+
},
904+
},
905+
}
906+
907+
:param params: parameters dict for iSCSI
908+
:param root_dir: path for image
909+
"""
910+
self._targets_luns = ast.literal_eval(params.get("iscsi_targets_luns"))
911+
# stores the iscsiLIO objects based on each targets
912+
self._targets_mapping = {}
913+
for target in self._targets_luns:
914+
single_target_param = params.copy()
915+
for lun in self._targets_luns[target]:
916+
single_target_param.update(self._targets_luns[target][lun])
917+
single_target_param["target"] = target
918+
single_target_param["iscsi_backend"] = "fileio"
919+
self._targets_mapping[target] = IscsiLIO(single_target_param, root_dir)
920+
if lun not in ("default_lun",):
921+
self._targets_mapping[target].luns = lun
922+
923+
def query_targets(self, emulated_image=None, lun=None):
924+
"""
925+
Dynamically filter the targets from image name given and lun given.
926+
927+
:param emulated_image: the image name. If none, do NOT check emulated_image
928+
:type emulated_image: string
929+
:param lun: the lun. If none, do NOT check lun
930+
:type lun: string
931+
932+
:return: the targets in list or []
933+
:rtype: list
934+
"""
935+
cmd = "targetcli ls /iscsi 1"
936+
target_info = process.run(cmd).stdout_text
937+
targets = re.findall(r"iqn[\.]\S+:\S+", target_info)
938+
939+
filtered_targets = []
940+
for target in targets:
941+
cmd = "targetcli ls /iscsi/%s/tpg1/luns" % target
942+
luns_info = process.run(cmd).stdout_text
943+
if (
944+
(not emulated_image and not lun)
945+
or (emulated_image and not lun and emulated_image + ")" in luns_info)
946+
or (
947+
emulated_image
948+
and lun
949+
and emulated_image + ")" in luns_info
950+
and " " + lun + " " in luns_info
951+
)
952+
):
953+
filtered_targets.append(target)
954+
return filtered_targets
955+
956+
def set_chap_auth_target(self, target=None):
957+
"""
958+
set up authentication information for every single initiator,
959+
which provides the capability to define common login information
960+
for all Endpoints in a TPG
961+
962+
:param target: the target.
963+
:type target: string
964+
"""
965+
targets = [target] if target else self._targets_mapping.keys()
966+
for target in targets:
967+
self._targets_mapping[target].set_chap_auth_target()
968+
969+
def export_target(self, target=None):
970+
"""
971+
Export target(s) in localhost for emulated iscsi.
972+
973+
:param target: the target.
974+
:type target: string
975+
"""
976+
targets = [target] if target else self._targets_mapping.keys()
977+
for target in targets:
978+
self._targets_mapping[target].export_target()
979+
980+
def delete_target(self, target=None):
981+
"""
982+
Delete target(s) from host.
983+
984+
:param target: the target.
985+
:type target: string
986+
"""
987+
targets = [target] if target else self._targets_mapping.keys()
988+
for target in targets:
989+
self._targets_mapping[target].delete_target()
990+
991+
def login(self, target=None):
992+
"""
993+
Login target. If target is None, login in with each target in this class.
994+
995+
:param target: the target.
996+
:type target: string
997+
"""
998+
if target:
999+
self._targets_mapping[target].login()
1000+
else:
1001+
for obj in self._targets_mapping.values():
1002+
obj.login()
1003+
1004+
def cleanup(self, target=None, confirmed=False):
1005+
"""
1006+
Clean up env after iscsi used.
1007+
1008+
:param target: the target.
1009+
:type target: string
1010+
:param confirmed: switch for cleanup all iscsi config
1011+
:type confirmed: bool
1012+
"""
1013+
targets = [target] if target else self._targets_mapping.keys()
1014+
for target in targets:
1015+
self._targets_mapping[target].cleanup(confirmed)
1016+
1017+
def logout(self, target=None):
1018+
"""
1019+
Logout from target.
1020+
1021+
:param target: the target.
1022+
:type target: string
1023+
"""
1024+
if self._targets_mapping[target].logged_in():
1025+
iscsi_logout(self.target)
1026+
1027+
def logged_in(self, target=None):
1028+
"""
1029+
Check if the session is login or not.
1030+
1031+
:param target: the target.
1032+
:type target: string
1033+
1034+
:return: logged in or not
1035+
:rtype: bool
1036+
"""
1037+
if target:
1038+
return self._targets_mapping[target].logged_in()

0 commit comments

Comments
 (0)