#!/usr/bin/python # # This script delete replica from the namespace. # # Arguments must be a list of file replica or the log file of dpm-drain. # When using the log file of a dpm-drain, entries for files marked as deleted are processed. # # Written by Michel Jouvin import sys import traceback import os import re import socket from optparse import OptionParser drain_valid_status = 'deleted|uploaded' try: import dpm2 as dpm except: python_version_toks = re.match('(?P\d\.\d)',sys.version) python_version = python_version_toks.group('major') lcg_location = os.getenv('LCG_LOCATION') if not lcg_location: lcg_location = '/opt/lcg' dpm_module_found = False for archlib in ('lib64','lib'): python_site_packages = 'python%s/site-packages' % python_version for pythondir in ('python', python_site_packages): dpm_module_location = "%s/%s/%s" % (lcg_location, archlib, pythondir) dpm_module_found = os.path.exists(dpm_module_location+'/dpm2.py') if dpm_module_found: break if dpm_module_found: break if dpm_module_location: sys.path.append(dpm_module_location) import dpm2 as dpm else: debug(0,"Unable to locate dpm2 Python module. Define PYTHONPATH appropriately") sys.exit(1) parser = OptionParser() parser.add_option('--delete', dest='really_delete', action='store_true', default=False, help="Really delete selected replica") parser.add_option('--dpm', dest='dpm_server', action='store', default=None, help="Name of the DPM head node") parser.add_option('--drain-log', dest='drain_log', action='store', help="Name of a dpm-drain log file") parser.add_option('--file', dest='rep_file', action='store', help="Name of the file containing the replica list") parser.add_option('--status', dest='file_status', action='store', help="Status of replica (with --drain-log only)") options, args = parser.parse_args() if options.dpm_server: dpns_server = options.dpm_server else: dpns_server = os.getenv('DPNS_HOST') if not dpns_server: dpns_server = socket.gethostname() print "Defining DPNS server to %s" % dpns_server os.environ['DPNS_HOST'] = dpns_server if not os.getenv('DPM_HOST'): print "Defining DPM server to %s" % dpns_server os.environ['DPM_HOST'] = dpns_server rep_list = None if options.rep_file and options.drain_log: print "--file and --drain-log are mutually exclusive" sys.exit(1) if options.rep_file: rep_list = open(options.rep_file) if options.drain_log: if not options.file_status: print "--status required with --drain-log. Possible values: deleted, uploaded or all" sys.exit(1) else: status_matcher = re.match('^'+drain_valid_status+'|all$',options.file_status) if status_matcher: if options.file_status == 'all': file_status = drain_valid_status else: file_status = options.file_status else: print "--status invalid value. Possible values: deleted, uploaded or all" sys.exit(1) rep_list = [] drain_log = open(options.drain_log) for line in drain_log: matcher = re.match('.*: The file\s(?P.*)\sis (recorded as being )?in the process of being '+file_status,line) if matcher: rep_list.append(matcher.group('file')) if not rep_list: rep_list = args if not rep_list: print "No replica to process" sys.exit(2) for replica in rep_list: replica = replica.rstrip() try: rep_infos = dpm.dpns_statr(replica) except ValueError: print "Replica %s doesn't exist in the namespace" % (replica) continue except Exception: print "Error finding information aobut replica %s: %s" % (replica,traceback.format_exception_only(sys.exc_type,sys.exc_value)[0]) continue if options.really_delete: print "Deleting replica %s (fileid=%d)..." % (replica,rep_infos.fileid) rep_file_id = dpm.dpns_fileid() rep_file_id.fileid = rep_infos.fileid rep_file_id.server = dpns_server try: dpm.dpns_delreplica(None,rep_file_id,replica) except Exception: print "Error deleting replica %s: %s" % (replica,traceback.format_exception_only(sys.exc_type,sys.exc_value)[0]) continue else: print "Replica %s (fileid=%d) will be deleted if --delete is specified" % (replica,rep_infos.fileid)