class XendGpfsIsoStorageRepo(XendStorageRepository):
    """A backwards compatibility storage repository so that
    traditional file:/dir/file.img and phy:/dev/hdxx images can
    still be represented in terms of the Xen API.
    """
    
    def __init__(self, sr_uuid, sr_type,
                 name_label, name_description, physical_size, other_config, content_type, shared, sm_config):
        """
        @ivar    images: mapping of all the images.
        @type    images: dictionary by image uuid.
        @ivar    lock:   lock to provide thread safety.
        """
        XendStorageRepository.__init__(self, sr_uuid, sr_type,
                                       name_label, name_description)
        #log.debug(self.lock)
        #log.debug(self.uuid)
        self.type = sr_type
        self.name_label = name_label
        self.name_description = name_description
        self.other_config = other_config
        self.content_type = content_type
        self.shared = shared
        self.sm_config = sm_config
#        location = other_config.get('location')
        encode_passwd = other_config.get('password')
        self.passwd = encoding.ansi_decode(encode_passwd)
        auto = other_config.get('auto-scan', True)
#        local = location.split(':')[1]
#        if cmp(int(storage_max())*KB, physical_size) > 0:
#            self.physical_size = physical_size
#        else:
        location = self.other_config.get('location')
        self.local_sr_dir = location
        self.location = location
        self.mount_point = self._get_mount_point(self.location)
#        s_max = storage_max(self.local_sr_dir)
#        if s_max:
#            self.physical_size = int(s_max)*KB
#        else:
#            self.physical_size = 0
#        s_util = storage_util(self.local_sr_dir)
#        if s_util:
#            self.physical_utilisation = int(s_util)*KB
#        else:
#            self.physical_utilisation = 0
#        d_util = dir_util(self.local_sr_dir)
#        if d_util:
#            self.virtual_allocation = int(d_util)*KB
#        else:
#            self.virtual_allocation = 0
        self.state = XendStateStore(xendoptions().get_xend_state_path()
                                    + '/gpfs_iso_sr/%s' % self.uuid)
        stored_images = self.state.load_state('vdi')
        images_path = {}
        if stored_images:
            for image_uuid, image in stored_images.items():
                images_path[image['location'].replace(VDI_TYPE, '')] = image_uuid
                self.images[image_uuid] = XendLocalVDI(image)
#        self.update(auto)
        #self.save_state(True)
        #XendNode.instance().test_obj = self
#        TestObj.obj = self
#        log.debug(self.__dict__)

    def update(self, auto=True):
#        location = self.other_config.get('location')
#        local = location.split(':')[1]
        local = self.local_sr_dir
        stored_images = self.state.load_state('vdi')
        images_path = {}
        if stored_images:
            for image_uuid, image in stored_images.items():
                images_path[image['location'].replace(VDI_TYPE, '')] = image_uuid
                self.images[image_uuid] = XendLocalVDI(image)
        if auto:
            isos = iso_files(local)
            log.debug(isos)
            vdi_struct = {}
            for iso in isos.keys():
                if iso not in images_path.keys():
                    vdi_struct['other_config'] = {}
                    vdi_struct['location'] = VDI_TYPE+iso
                    vdi_struct['type'] = 'system'
                    vdi_struct['physical_utilisation'] = isos[iso]
                    vdi_struct['VBDs'] = []
                    vdi_struct['name_label'] = os.path.basename(iso)
                    #XendTask.log_progress(0, 100, self.create_vdi_append_state, vdi_struct)
    #                self.images[image_new] = XendLocalVDI(image)
                    self.create_vdi_append_state(vdi_struct)
            cd_rom = 'phy:/dev/sr0'
            log.debug(images_path.keys())
            if cd_rom not in images_path.keys():
                log.debug('In cd-rom create.')
                vdi_struct['other_config'] = {}
                vdi_struct['location'] = cd_rom
                vdi_struct['type'] = 'system'
                vdi_struct['VBDs'] = []
                vdi_struct['name_label'] = 'cd-rom'  
                self.create_vdi_append_state(vdi_struct)    
            import copy
            image_now = copy.deepcopy(images_path)          
            for img,vdi_uuid in image_now.items():
                if img not in isos.keys() and cmp(img, cd_rom) != 0:
                    self.destroy_vdi(vdi_uuid)

    def get_record(self, transient = True):
        retval = {'uuid': self.uuid,
                  'name_label': self.name_label,
                  'name_description': self.name_description,
                  'resident_on' : XendNode.instance().uuid,
                  'virtual_allocation': 0,
                  'physical_utilisation': self.get_physical_utilisation(),
                  'physical_size': self.get_physical_size(),
                  'type': self.type,
                  'content_type': self.content_type,
                  'VDIs': self.images.keys(),
                  'PBDs': XendPBD.get_by_SR(self.uuid),
                  'other_config': self.other_config,
                  'shared': self.shared,
                  'mount_point': self.mount_point, 
                  'sm_config': self.sm_config,}
        return retval
    
    def get_physical_utilisation(self):
        s_util = storage_util(self.local_sr_dir)
        if s_util:
            self.physical_utilisation = int(s_util)*KB
        else:
            self.physical_utilisation = 0
        return self.physical_utilisation
        
    def get_physical_size(self):
        s_max = storage_max(self.local_sr_dir)
        if s_max:
            self.physical_size = int(s_max)*KB
        else:
            self.physical_size = 0   
        return self.physical_size       

    def _get_mount_point(self, location):
        tmp = location.rsplit('/', 1)
        return tmp[0]      

    def create_vdi(self, vdi_struct, transient = False):
        """ Creates a fake VDI image for a traditional image string.

        The image uri is stored in the attribute 'uri'
        """
        if not vdi_struct.get('uuid') or vdi_struct.get('uuid') == '':
            vdi_struct['uuid'] = uuid.createString()
        vdi_struct['SR'] = self.uuid
        new_image = XendLocalVDI(vdi_struct)
        if vdi_struct.get('type') == 'user':            
#            self.create_img_file(vdi_struct)
            self.create_logical_volume(vdi_struct)    
        self.images[new_image.uuid] = new_image
        self.save_state(transient)
        return new_image.uuid
    
    def create_vdi_append_state(self, vdi_struct, transient = True):
        """ Creates a fake VDI image for a traditional image string.

        The image uri is stored in the attribute 'uri'
        """
#        f = open("/opt/xen/bug", "a")
        
#        if not vdi_struct.get('uuid') or vdi_struct.get('uuid') == '':
        vdi_struct['uuid'] = uuid.createString()
        vdi_struct['SR'] = self.uuid
        new_image = XendLocalVDI(vdi_struct)
        if vdi_struct.get('type') == 'user':            
#            self.create_img_file(vdi_struct)
            self.create_logical_volume(vdi_struct)    
        self.images[new_image.uuid] = new_image
        self.append_state(new_image, transient)
#        f.write("go to here\n")
#        f.close()
        return new_image.uuid

    def create_img_file(self, vdi_struct, path=None, size=None):
        path = IMG_FILE_PATH + vdi_struct.get('uuid') + '.img'
        size = int(vdi_struct.get('virtual_size')) * KB
        subprocess.Popen("vhd-util create -n %s -s %d" % (path, size), shell=True,
                           stdout=subprocess.PIPE)
        p = subprocess.Popen("dd if=/dev/zero of=%s bs=1M count=0 seek=%d" % (path, size), shell=True,
                           stdout=subprocess.PIPE)
#        log.debug("dd if=/dev/zero of=%s bs=1M count=0 seek=%d" % (path, size))

    def change_vdi_name_label(self, vdi_uuid, new_name):
        location = self.images[vdi_uuid].location.replace(VDI_TYPE, '')
        old_name = self.images[vdi_uuid].name_label
        new_location = location.replace(old_name, new_name)
        cmd = "mv %s %s" % (location, new_location)
        result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        self.update()

    def del_img_file_from_ssh(self, vdi_uuid):
#        location = self.other_config['location']
#        host_url = location.split(':')[0]
#        local = location.split(':')[1]
#        vdi_name = self.images[vdi_uuid].name_label
#        file = '%s/%s' %(local, vdi_name)
        location = self.images[vdi_uuid].location.replace(VDI_TYPE, '')
        cmd = 'rm -f %s' % location
        result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)

    def get_vg_name(self):
        cmd = [VG_BINARY, '--noheadings', '--nosuffix', '--options=vg_name']
        (rc, stdout, stderr) = doexec(cmd)
        if rc != 0:
            err = stderr.read();
            out = stdout.read();
            stdout.close();
            stderr.close();
            raise Exception, 'Failed to get VG name. Check that lvm installed in dom0.';
        vg_name = stdout.read()
        stdout.close()
        stderr.close()
        return vg_name
        
    def create_logical_volume(self, vdi_struct, lv_name=None, size=None, vg_name=None):
        lv_name = 'VHD-' + vdi_struct.get('uuid')
        size = int(vdi_struct.get('virtual_size')) * KB
        vg_name = mytrim(self.get_vg_name())
        cmd = [LV_CREATE_BINARY, '%s' %vg_name, '-L', '%dM' %size, '-n', '%s' %lv_name]
        (rc, stdout, stderr) = doexec(cmd)
        if rc != 0:
            err = stderr.read();
            out = stdout.read();
            stdout.close();
            stderr.close();
            raise Exception, 'Failed to create logical volume: %s, lv_size: %d on VG: %s.\n%s' %(lv_name, size, vg_name, err);
        stdout.close()
        stderr.close()

    def save_state(self, transient=False):
        vdi_records = dict([(k, v.get_record(transient))
                            for k, v in self.images.items()])
        self.state.save_state('vdi', vdi_records)

    def append_state(self, new_image, transient):
        vdi_records = dict([(new_image.uuid, new_image.get_record(transient))])
        self.state.append_state('vdi', vdi_records)

    def destroy_vdi(self, vdi_uuid, del_file=True, transient = False):
#        if vdi_name:
#            for vdi_ref, image in self.images.items():
#                if image.name_label == vdi_name:
#                    vdi_uuid = vdi_ref
        if vdi_uuid in self.images:
            tmp = self.other_config['location'].split(':')
            exists = os.path.exists(tmp[len(tmp)-1])
            log.debug("in images")
            if exists and del_file:
                self.del_img_file_from_ssh(vdi_uuid)
            del self.images[vdi_uuid]
        else:
            log.debug("error: must not be here")
        self.save_state(transient)
        XendNode.instance().save_SRs()