#! /usr/bin/env python # ----------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ----------------------------------------------------------------------- # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + # + ducc_disk_info # + # + purpose: report on DUCC_HOME disk usage # + # + input: none (DUCC_HOME implied from location of this script) # + # + output: filesystem=% quota=% # + # + exit code: the greater of { i, j } # + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import os import subprocess import sys from optparse import HelpFormatter from optparse import OptionGroup from optparse import OptionParser # ---------------------------------------------- # Extend OptionParser class class ExtendedOptionParser(OptionParser): # override epilog formatter so # that newlines are not deleted! def format_epilog(self, formatter): return self.epilog # ---------------------------------------------- cmd_df = 'df' cmd_quota = 'quota' code = -1 message = 'DUCC_HOME: ' # epilog for --help def get_epilog(): epilog = '' epilog = epilog + '\n' epilog = epilog+'Purpose: display the filesystem and quota usage for the DUCC_HOME directory relative to the location of this script.' epilog = epilog + '\n' return epilog # parse command line def parse_cmdline(): global options parser = ExtendedOptionParser(epilog=get_epilog()) width = 45 parser.formatter.help_position = width parser.formatter.max_help_position = width parser.add_option('--code', action='store_true', dest='flag_code', default=False, help='display exit code, which is the greater of disk usage percentage and quota usage percentage') parser.add_option('--debug', action='store_true', dest='flag_debug', default=False, help='display debug information') parser.add_option('--nomsg', action='store_false', dest='flag_msg', default=True, help='suppress display of filesystem and quota percentages used message') (options, args) = parser.parse_args() # normalize path to always end with / def normalize_path(path): retVal = path if(not path.endswith('/')): retVal = path+'/' return retVal # normalize quota value to bytes def normalize_quota(value): if(value.endswith('M')): tval = value.split('M')[0] retVal = int(tval)*1024*1024 elif(value.endswith('k')): tval = value.split('k')[0] retVal = int(tval)*1024 else: retVal = int(value) return retVal # determine quota usage def check_quota(): global code global cmd_quota global message global filesystem try: p = subprocess.Popen([cmd_quota, '-A'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() qfs = None data = None fs1 = normalize_path(filesystem) #print fs1 for line in out.splitlines(): tokens = line.split() #print tokens if(qfs == None): fs2 = normalize_path(tokens[0]) #print fs2 if(fs1 == fs2): qfs = fs1 elif(data == None): data = tokens break blocks = normalize_quota(data[0]) limit = normalize_quota(data[2]) qpct = int(blocks/(limit*1.0)*100) #print qfs, blocks, limit, qpct message = message+'quota='+str(qpct)+'%'+' ' except Exception,e: emessage = 'Exception: '+str(e) emessage = emessage.strip() if(options.flag_debug): print emessage message = message+'quota='+'N/A'+' ' return # determine filesystem usage def check_disk(): global ducc_home global code global cmd_df global message global filesystem try: p = subprocess.Popen([cmd_df, ducc_home], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() pctused = 0 for line in out.splitlines(): tokens = line.split() filesystem = tokens[0].strip() pctused = tokens[4].split('%')[0] number = float(pctused) if(pctused > code): code = pctused message = message+'filesystem='+pctused+'%'+' ' except Exception,e: emessage = 'Exception: '+str(e) emessage = emessage.strip() if(options.flag_debug): print emessage message = message+'filesystem='+'N/A'+' ' return # process def process(): check_disk() check_quota() return # initialize def initialize(): global ducc_home pathname = os.path.dirname(sys.argv[0]) ducc_home = pathname.rsplit('/',2)[0] parse_cmdline() return # main def main(argv): global ducc_home global message global code try: initialize() process() except Exception,e: message = 'Exception: '+str(e) message = message.strip() if(options.flag_msg): print message if(options.flag_code): sys.exit(code) if __name__ == '__main__': main(sys.argv[1:])