Beispiel #1
0
 def do_cd(self, arg):
     if arg == "":
         self.current = "/"
     elif arg == "..":
         self.current = os.path.dirname(self.current)
     elif isdir(self.up, arg):
         self.current = os.path.join(self.current, arg)
     else:
         tmp = os.path.join(self.current, arg)
         if isdir(self.up, tmp):
             self.current = tmp
Beispiel #2
0
 def do_cd(self, arg):
     if arg == "":
         self.current = "/"
     elif arg == "..":
         self.current = os.path.dirname(self.current)
     elif isdir(self.up, arg):
         self.current = os.path.join(self.current, arg)
     else:
         tmp = os.path.join(self.current, arg)
         if isdir(self.up, tmp):
             self.current = tmp
Beispiel #3
0
def scan_srlist(path, dconf):
    """Scan and report SR, UUID."""
    dom = xml.dom.minidom.Document()
    element = dom.createElement("SRlist")
    dom.appendChild(element)
    for val in filter(util.match_uuid, util.ioretry(
            lambda: util.listdir(path))):
        fullpath = os.path.join(path, val)
        if not util.ioretry(lambda: util.isdir(fullpath)):
            continue

        entry = dom.createElement('SR')
        element.appendChild(entry)

        subentry = dom.createElement("UUID")
        entry.appendChild(subentry)
        textnode = dom.createTextNode(val)
        subentry.appendChild(textnode)

    from NFSSR import PROBEVERSION
    if dconf.has_key(PROBEVERSION):
        util.SMlog("Add supported nfs versions to sr-probe")
        supported_versions = get_supported_nfs_versions(dconf.get('server'))
        supp_ver = dom.createElement("SupportedVersions")
        element.appendChild(supp_ver)

        for ver in supported_versions:
            version = dom.createElement('Version')
            supp_ver.appendChild(version)
            textnode = dom.createTextNode(ver)
            version.appendChild(textnode)

    return dom.toprettyxml()
Beispiel #4
0
def soft_mount(mountpoint, remoteserver, remotepath, transport):
    """Mount the remote NFS export at 'mountpoint'"""
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException, inst:
        raise NfsException("Failed to make directory: code is %d" % inst.code)
Beispiel #5
0
    def attach(self, sr_uuid):
        if not util.ioretry(lambda: self._checkmount()):
            try:
                # make sure NFS over TCP/IP V3 is supported on the server
                util.ioretry(lambda: util.pread(["/usr/sbin/rpcinfo","-t", \
                              "%s" % self.remoteserver, "nfs","3"]), \
                              errlist=[errno.EPERM], nofail=1)
            except util.CommandException as inst:
                raise xs_errors.XenError('NFSVersion', \
                      opterr='or NFS server timed out')
            try:
                # make a mountpoint:
                if not util.ioretry(lambda: util.isdir(self.path)):
                    util.ioretry(lambda: util.makedirs(self.path))

                timeout = int((SOFTMOUNT_TIMEOUT / 3.0) * 10.0)
                util.ioretry(lambda: util.pread(["mount.nfs", "%s:%s" \
                             % (self.remoteserver, self.remotepath),  \
                             self.path, "-o", \
                             "udp,soft,timeo=%d,retrans=1,noac" % \
                             timeout]), errlist=[errno.EPIPE, errno.EIO],
                             nofail=1)
            except util.CommandException as inst:
                raise xs_errors.XenError('NFSMount')
        return super(NFSSR, self).attach(sr_uuid)
Beispiel #6
0
def main():
    """
        Parse all the arguments
    """
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", help="Input", type=str, default="")
    parser.add_argument("--output", help="Output", type=str, default="")
    parser.add_argument("--dtype",
                        help="Data type of the input sequence",
                        type=str,
                        default="uint8")
    args = parser.parse_args()
    if not util.istifseq(args.input):
        print('Input directory should contain a TIF sequence')
        sys.exit()
    if not util.isdir(args.output):
        print('Output directory')
        sys.exit()
    """
        Read the volume file
    """
    data = imread_tifseq(args.input, dtype=args.dtype)
    """
        Write the volume to the desired format 
    """
    imwrite_pngseq(data, args.output)
Beispiel #7
0
    def mount(self, mountpoint=None):
        """Mount the remote CIFS export at 'mountpoint'"""
        if mountpoint == None:
            mountpoint = self.mountpoint
        elif not util.is_string(mountpoint) or mountpoint == "":
            raise CifsException("mountpoint not a string object")

        missing_params = set()

        if not self.dconf.has_key('username'):
            missing_params.add('username')

        if not (self.dconf.has_key('password') or
                self.dconf.has_key('password_secret')):
            missing_params.add('password')

        if missing_params:
            errstr = 'device-config is missing the following parameters: ' + \
                     ', '.join([param for param in missing_params])
            raise xs_errors.XenError('ConfigParamsMissing', opterr=errstr)

        try:
            if not util.ioretry(lambda: util.isdir(mountpoint)):
                util.ioretry(lambda: util.makedirs(mountpoint))
        except util.CommandException, inst:
            raise CifsException("Failed to make directory: code is %d" %
                                inst.code)
Beispiel #8
0
def scan_srlist(path, dconf):
    """Scan and report SR, UUID."""
    dom = xml.dom.minidom.Document()
    element = dom.createElement("SRlist")
    dom.appendChild(element)
    for val in filter(util.match_uuid,
                      util.ioretry(lambda: util.listdir(path))):
        fullpath = os.path.join(path, val)
        if not util.ioretry(lambda: util.isdir(fullpath)):
            continue

        entry = dom.createElement('SR')
        element.appendChild(entry)

        subentry = dom.createElement("UUID")
        entry.appendChild(subentry)
        textnode = dom.createTextNode(val)
        subentry.appendChild(textnode)

    from NFSSR import PROBEVERSION
    if dconf.has_key(PROBEVERSION):
        util.SMlog("Add supported nfs versions to sr-probe")
        supported_versions = get_supported_nfs_versions(dconf.get('server'))
        supp_ver = dom.createElement("SupportedVersions")
        element.appendChild(supp_ver)

        for ver in supported_versions:
            version = dom.createElement('Version')
            supp_ver.appendChild(version)
            textnode = dom.createTextNode(ver)
            version.appendChild(textnode)

    return dom.toprettyxml()
Beispiel #9
0
def soft_mount(mountpoint, remoteserver, remotepath, transport):
    """Mount the remote NFS export at 'mountpoint'"""
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException, inst:
        raise NfsException("Failed to make directory: code is %d" % 
                            inst.code)
Beispiel #10
0
 def _checkpath(self, path):
     try:
         if util.ioretry(lambda: util.pathexists(path)):
             if util.ioretry(lambda: util.isdir(path)):
                 return True
         return False
     except util.CommandException, inst:
         raise xs_errors.XenError("EIO", opterr="IO error checking path %s" % path)
 def _checkpath(self, path):
     try:
         if util.ioretry(lambda: util.pathexists(path)):
             if util.ioretry(lambda: util.isdir(path)):
                 return True
         return False
     except util.CommandException, inst:
         raise xs_errors.XenError('EIO', \
               opterr='IO error checking path %s' % path)
Beispiel #12
0
Datei: nfs.py Projekt: BobBall/sm
def soft_mount(mountpoint, remoteserver, remotepath, transport, timeout=0,
               nfsversion=DEFAULT_NFSVERSION):
    """Mount the remote NFS export at 'mountpoint'.
    The 'timeout' param here is in seconds"""
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException, inst:
        raise NfsException("Failed to make directory: code is %d" % 
                            inst.code)
Beispiel #13
0
    def scan(self, sr_uuid):
        """Scan: see _loadvdis"""
        if not util.isdir(self.path):
            return

        self._loadvdis()
        self.physical_size = util.get_fs_size(self.path)
        self.physical_utilisation = util.get_fs_utilisation(self.path)
        self.virtual_allocation = self._sum_vdis()

        return super(LocalISOSR, self).scan(sr_uuid)
Beispiel #14
0
    def mount(self, mountpoint=None):
        """Mount the remote gluster export at 'mountpoint'"""
        if mountpoint is None:
            mountpoint = self.mountpoint
        elif not util.is_string(mountpoint) or mountpoint == "":
            raise GlusterFSException("mountpoint not a string object")

        try:
            if not util.ioretry(lambda: util.isdir(mountpoint)):
                util.ioretry(lambda: util.makedirs(mountpoint))
        except util.CommandException, inst:
            raise GlusterFSException("Failed to make directory: code is %d" % inst.code)
Beispiel #15
0
Datei: nfs.py Projekt: stormi/sm
def soft_mount(mountpoint, remoteserver, remotepath, transport, useroptions='',
               timeout=None, nfsversion=DEFAULT_NFSVERSION, retrans=None):
    """Mount the remote NFS export at 'mountpoint'.

    The 'timeout' param here is in deciseconds (tenths of a second). See
    nfs(5) for details.
    """
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException as inst:
        raise NfsException("Failed to make directory: code is %d" %
                           inst.code)


    # Wait for NFS service to be available
    try: 
        if not check_server_service(remoteserver):
            raise util.CommandException(code=errno.EOPNOTSUPP,
                    reason="No NFS service on host")
    except util.CommandException as inst: 
        raise NfsException("Failed to detect NFS service on server %s" 
                           % remoteserver)

    mountcommand = 'mount.nfs'
    if nfsversion == '4':
        mountcommand = 'mount.nfs4'
        
    if nfsversion == '4.1':
        mountcommand = 'mount.nfs4'

    options = "soft,proto=%s,vers=%s" % (
        transport,
        nfsversion)
    options += ',acdirmin=0,acdirmax=0'

    if timeout != None:
        options += ",timeo=%s" % timeout
    if retrans != None:
        options += ",retrans=%s" % retrans
    if useroptions != '':
        options += ",%s" % useroptions

    try:
        util.ioretry(lambda:
                     util.pread([mountcommand, "%s:%s"
                                 % (remoteserver, remotepath),
                                 mountpoint, "-o", options]),
                     errlist=[errno.EPIPE, errno.EIO],
                     maxretry=2, nofail=True)
    except util.CommandException as inst:
        raise NfsException("mount failed with return code %d" % inst.code)
Beispiel #16
0
def soft_mount(mountpoint, remoteserver, remotepath, transport, useroptions='',
               timeout=None, nfsversion=DEFAULT_NFSVERSION, retrans=None):
    """Mount the remote NFS export at 'mountpoint'.

    The 'timeout' param here is in deciseconds (tenths of a second). See
    nfs(5) for details.
    """
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException, inst:
        raise NfsException("Failed to make directory: code is %d" %
                           inst.code)
Beispiel #17
0
    def mount(self, mountpoint=None):
        """Mount the remote SMB export at 'mountpoint'"""
        if mountpoint == None:
            mountpoint = self.mountpoint
        elif not util.is_string(mountpoint) or mountpoint == "":
            raise SMBException("mountpoint not a string object")

        try:
            if not util.ioretry(lambda: util.isdir(mountpoint)):
                util.ioretry(lambda: util.makedirs(mountpoint))
        except util.CommandException, inst:
            raise SMBException("Failed to make directory: code is %d" %
                                inst.code)
Beispiel #18
0
def soft_mount(mountpoint, remoteserver, remotepath, transport, useroptions='',
               timeout=None, nfsversion=DEFAULT_NFSVERSION, retrans=None):
    """Mount the remote NFS export at 'mountpoint'.

    The 'timeout' param here is in deciseconds (tenths of a second). See
    nfs(5) for details.
    """
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException, inst:
        raise NfsException("Failed to make directory: code is %d" %
                           inst.code)
Beispiel #19
0
def Get(up, src, dst, output=True):
    if isdir(up, src) and os.path.isdir(dst):
        return Gets(up, src, dst)

    if isdir(up, src) and not os.path.isdir(dst):
        return False

    if not isdir(up, src) and os.path.isdir(dst):
        dst += basename(src)

    err = False
    try:
        f = open(dst, "wb")
        up.get(src, f)
        if output:
            print src, "====>>>", dst
    except:
        err = True

    f.close()
    if err and output:
        print "Download Error"
        return err
Beispiel #20
0
def Get(up, src, dst, output=True):
    if isdir(up, src) and os.path.isdir(dst):
        return Gets(up, src, dst)

    if isdir(up, src) and not os.path.isdir(dst):
        return False

    if not isdir(up, src) and os.path.isdir(dst):
        dst += basename(src)

    err = False
    try:
        f = open(dst, "wb")
        up.get(src, f)
        if output:
            print src, "====>>>", dst
    except:
        err = True

    f.close()
    if err and output:
        print "Download Error"
        return err
Beispiel #21
0
def soft_mount(mountpoint,
               remoteserver,
               remotepath,
               transport,
               timeout=0,
               nfsversion=DEFAULT_NFSVERSION):
    """Mount the remote NFS export at 'mountpoint'.

    The 'timeout' param here is in seconds
    """
    try:
        if not util.ioretry(lambda: util.isdir(mountpoint)):
            util.ioretry(lambda: util.makedirs(mountpoint))
    except util.CommandException, inst:
        raise NfsException("Failed to make directory: code is %d" % inst.code)
Beispiel #22
0
def Put(up, src, dst, output=True):
    # i'm so damn like python
    if os.path.isdir(src) and isdir(up, dst):
        return Puts(up, src, dst)

    if os.path.isdir(src) and not isdir(up, dst):
        return True

    if os.path.isfile(src) and isdir(up, dst):
        dst += basename(src)

    err = False
    try:
        f = open(src, "rb")
        up.put(dst, f)
        if output:
            print src, "====>>>", dst
    except:
        err = True

    f.close()
    if err and output:
        print "Upload Error"
        return err
Beispiel #23
0
def Put(up, src, dst, output=True):
    # i'm so damn like python
    if os.path.isdir(src) and isdir(up, dst):
        return Puts(up, src, dst)

    if os.path.isdir(src) and not isdir(up, dst):
        return True

    if os.path.isfile(src) and isdir(up, dst):
        dst += basename(src)

    err = False
    try:
        f = open(src, "rb")
        up.put(dst, f)
        if output:
            print src, "====>>>", dst
    except:
        err = True

    f.close()
    if err and output:
        print "Upload Error"
        return err
Beispiel #24
0
    def mount(self, mountpoint, blockdevice):
        try:
            if not util.ioretry(lambda: util.isdir(mountpoint)):
                util.ioretry(lambda: util.makedirs(mountpoint))
        except util.CommandException:
            raise xs_errors.XenError('SRUnavailable', \
                  opterr='no such directory %s' % mountpoint)

        cmd = ['mount', '-t', 'ocfs2', blockdevice, mountpoint, '-o', \
               'noatime,data=writeback,nointr,commit=60,coherency=buffered']
        try:
             ret = util.pread(cmd)
        except util.CommandException, inst:
             raise xs_errors.XenError('OCFSMount', 
                                      opterr='Failed to mount FS. Errno is %d' \
                                             % os.strerror(inst.code))
Beispiel #25
0
def scan_srlist(path):
    dom = xml.dom.minidom.Document()
    element = dom.createElement("SRlist")
    dom.appendChild(element)
    for val in filter(util.match_uuid, util.ioretry( \
            lambda: util.listdir(path))):
        fullpath = os.path.join(path, val)
        if not util.ioretry(lambda: util.isdir(fullpath)):
            continue
            
        entry = dom.createElement('SR')
        element.appendChild(entry)
        
        subentry = dom.createElement("UUID")
        entry.appendChild(subentry)
        textnode = dom.createTextNode(val)
        subentry.appendChild(textnode)

    return dom.toprettyxml()
Beispiel #26
0
Datei: nfs.py Projekt: yunleid/sm
def scan_srlist(path):
    dom = xml.dom.minidom.Document()
    element = dom.createElement("SRlist")
    dom.appendChild(element)
    for val in filter(util.match_uuid, util.ioretry( \
            lambda: util.listdir(path))):
        fullpath = os.path.join(path, val)
        if not util.ioretry(lambda: util.isdir(fullpath)):
            continue

        entry = dom.createElement('SR')
        element.appendChild(entry)

        subentry = dom.createElement("UUID")
        entry.appendChild(subentry)
        textnode = dom.createTextNode(val)
        subentry.appendChild(textnode)

    return dom.toprettyxml()
Beispiel #27
0
    def mount(self, mountpoint, blockdevice):
        try:
            if not util.ioretry(lambda: util.isdir(mountpoint)):
                util.ioretry(lambda: util.makedirs(mountpoint))
        except util.CommandException:
            raise xs_errors.XenError("SRUnavailable", opterr="no such directory %s" % mountpoint)

        cmd = [
            "mount",
            "-t",
            "ocfs2",
            blockdevice,
            mountpoint,
            "-o",
            "noatime,data=writeback,nointr,commit=60,coherency=buffered",
        ]
        try:
            ret = util.pread(cmd)
        except util.CommandException, inst:
            raise xs_errors.XenError("OCFSMount", opterr="Failed to mount FS. Errno is %d" % os.strerror(inst.code))
Beispiel #28
0
    def attach(self, sr_uuid):
        if not util.ioretry(lambda: self._checkmount()):
            try:
                # make sure NFS over TCP/IP V3 is supported on the server
                util.ioretry(lambda: util.pread(["/usr/sbin/rpcinfo","-t", \
                              "%s" % self.remoteserver, "nfs","3"]), \
                              errlist=[errno.EPERM], nofail=1)
            except util.CommandException, inst:
                raise xs_errors.XenError('NFSVersion', \
                      opterr='or NFS server timed out')
            try:
                # make a mountpoint:
                if not util.ioretry(lambda: util.isdir(self.path)):
                    util.ioretry(lambda: util.makedirs(self.path))

                timeout = int((SOFTMOUNT_TIMEOUT / 3.0) * 10.0)
                util.ioretry(lambda: util.pread(["mount.nfs", "%s:%s" \
                             % (self.remoteserver, self.remotepath),  \
                             self.path, "-o", \
                             "udp,soft,timeo=%d,retrans=1,noac" % \
                             timeout]), errlist=[errno.EPIPE, errno.EIO],
                             nofail=1)
            except util.CommandException, inst:
                raise xs_errors.XenError('NFSMount')
Beispiel #29
0
    def attach(self, sr_uuid):
        """Std. attach"""
        # Very-Legacy mode means the ISOs are in the local fs - so no need to attach.
        if 'legacy_mode' in self.dconf:
            # Verify path exists
            if not os.path.exists(self.mountpoint):
                raise xs_errors.XenError('ISOLocalPath')
            return

        # Check whether we're already mounted
        if self._checkmount():
            return

        # Create the mountpoint if it's not already there
        if not util.isdir(self.mountpoint):
            util.makedirs(self.mountpoint)

        mountcmd = []
        location = util.to_plain_string(self.dconf['location'])
        # TODO: Have XC standardise iso type string
        protocol = 'nfs_iso'
        options = ''

        if 'type' in self.dconf:
            protocol = self.dconf['type']
        elif ":/" not in location:
            protocol = 'cifs'

        if 'options' in self.dconf:
            options = self.dconf['options'].split(' ')
            if protocol == 'cifs':
                options = filter(lambda x: x != "", options)
            else:
                options = self.getNFSOptions(options)

        # SMB options are passed differently for create via
        # XC/xe sr-create and create via xe-mount-iso-sr
        # In both cases check if SMB version is passed are not.
        # If not use self.smbversion.
        if protocol == 'cifs':
            if 'type' in self.dconf:
                # Create via XC or sr-create
                # Check for username and password
                mountcmd = ["mount.cifs", location, self.mountpoint]
                if 'vers' in self.dconf:
                    self.is_smbversion_specified = True
                    self.smbversion = self.dconf['vers']
                    util.SMlog("self.dconf['vers'] = %s" % self.dconf['vers'])
                self.appendCIFSMountOptions(mountcmd)
            else:
                # Creation via xe-mount-iso-sr
                try:
                    mountcmd = ["mount", location, self.mountpoint]
                    if options and options[0] == '-o':
                        pos = options[1].find('vers=')
                        if pos == -1:
                            options[1] += ',' + self.getSMBVersion()
                        else:
                            self.smbversion = self.getSMBVersionFromOptions(
                                options[1])
                            self.is_smbversion_specified = True
                    else:
                        raise ValueError
                    mountcmd.extend(options)
                except ValueError:
                    raise xs_errors.XenError('ISOInvalidXeMountOptions')
            # Check the validity of 'smbversion'.
            # Raise an exception for any invalid version.
            if self.smbversion not in [SMB_VERSION_1, SMB_VERSION_3]:
                raise xs_errors.XenError('ISOInvalidSMBversion')

        # Attempt mounting
        try:
            if protocol == 'nfs_iso':
                # For NFS, do a soft mount with tcp as protocol. Since ISO SR is
                # going to be r-only, a failure in nfs link can be reported back
                # to the process waiting.
                serv_path = location.split(':')
                util._testHost(serv_path[0], NFSPORT, 'NFSTarget')
                nfs.soft_mount(self.mountpoint,
                               serv_path[0],
                               serv_path[1],
                               'tcp',
                               useroptions=options,
                               nfsversion=self.nfsversion)
            else:
                smb3_fail_reason = None
                if self.smbversion in SMB_VERSION_3:
                    util.SMlog('ISOSR mount over smb 3.0')
                    try:
                        self.mountOverSMB(mountcmd)
                    except util.CommandException as inst:
                        if not self.is_smbversion_specified:
                            util.SMlog('Retrying ISOSR mount over smb 1.0')
                            smb3_fail_reason = inst.reason
                            # mountcmd is constructed such that the last two
                            # items will contain -o argument and its value.
                            del mountcmd[-2:]
                            self.smbversion = SMB_VERSION_1
                            if not options:
                                self.appendCIFSMountOptions(mountcmd)
                            else:
                                if options[0] == '-o':
                                    # regex can be used here since we have
                                    # already validated version entry
                                    options[1] = re.sub(
                                        'vers=3.0', 'vers=1.0', options[1])
                                mountcmd.extend(options)
                            self.mountOverSMB(mountcmd)
                        else:
                            raise xs_errors.XenError('ISOMountFailure',
                                                     opterr=inst.reason)
                else:
                    util.SMlog('ISOSR mount over smb 1.0')
                    self.mountOverSMB(mountcmd)
        except util.CommandException as inst:
            if not self.is_smbversion_specified:
                raise xs_errors.XenError('ISOMountFailure',
                                         opterr=smb3_fail_reason)
            else:
                raise xs_errors.XenError('ISOMountFailure', opterr=inst.reason)

        # Check the iso_path is accessible
        if not self._checkmount():
            self.detach(sr_uuid)
            raise xs_errors.XenError('ISOSharenameFailure')
Beispiel #30
0
    def scan(self, sr_uuid):
        """Scan: see _loadvdis"""
        if not util.isdir(self.path):
            raise xs_errors.XenError('SRUnavailable', \
                    opterr='no such directory %s' % self.path)

        if ('legacy_mode' not in self.dconf) and (not self._checkmount()):
            raise xs_errors.XenError('SRUnavailable', \
                    opterr='directory not mounted: %s' % self.path)

        #try:
        if not self.vdis:
            self._loadvdis()
        self.physical_size = util.get_fs_size(self.path)
        self.physical_utilisation = util.get_fs_utilisation(self.path)
        self.virtual_allocation = self.physical_size

        other_config = self.session.xenapi.SR.get_other_config(self.sr_ref)

        if 'xenserver_tools_sr' in other_config and \
                other_config['xenserver_tools_sr'] == "true":
            # Out of all the xs-tools ISOs which exist in this dom0, we mark
            # only one as the official one.

            # Pass 1: find the latest version
            latest_build_vdi = None
            latest_build_number = "0"
            for vdi_name in self.vdis:
                vdi = self.vdis[vdi_name]

                if latest_build_vdi is None:
                    latest_build_vdi = vdi.location
                    latest_build_number = "0"

                if 'xs-tools-build' in vdi.sm_config:
                    bld = vdi.sm_config['xs-tools-build']
                    if bld >= latest_build_number:
                        latest_build_vdi = vdi.location
                        latest_build_number = bld

            # Pass 2: mark all VDIs accordingly
            for vdi_name in self.vdis:
                vdi = self.vdis[vdi_name]
                if vdi.location == latest_build_vdi:
                    vdi.sm_config['xs-tools'] = "true"
                else:
                    if "xs-tools" in vdi.sm_config:
                        del vdi.sm_config['xs-tools']

            # Synchronise the VDIs: this will update the sm_config maps of current records
            scanrecord = SR.ScanRecord(self)
            scanrecord.synchronise_new()
            scanrecord.synchronise_existing()

            # Everything that looks like an xs-tools ISO but which isn't the
            # primary one will also be renamed "Old version of ..."
            sr = self.session.xenapi.SR.get_by_uuid(sr_uuid)
            all_vdis = self.session.xenapi.VDI.get_all_records_where(
                "field \"SR\" = \"%s\"" % sr)
            for vdi_ref in all_vdis.keys():
                vdi = all_vdis[vdi_ref]
                if 'xs-tools-version' in vdi['sm_config']:
                    name = tools_iso_name(vdi['location'])
                    if 'xs-tools' in vdi['sm_config']:
                        self.session.xenapi.VDI.set_name_label(vdi_ref, name)
                    else:
                        self.session.xenapi.VDI.set_name_label(
                            vdi_ref, "Old version of " + name)

            # never forget old VDI records to cope with rolling upgrade
            for location in scanrecord.gone:
                vdi = scanrecord.get_xenapi_vdi(location)
                util.SMlog(
                    "Marking previous version of tools ISO: location=%s uuid=%s"
                    % (vdi['location'], vdi['uuid']))
                vdi = self.session.xenapi.VDI.get_by_uuid(vdi['uuid'])
                name_label = self.session.xenapi.VDI.get_name_label(vdi)
                if not (name_label.startswith("Old version of ")):
                    self.session.xenapi.VDI.set_name_label(
                        vdi, "Old version of " + name_label)
                # Mark it as missing for informational purposes only
                self.session.xenapi.VDI.set_missing(vdi, True)
                self.session.xenapi.VDI.remove_from_sm_config(vdi, 'xs-tools')

        else:
            return super(ISOSR, self).scan(sr_uuid)