def do_detach_volume(oci_session, iscsiadm_session, iqn): """ Detach the volume with given IQN Parameters ---------- oci_session: OCISession The iscsiadm session. iscsiadm_session: iscsiadm.session() ocid: str The OCID. Returns ------- None Raise ----- Exception : when destroy has failed """ _volume = get_volume_by_iqn(oci_session, iqn) if _volume is None: raise Exception("Volume with IQN [%s] not found" % iqn) try: _logger.info("Detaching volume %s (%s)", _volume.get_display_name(), _volume.get_iqn()) _volume.detach() except OCISDKError as e: _logger.debug("Failed to disconnect volume", exc_info=True) raise Exception("Failed to disconnect volume %s: %s" % iqn) from e _logger.debug('Volume detached, detaching it from iSCSI session') if not iscsiadm.detach(iscsiadm_session[iqn]['persistent_portal_ip'], iscsiadm_session[iqn]['persistent_portal_port'], iqn): raise Exception("Failed to detach target %s" % iqn)
def main(): """ Main. Returns ------- int Return value of the operation, if any. 0 otherwise. """ global USE_OCI_SDK global oci_sdk_error global _user_euid oci_sdk_error = None oci_sess = None args = parse_args() _user_euid = os.geteuid() if oci_utils.oci_api.HAVE_OCI_SDK: try: oci_sess = oci_utils.oci_api.OCISession() USE_OCI_SDK = True except Exception as e: oci_sdk_error = str(e) USE_OCI_SDK = False if args.debug: raise if not os.path.isfile("/var/run/ocid.pid"): _logger.error("Warning:\n" "For full functionality of this utility the ocid " "service must be running\n" "The administrator can start it using this command:\n" " sudo systemctl start ocid.service\n") max_volumes = OCIUtilsConfiguration.getint('iscsi', 'max_volumes') if max_volumes > oci_utils._MAX_VOLUMES_LIMIT: _logger.error( "Your configured max_volumes(%s) is over the limit(%s)\n" % (max_volumes, oci_utils._MAX_VOLUMES_LIMIT)) max_volumes = oci_utils._MAX_VOLUMES_LIMIT ocid_cache = load_cache(iscsiadm.ISCSIADM_CACHE, max_age=timedelta(minutes=2))[1] if ocid_cache is None and _user_euid == 0: # run ocid once, to update the cache ocid_refresh(wait=True, debug=args.debug) # now try to load again ocid_cache = load_cache(iscsiadm.ISCSIADM_CACHE, max_age=timedelta(minutes=2))[1] if ocid_cache is None: targets, attach_failed = None, None else: targets, attach_failed = ocid_cache disks = lsblk.list() session = iscsiadm.session() detached = load_cache(__ignore_file)[1] if detached is None: detached = [] if args.create_volume: if _user_euid != 0: _logger.error("You must run this program with root privileges " "to create and attach iSCSI devices.\n") return 1 if len(disks) > max_volumes: _logger.error( "This instance reached the max_volumes(%s)\n" % max_volumes) return 1 # FIXME: use_chap retval = do_create_volume(oci_sess, size=args.create_volume, display_name=args.volume_name) elif args.destroy_volume: if _user_euid != 0: _logger.error("You must run this program with root privileges " "to destroy a iSCSI volume.\n") return 1 retval = do_destroy_volume(oci_sess, args.destroy_volume, args.interactive) if retval == 0: print "Volume %s is destroyed." % args.destroy_volume return retval elif args.detach_iqns: if _user_euid != 0: _logger.error("You must run this program with root privileges " "to detach iSCSI devices.\n") return 1 write_ignore_file = False retval = 0 do_refresh = False for iqn in args.detach_iqns: if not iqn.startswith("iqn."): _logger.error("Invalid IQN %s\n" % iqn) retval = 1 continue if iqn in detached: _logger.error("Target %s is already detached\n" % iqn) retval = 1 continue if iqn not in session: _logger.error("Target %s not found\n" % iqn) retval = 1 continue if 'boot:uefi' in iqn: _logger.error("IQN %s is the boot device, cannot " "detach.\n" % iqn) retval = 1 continue if not unmount_device(session, iqn, disks): if args.interactive: cont = ask_yes_no("Failed to unmount volume. " "Continue detaching anyway?") if not cont: return 1 else: return 1 api_detached = False if USE_OCI_SDK: api_detached = api_detach(oci_sess, iqn) if not iscsiadm.detach(session[iqn]['persistent_portal_ip'], session[iqn]['persistent_portal_port'], iqn): _logger.error("Failed to detach target %s\n" % iqn) retval = 1 else: if not api_detached: detached.append(iqn) write_ignore_file = True do_refresh = True if write_ignore_file: _logger.error("Updating ignore file: %s\n" % detached) write_cache(cache_content=detached, cache_fname=__ignore_file) if do_refresh: ocid_refresh(debug=args.debug) return retval elif args.attach_iqns: if _user_euid != 0: _logger.error("You must run this program with root " "privileges to attach iSCSI devices.\n") return 1 if len(disks) > max_volumes: _logger.error( "This instance reached the max_volumes(%s)\n" % max_volumes) return 1 retval = 0 write_ignore_file = False do_refresh = False for iqn in args.attach_iqns: if iqn.startswith('ocid1.volume.oc'): # it's an OCID if not do_attach_ocid(oci_sess, iqn): retval = 1 continue elif not iqn.startswith("iqn."): _logger.error("Invalid IQN %s \n" % iqn) retval = 1 continue if iqn in session: print "Target %s is already attached." % iqn continue if iqn not in detached and iqn not in attach_failed: _logger.error("Target %s not found\n" % iqn) retval = 1 continue user = args.username passwd = args.password if user is None or passwd is None: (user, passwd) = get_chap_secret(iqn) if do_attach(oci_sess, iqn, targets, user=user, passwd=passwd) != 0: _logger.error("Failed to attach target %s\n" % iqn) retval = 1 else: do_refresh = True if iqn in detached: detached.remove(iqn) if args.username is not None: save_chap_secret(iqn, args.username, args.password) write_ignore_file = True if write_ignore_file: write_cache(cache_content=detached, cache_fname=__ignore_file) if do_refresh: ocid_refresh(debug=args.debug) return retval if args.show: display_current_devices(oci_sess, session, disks) api_display_available_devices(oci_sess, args) if args.create_volume or args.destroy_volume: return retval if detached: print print "Detached devices:" do_refresh = False write_ignore_file = False for iqn in detached: display_detached_device(iqn, targets) if args.interactive: if _user_euid != 0: print "You must run this program with root privileges " \ "to attach iSCSI devices.\n" ans = False else: ans = ask_yes_no("Would you like to attach this device?") if ans: retval = do_attach(oci_sess, iqn, targets) do_refresh = True if retval == 24: # authentication error attach_failed[iqn] = 24 if iqn in detached: detached.remove(iqn) write_ignore_file = True if write_ignore_file: write_cache(cache_content=detached, cache_fname=__ignore_file) if do_refresh: ocid_refresh(debug=args.debug) if attach_failed: print print "Devices that could not be attached automatically:" auth_errors = 0 for iqn in attach_failed.keys(): if attach_failed[iqn] == 24: auth_errors += 1 for iqn in attach_failed.keys(): display_attach_failed_device(iqn, targets, attach_failed) do_refresh = False if args.interactive: if attach_failed[iqn] != 24: # not authentication error ans = True while ans: if _user_euid != 0: print "You must run this program with root " \ "privileges to attach iSCSI devices.\n" ans = False else: ans = ask_yes_no("Would you like to retry " "attaching this device?") if ans: retval = do_attach(oci_sess, iqn, targets) if retval == 0: ans = False do_refresh = True else: ans = False else: # authentication error if _user_euid != 0: print "You must run this program with root " \ "privileges to configure iSCSI devices.\n" ans = False else: ans = ask_yes_no("Would you like to configure this " "device?") if ans: retval = 1 if USE_OCI_SDK: # try and get the user and password from the API retval = do_attach(oci_sess, iqn, targets, None, None) else: (user, passwd) = get_chap_secret(iqn) if user is not None: retval = do_attach(oci_sess, iqn, targets, user, passwd) if retval == 0: print "Device configured automatically." do_refresh = True else: myocid = get_instance_ocid() while ans: print "To find the CHAP username and " \ "password for this device, go to" print "https://console.us-phoenix-1." \ "oraclecloud.com/#/a/compute/instances" \ "/%s/disks?jt=listing" % \ myocid print "Select the Block Volume, then click " \ "the \"iSCSI Commands & Information\" " \ "button." print "CHAP username:"******"CHAP password:"******"Attaching iSCSI device..." retval = do_attach(oci_sess, iqn, targets, user, passwd) if retval != 0: ans = ask_yes_no("Would you like to try " "again?") else: ans = False do_refresh = True if do_refresh: ocid_refresh(debug=args.debug) if not args.interactive and auth_errors: print print "Use the -i or --interactive mode to configure " \ "devices that require authentication information" if not args.show and not attach_failed and not detached: print "All known devices are attached." print "Use the -s or --show option for details." return 0