def detach_target(self, target): with sqlite3.connect(self.SQLITE_DB) as con: cur = con.cursor() tgt_num = self.find_iscsi_target_num(target) runCommand(['tgtadm', '--lld', 'iscsi', '--op', 'delete', '--mode', 'target', '--tid', tgt_num])# remove iscsi target cur.execute('UPDATE zvols SET iscsi_target = NULL where iscsi_target = ?',[target]) con.commit()
def find_iscsi_target_num(self, target): """ This is only called of using tgt """ out = runCommand(['tgtadm', '--op', 'show', '--mode', 'target']) for line in out: if line.startswith('Target ') and line.split()[2] == target: return (line.split()[1])[:-1] return None
def download_snapshot( self, zpool, zvol, remotehost, ): params = { 'user': self.imgUser, 'zpool': zpool, 'zvol': zvol, 'snap_name': self.snapname(), 'remotehost': remotehost, 'remotehost_zpool': self.get_node_zpool(remotehost), 'local_last_snapshot': self.find_last_snapshot(zpool, zvol), } download_speed = imgstorage.get_attribute('img_download_speed', remotehost, self.logger) params['throttle'] = (' | pv -L %s -q ' % download_speed if download_speed else '' ) runCommand(['su', self.imgUser, '-c', '/usr/bin/ssh %(remotehost)s "/sbin/zfs snap %(remotehost_zpool)s/%(zvol)s@%(snap_name)s"' % params]) runCommand(['su %(user)s -c \'/usr/bin/ssh %(remotehost)s "/sbin/zfs send -i %(remotehost_zpool)s/%(zvol)s@%(local_last_snapshot)s %(remotehost_zpool)s/%(zvol)s@%(snap_name)s"\' %(throttle)s | zfs receive -F %(zpool)s/%(zvol)s' % params], shell=True) def destroy_local_snapshot(snapshot): runCommand(['/sbin/zfs', 'destroy', snapshot]) out = runCommand([ '/sbin/zfs', 'list', '-Hpr', '-t', 'snapshot', '-o', 'name', '-s', 'creation', '%s/%s' % (zpool, zvol), ]) ## Find only the snapshots that we have created out = filter(lambda x : x.find(self.prefix) >= 0, out) map(destroy_local_snapshot, out[:-2])
def upload_snapshot( self, zpool, zvol, remotehost, remotezpool, ): args = [ '/opt/rocks/bin/snapshot_upload.sh', '-p', zpool, '-v', zvol, '-r', remotehost, '-y', remotezpool, '-u', self.imgUser ] upload_speed = self.getZvolAttr(zvol, 'uploadspeed') if (not upload_speed): upload_speed = self.getAttr('uploadspeed') if (upload_speed): args.extend(['-t', upload_speed]) runCommand(args)
def find_iscsi_target_num(self, target): out = runCommand(['tgtadm', '--op', 'show', '--mode', 'target']) self.logger.debug("Looking for target's number in output of tgtadm") for line in out: if line.startswith('Target ') and line.split()[2] == target: tgt_num = line.split()[1][:-1] self.logger.debug("target number is %s"%tgt_num) return tgt_num return None
def get_iscsi_targets_orig(): """return a list of all the active target the dictionary keys are the target names and the data is their associated TID""" out = runCommand(['tgtadm', '--op', 'show', '--mode', 'target']) ret = [] for line in out: if line.startswith('Target ') and len(line.split()) >= 2: ret.append(line.split()[1]) return ret
def get_iscsi_targets(): """return a list of all the active target the dictionary keys are the target names and the data is their associated TID""" out = runCommand(['tgtadm', '--op', 'show', '--mode', 'target']) ret = [] for line in out: if line.startswith('Target ') and len(line.split()) >= 2: ret.append(line.split()[2]) return ret
def upload_snapshot( self, zpool, zvol, remotehost, remotezpool, ): args = ['/opt/rocks/bin/snapshot_upload.sh', '-p', zpool, '-v', zvol, '-r', remotehost, '-y', remotezpool, '-u', self.imgUser] upload_speed = self.getZvolAttr(zvol,'uploadspeed') if(not upload_speed): upload_speed = self.getAttr('uploadspeed') if(upload_speed): args.extend(['-t', upload_speed]) runCommand(args)
def get_iscsi_targets(): """return a list of all the active target the dictionary keys are the target names and the data is their associated TID""" out = runCommand(['targetcli', 'iscsi/', 'ls']) print out ret = [] for line in out: if 'TPG' in line and len(line.split()) >= 2: ret.append(line.split()[1]) return ret
def delete_target_orig(self,target): if target: tgt_num = self.find_iscsi_target_num(target) if tgt_num: # this cammand is also run be the rocks clean host storagemap # which is not inside an IOLoop for the moment do not use coroutine # TODO find a solution for this runCommand([ # remove iscsi target 'tgtadm', '--lld', 'iscsi', '--op', 'delete', '--mode', 'target', '--tid', tgt_num, ])
def download_snapshot( self, zpool, zvol, remotehost, remotezpool, is_delete_remote, ): args = [ '/opt/rocks/bin/snapshot_download.sh', '-p', zpool, '-v', zvol, '-r', remotehost, '-y', remotezpool, '-u', self.imgUser ] if (is_delete_remote): args.append('-d') download_speed = self.getZvolAttr(zvol, 'downloadspeed') if (not download_speed): download_speed = self.getAttr('downloadspeed') if (download_speed and not is_delete_remote): args.extend(['-t', download_speed]) runCommand(args)
def clean_vm(self, nas, volume): import imgstorage.imgstoragevm # ISCSI target removal mappings = imgstorage.imgstoragevm.get_blk_dev_list() target_name = nas + '-' + volume def func(x): return x.endswith(target_name) target = self.find_one(mappings, func, target_name) if target: target = target[0] print "removing ISCSI target ", target imgstorage.imgstoragevm.disconnect_iscsi(target) # device mapper removal dm_name = '%s-snap' % volume dm_path = '/dev/mapper/' + dm_name if os.path.exists(dm_path): print 'removing dm ', dm_name imgstorage.runCommand(['dmsetup', 'remove', dm_name]) # zfs FS removal targets = [] zfs_list = imgstorage.imgstoragevm.get_zfs_list() vol_name = volume def func(x): return x.split('/')[-1] == vol_name targets.extend(self.find_one(zfs_list, func, vol_name)) vol_name = volume + '-temp-write' targets.extend(self.find_one(zfs_list, func, vol_name)) for target in targets: print "removing zfs volume ", target imgstorage.runCommand(['zfs', 'destroy', '-r', target])
def upload_snapshot( self, zpool, zvol, remotehost, ): params = { 'user': self.imgUser, 'zpool': zpool, 'zvol': zvol, 'snap_name': self.snapname(), 'remotehost': remotehost, 'remotehost_zpool': self.get_node_zpool(remotehost), } upload_speed = imgstorage.get_attribute('img_upload_speed', remotehost, self.logger) params['throttle'] = (' | pv -L %s -q ' % upload_speed if upload_speed else '') runCommand(['zfs', 'snap', '%(zpool)s/%(zvol)s@%(snap_name)s' % params]) runCommand(['zfs send %(zpool)s/%(zvol)s@%(snap_name)s %(throttle)s | su %(user)s -c \'ssh %(remotehost)s "/sbin/zfs receive -F %(remotehost_zpool)s/%(zvol)s"\'' % params], shell=True)
def download_snapshot( self, zpool, zvol, remotehost, remotezpool, is_delete_remote, ): args = ['/opt/rocks/bin/snapshot_download.sh', '-p', zpool, '-v', zvol, '-r', remotehost, '-y', remotezpool, '-u', self.imgUser] if(is_delete_remote): args.append('-d') download_speed = self.getZvolAttr(zvol,'downloadspeed') if(not download_speed): download_speed = self.getAttr('downloadspeed') if(download_speed and not is_delete_remote): args.extend(['-t', download_speed]) runCommand(args)
def detach_target(self, target, is_remove_host): if target: tgt_num = self.find_iscsi_target_num(target) if tgt_num: # this cammand is also run be the rocks clean host storagemap # which is not inside an IOLoop for the moment do not use coroutine # TODO find a solution for this runCommand([ # remove iscsi target 'tgtadm', '--lld', 'iscsi', '--op', 'delete', '--mode', 'target', '--tid', tgt_num, ]) with sqlite3.connect(self.SQLITE_DB) as con: cur = con.cursor() if is_remove_host: cur.execute('''UPDATE zvols SET iscsi_target = NULL, remotehost = NULL, remotepool = NULL where iscsi_target = ?''' , [target]) else: cur.execute('''UPDATE zvols SET iscsi_target = NULL where iscsi_target = ?''' , [target]) con.commit()
def detach_target(self, target, is_remove_host): if target: tgt_num = self.find_iscsi_target_num(target) if tgt_num: # this cammand is also run be the rocks clean host storagemap # which is not inside an IOLoop for the moment do not use coroutine # TODO find a solution for this runCommand([ # remove iscsi target 'tgtadm', '--lld', 'iscsi', '--op', 'delete', '--mode', 'target', '--tid', tgt_num, ]) with sqlite3.connect(self.SQLITE_DB) as con: cur = con.cursor() if is_remove_host: cur.execute( '''UPDATE zvols SET iscsi_target = NULL, remotehost = NULL, remotepool = NULL where iscsi_target = ?''', [target]) else: cur.execute( '''UPDATE zvols SET iscsi_target = NULL where iscsi_target = ?''', [target]) con.commit()
def del_zvol(self, message, props): zvol_name = message['zvol'] self.logger.debug("Deleting zvol %s"%zvol_name) with sqlite3.connect(self.SQLITE_DB) as con: cur = con.cursor() try : self.lock_zvol(zvol_name, props.reply_to) cur.execute('SELECT hosting, iscsi_target FROM zvols WHERE zvol = ?',[zvol_name]) row = cur.fetchone() if row == None: raise ActionError('ZVol %s not found in database'%zvol_name) if row[1] != None: raise ActionError('Error deleting zvol %s: is mapped'%zvol_name) self.logger.debug("Invoking zfs destroy %s/%s"%(self.ZPOOL,zvol_name)) runCommand(['zfs', 'destroy', '%s/%s'%(self.ZPOOL, zvol_name)]) self.logger.debug('zfs destroy success %s'%zvol_name) cur.execute('DELETE FROM zvols WHERE zvol = ?',[zvol_name]) con.commit() self.release_zvol(zvol_name) self.queue_connector.publish_message({'action': 'zvol_deleted', 'status': 'success'}, exchange='', routing_key=props.reply_to) except ActionError, err: if not isinstance(err, ZvolBusyActionError): self.release_zvol(zvol_name) self.failAction(props.reply_to, 'zvol_deleted', str(err))
def find_last_snapshot(self, zpool, zvol): out = runCommand([ 'zfs', 'list', '-Hpr', '-t', 'snapshot', '-o', 'name', '-s', 'creation', '%s/%s' % (zpool, zvol), ]) if not out: raise ActionError('No shapshots found') return out[-1].split('@')[1]
def destroy_local_snapshot(snapshot): runCommand(['/sbin/zfs', 'destroy', snapshot])
def find_iscsi_target_num(self, target): out = runCommand(['tgtadm', '--op', 'show', '--mode', 'target']) for line in out: if line.startswith('Target ') and line.split()[2] == target: return (line.split()[1])[:-1] return None
def delete_target(self,target): all_targets = get_iscsi_targets() if target in all_targets: runCommand(['targetcli','iscsi/','delete', target])
def set_zvol(self, message, props): hosting = message['hosting'] zvol_name = message['zvol'] self.logger.debug("Setting zvol %s"%zvol_name) with sqlite3.connect(self.SQLITE_DB) as con: cur = con.cursor() try : self.lock_zvol(zvol_name, props.reply_to) cur.execute('SELECT count(*) FROM zvols WHERE zvol = ?',[zvol_name]) if(cur.fetchone()[0] == 0): runCommand(['zfs', 'create', '-o', 'primarycache=metadata', '-o', 'volblocksize=128K', '-V', '%sgb'%message['size'], '%s/%s'%(self.ZPOOL, zvol_name)]) cur.execute('INSERT OR REPLACE INTO zvols VALUES (?,?,?) ',(zvol_name, None, None)) con.commit() self.logger.debug('Created new zvol %s'%zvol_name) cur.execute('SELECT iscsi_target FROM zvols WHERE zvol = ?',[zvol_name]) row = cur.fetchone() if (row != None and row[0] != None): #zvol is mapped raise ActionError('Error when mapping zvol: already mapped') ip = None use_ib = False if(self.ib_net): try: ip = socket.gethostbyname('%s.%s'%(hosting, self.ib_net)) use_ib = True except: pass if not use_ib: try: ip = socket.gethostbyname(hosting) except: raise ActionError('Host %s is unknown'%hosting) iscsi_target = '' out = runCommand(['tgt-setup-lun', '-n', zvol_name, '-d', '/dev/%s/%s'%(self.ZPOOL, zvol_name), ip]) for line in out: if "Creating new target" in line: iscsi_target = line['Creating new target (name='.__len__():line.index(',')] self.logger.debug('Mapped %s to iscsi target %s'%(zvol_name, iscsi_target)) cur.execute('INSERT OR REPLACE INTO zvols VALUES (?,?,?) ',(zvol_name, iscsi_target,hosting)) con.commit() def failDeliver(target, zvol, reply_to, hosting): self.detach_target(target) self.failAction(props.reply_to, 'zvol_attached', 'Compute node %s is unavailable'%hosting) self.release_zvol(zvol_name) self.queue_connector.publish_message( {'action': 'set_zvol', 'target':iscsi_target, 'nas': ('%s.%s'%(self.NODE_NAME, self.ib_net)) if use_ib else self.NODE_NAME}, hosting, self.NODE_NAME, on_fail=lambda: failDeliver(iscsi_target, zvol_name, props.reply_to, hosting)) self.logger.debug("Setting iscsi %s sent"%iscsi_target) except ActionError, err: if not isinstance(err, ZvolBusyActionError): self.release_zvol(zvol_name) self.failAction(props.reply_to, 'zvol_attached', str(err))