more precisely: override execute() of the command or data, not parse(). --- pyanaconda/kickstart.py | 22 +++++++++------------- 1 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index bc1d8b6..7e5480c 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -382,25 +382,21 @@ class IgnoreDisk(commands.ignoredisk.RHEL6_IgnoreDisk): if not self.interactive: anaconda.ksdata.skipSteps.extend(["filter", "filtertype"])
-class Iscsi(commands.iscsi.F10_Iscsi): - def parse(self, args): - tg = commands.iscsi.F10_Iscsi.parse(self, args) - +class IscsiData(commands.iscsi.F10_IscsiData): + def execute(self, anaconda): try: - storage.iscsi.iscsi().addTarget(tg.ipaddr, tg.port, - tg.user, tg.password, tg.user_in, tg.password_in) - log.info("added iscsi target: %s" %(tg.ipaddr,)) + storage.iscsi.iscsi().addTarget(self.ipaddr, self.port, + self.user, self.password, + self.user_in, self.password_in, + anaconda.intf) + log.info("added iscsi target: %s" %(self.ipaddr,)) except (IOError, ValueError), e: raise KickstartValueError, formatErrorMsg(self.lineno, msg=str(e)) - return tg
class IscsiName(commands.iscsiname.FC6_IscsiName): - def parse(self, args): - retval = commands.iscsiname.FC6_IscsiName.parse(self, args) - + def execute(self, anaconda): storage.iscsi.iscsi().initiator = self.iscsiname - return retval
class Keyboard(commands.keyboard.FC3_Keyboard): def execute(self, anaconda): @@ -1092,7 +1088,6 @@ commandMap = { "halt": Reboot, "ignoredisk": IgnoreDisk, "install": Upgrade, - "iscsi": Iscsi, "iscsiname": IscsiName, "keyboard": Keyboard, "lang": Lang, @@ -1111,6 +1106,7 @@ commandMap = { }
dataMap = { + "IscsiData" : IscsiData, "LogVolData": LogVolData, "NetworkData": NetworkData, "PartData": PartitionData,
This gets us rid of iscsi.addTarget() completely.
Currently the kickstart iscsi support is limited to: 1) use the same credentials sets for both the discovery and the login, i.e. user can't specify different sets 2) log into every discovered node (i.e. user can't specify only a subset of discovered targets to log into)
Note that this change makes it easier to implement an enhancement removing both these limitations. --- pyanaconda/kickstart.py | 25 +++++++++++++---- pyanaconda/storage/iscsi.py | 62 +------------------------------------------ 2 files changed, 20 insertions(+), 67 deletions(-)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index 7e5480c..84acd1d 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -384,15 +384,28 @@ class IgnoreDisk(commands.ignoredisk.RHEL6_IgnoreDisk):
class IscsiData(commands.iscsi.F10_IscsiData): def execute(self, anaconda): + self.anaconda = anaconda try: - storage.iscsi.iscsi().addTarget(self.ipaddr, self.port, - self.user, self.password, - self.user_in, self.password_in, - anaconda.intf) - log.info("added iscsi target: %s" %(self.ipaddr,)) - except (IOError, ValueError), e: + discovered_nodes = \ + storage.iscsi.iscsi().discover(self.ipaddr, self.port, + self.user, self.password, + self.user_in, self.password_in, + self.anaconda.intf) + logged_into_nodes = filter(self.iscsi_login, discovered_nodes) + if len(logged_into_nodes) < 1: + msg = _("Could not log into any iSCSI nodes at the portal.") + raise KickstartValueError, formatErrorMsg(self.lineno, + msg=msg) + + except (IOError, ValueError) as e: raise KickstartValueError, formatErrorMsg(self.lineno, msg=str(e)) + def iscsi_login(self, node): + (rc, _) = storage.iscsi.iscsi().log_into_node(node, + self.user, self.password, + self.user_in, self.password_in, + self.anaconda.intf) + return rc
class IscsiName(commands.iscsiname.FC6_IscsiName): def execute(self, anaconda): diff --git a/pyanaconda/storage/iscsi.py b/pyanaconda/storage/iscsi.py index c9c21cc..a29fc36 100644 --- a/pyanaconda/storage/iscsi.py +++ b/pyanaconda/storage/iscsi.py @@ -79,7 +79,7 @@ class iscsi(object): This class will automatically discover and login to iBFT (or other firmware) configured iscsi devices when the startup() method gets called. It can also be used to manually configure iscsi devices - through the addTarget() method. + through the discover() and log_into_node() methods.
As this class needs to make sure certain things like starting iscsid and logging in to firmware discovered disks only happens once @@ -265,66 +265,6 @@ class iscsi(object):
return (rc, msg)
- def addTarget(self, ipaddr, port="3260", user=None, pw=None, - user_in=None, pw_in=None, intf=None): - authinfo = None - found = 0 - logged_in = 0 - - if not has_iscsi(): - raise IOError, _("iSCSI not available") - if self._initiator == "": - raise ValueError, _("No initiator name set") - - if user or pw or user_in or pw_in: - # Note may raise a ValueError - authinfo = libiscsi.chapAuthInfo(username=user, password=pw, - reverse_username=user_in, - reverse_password=pw_in) - self.startup(intf) - - # Note may raise an IOError - found_nodes = libiscsi.discover_sendtargets(address=ipaddr, - port=int(port), - authinfo=authinfo) - if found_nodes == None: - raise IOError, _("No iSCSI nodes discovered") - - if intf: - w = intf.waitWindow(_("Logging in to iSCSI nodes"), - _("Logging in to iSCSI nodes")) - - for node in found_nodes: - # skip nodes we already have - if node in self.nodes: - continue - - found = found + 1 - try: - if (authinfo): - node.setAuth(authinfo) - node.login() - log.info("iscsi.addTarget logged in to %s %s %s" % (node.name, node.address, node.port)) - self.nodes.append(node) - logged_in = logged_in + 1 - except IOError, e: - log.warning( - "Could not log into discovered iscsi target %s: %s" % - (node.name, str(e))) - # some nodes may require different credentials - pass - - if intf: - w.pop() - - if found == 0: - raise IOError, _("No new iSCSI nodes discovered") - - if logged_in == 0: - raise IOError, _("Could not log in to any of the discovered nodes") - - self.stabilize(intf) - def writeKS(self, f): if not self.initiatorSet: return
- def iscsi_login(self, node):
(rc, _) = storage.iscsi.iscsi().log_into_node(node,
self.user, self.password,
self.user_in, self.password_in,
self.anaconda.intf)
return rc
I'd prefer this method to start with at least one underscore.
- Chris
This prevents calling find_program_in_path() repeatedly and having the log message "ISCSID is /sbin/iscsid" all over the place. --- pyanaconda/storage/iscsi.py | 23 +++++++++++------------ 1 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/pyanaconda/storage/iscsi.py b/pyanaconda/storage/iscsi.py index a29fc36..26fa5b5 100644 --- a/pyanaconda/storage/iscsi.py +++ b/pyanaconda/storage/iscsi.py @@ -45,19 +45,18 @@ INITIATOR_FILE="/etc/iscsi/initiatorname.iscsi"
def has_iscsi(): global ISCSID - location = iutil.find_program_in_path("iscsid") - if location: - ISCSID = location - - if ISCSID == "" or not has_libiscsi: - return False - - log.info("ISCSID is %s" % (ISCSID,)) - - # make sure the module is loaded - if not os.access("/sys/module/iscsi_tcp", os.X_OK): - return False - return True + + if os.access("/sys/module/iscsi_tcp", os.X_OK): + if len(ISCSID): + return True + else: + location = iutil.find_program_in_path("iscsid") + if location: + ISCSID = location + log.info("ISCSID is %s" % (ISCSID,)) + return True + + return False
def randomIname(): """Generate a random initiator name the same way as iscsi-iname"""
def has_iscsi(): global ISCSID
- location = iutil.find_program_in_path("iscsid")
- if location:
ISCSID = location
- if ISCSID == "" or not has_libiscsi:
return False
- log.info("ISCSID is %s" % (ISCSID,))
- # make sure the module is loaded
- if not os.access("/sys/module/iscsi_tcp", os.X_OK):
return False
- return True
- if os.access("/sys/module/iscsi_tcp", os.X_OK):
if len(ISCSID):
return True
else:
location = iutil.find_program_in_path("iscsid")
if location:
ISCSID = location
log.info("ISCSID is %s" % (ISCSID,))
return True
- return False
def randomIname(): """Generate a random initiator name the same way as iscsi-iname"""
If you change the first test to "if not os.access..." and have it return False, we can get rid of some of the indentation. Also I don't think you need to use "len(ISCSID)" there. You can just say "if ISCSID:".
- Chris
more precisely: override execute() of the command or data, not parse().
Have you verified with this change that you can still specify iscsi devices in the clearpart and part commands?
- Chris
On 10/27/2010 03:50 PM, Chris Lumens wrote:
more precisely: override execute() of the command or data, not parse().
Have you verified with this change that you can still specify iscsi devices in the clearpart and part commands?
- Chris
Hey,
No, just tested it and I can't, good hunch! The clearpart command checks whether the disk exists in it's parse() already. I am going to rework the set without this patch and send it again.
Ales
This prevents calling find_program_in_path() repeatedly and having the log message "ISCSID is /sbin/iscsid" all over the place. --- pyanaconda/storage/iscsi.py | 17 ++++++++--------- 1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/pyanaconda/storage/iscsi.py b/pyanaconda/storage/iscsi.py index a29fc36..3bd953b 100644 --- a/pyanaconda/storage/iscsi.py +++ b/pyanaconda/storage/iscsi.py @@ -45,18 +45,17 @@ INITIATOR_FILE="/etc/iscsi/initiatorname.iscsi"
def has_iscsi(): global ISCSID - location = iutil.find_program_in_path("iscsid") - if location: - ISCSID = location - - if ISCSID == "" or not has_libiscsi: + + if not os.access("/sys/module/iscsi_tcp", os.X_OK): return False
- log.info("ISCSID is %s" % (ISCSID,)) + if not ISCSID: + location = iutil.find_program_in_path("iscsid") + if not location: + return False + ISCSID = location + log.info("ISCSID is %s" % (ISCSID,))
- # make sure the module is loaded - if not os.access("/sys/module/iscsi_tcp", os.X_OK): - return False return True
def randomIname():
--- pyanaconda/packages.py | 2 +- pyanaconda/upgrade.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/packages.py b/pyanaconda/packages.py index 8c9be1c..eb01f23 100644 --- a/pyanaconda/packages.py +++ b/pyanaconda/packages.py @@ -182,7 +182,7 @@ def setupTimezone(anaconda): args.append("-u")
try: - iutil.execWithRedirect("/usr/sbin/hwclock", args, stdin = None, + iutil.execWithRedirect("/sbin/hwclock", args, stdin = None, stdout = "/dev/tty5", stderr = "/dev/tty5") except RuntimeError: log.error("Failed to set clock") diff --git a/pyanaconda/upgrade.py b/pyanaconda/upgrade.py index c2726fb..5ca8789 100644 --- a/pyanaconda/upgrade.py +++ b/pyanaconda/upgrade.py @@ -161,7 +161,7 @@ def restoreTime(anaconda): return args = [ "--hctosys" ] try: - iutil.execWithRedirect("/usr/sbin/hwclock", args,stdout = "/dev/tty5", + iutil.execWithRedirect("/sbin/hwclock", args,stdout = "/dev/tty5", stderr = "/dev/tty5") except RuntimeError: log.error("Failed to set the clock.")
This gets us rid of iscsi.addTarget() completely.
Currently the kickstart iscsi support is limited to: 1) use the same credentials sets for both the discovery and the login, i.e. user can't specify different sets 2) log into every discovered node (i.e. user can't specify only a subset of discovered targets to log into)
Note that this change makes it easier to implement an enhancement removing both these limitations. --- pyanaconda/kickstart.py | 27 ++++++++++++++++--- pyanaconda/storage/iscsi.py | 62 +------------------------------------------ 2 files changed, 24 insertions(+), 65 deletions(-)
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index bc1d8b6..b60086d 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -383,16 +383,35 @@ class IgnoreDisk(commands.ignoredisk.RHEL6_IgnoreDisk): anaconda.ksdata.skipSteps.extend(["filter", "filtertype"])
class Iscsi(commands.iscsi.F10_Iscsi): + class Login(object): + def __init__(self, iscsi_obj, tg_data): + self.iscsi_obj = iscsi_obj + self.tg_data = tg_data + + def login(self, node): + (rc, _) = self.iscsi_obj.log_into_node( + node, self.tg_data.user, self.tg_data.password, + self.tg_data.user_in, self.tg_data.password_in) + return rc + def parse(self, args): tg = commands.iscsi.F10_Iscsi.parse(self, args)
try: - storage.iscsi.iscsi().addTarget(tg.ipaddr, tg.port, - tg.user, tg.password, tg.user_in, tg.password_in) - log.info("added iscsi target: %s" %(tg.ipaddr,)) - except (IOError, ValueError), e: + iscsi_obj = storage.iscsi.iscsi() + discovered_nodes = iscsi_obj.discover( + tg.ipaddr, tg.port, tg.user, tg.password, + tg.user_in, tg.password_in) + login = self.Login(iscsi_obj, tg) + logged_into_nodes = filter(login.login, discovered_nodes) + if len(logged_into_nodes) < 1: + msg = _("Could not log into any iSCSI nodes at the portal.") + raise KickstartValueError, formatErrorMsg(self.lineno, + msg=msg) + except (IOError, ValueError) as e: raise KickstartValueError, formatErrorMsg(self.lineno, msg=str(e)) + return tg
class IscsiName(commands.iscsiname.FC6_IscsiName): diff --git a/pyanaconda/storage/iscsi.py b/pyanaconda/storage/iscsi.py index c9c21cc..a29fc36 100644 --- a/pyanaconda/storage/iscsi.py +++ b/pyanaconda/storage/iscsi.py @@ -79,7 +79,7 @@ class iscsi(object): This class will automatically discover and login to iBFT (or other firmware) configured iscsi devices when the startup() method gets called. It can also be used to manually configure iscsi devices - through the addTarget() method. + through the discover() and log_into_node() methods.
As this class needs to make sure certain things like starting iscsid and logging in to firmware discovered disks only happens once @@ -265,66 +265,6 @@ class iscsi(object):
return (rc, msg)
- def addTarget(self, ipaddr, port="3260", user=None, pw=None, - user_in=None, pw_in=None, intf=None): - authinfo = None - found = 0 - logged_in = 0 - - if not has_iscsi(): - raise IOError, _("iSCSI not available") - if self._initiator == "": - raise ValueError, _("No initiator name set") - - if user or pw or user_in or pw_in: - # Note may raise a ValueError - authinfo = libiscsi.chapAuthInfo(username=user, password=pw, - reverse_username=user_in, - reverse_password=pw_in) - self.startup(intf) - - # Note may raise an IOError - found_nodes = libiscsi.discover_sendtargets(address=ipaddr, - port=int(port), - authinfo=authinfo) - if found_nodes == None: - raise IOError, _("No iSCSI nodes discovered") - - if intf: - w = intf.waitWindow(_("Logging in to iSCSI nodes"), - _("Logging in to iSCSI nodes")) - - for node in found_nodes: - # skip nodes we already have - if node in self.nodes: - continue - - found = found + 1 - try: - if (authinfo): - node.setAuth(authinfo) - node.login() - log.info("iscsi.addTarget logged in to %s %s %s" % (node.name, node.address, node.port)) - self.nodes.append(node) - logged_in = logged_in + 1 - except IOError, e: - log.warning( - "Could not log into discovered iscsi target %s: %s" % - (node.name, str(e))) - # some nodes may require different credentials - pass - - if intf: - w.pop() - - if found == 0: - raise IOError, _("No new iSCSI nodes discovered") - - if logged_in == 0: - raise IOError, _("Could not log in to any of the discovered nodes") - - self.stabilize(intf) - def writeKS(self, f): if not self.initiatorSet: return
anaconda-devel@lists.stg.fedoraproject.org