#!/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. # ----------------------------------------------------------------------- import os import sys import glob import subprocess import string import binascii from ducc_util import DuccUtil class DuccRmQOccupancy(DuccUtil): def format(self, nodes, shares): typemap = {'R':'Res', 'M':' AP', 'J':'Job', 'S':'Svc'} print("%20s %6s %11s %6s %10s %15s %10s %6s %6s %6s %8s %7s %10s %8s" % ("Node", "Status", "Blacklisted", "Online", "Responsive", "Nodepool", "Memory", "Order", "Free", "In-Use", "Np-InUse", "Quantum", "Reservable", "Classes")) print("%20s %6s %11s %6s %10s %15s %10s %6s %6s %6s %8s %7s %10s %8s" % ("----", "------", "-----------", "------", "----------", "--------", "------", "-----", "----", "------", "--------", "-------", "----------", "-------")) for n in nodes: if (n['blacklisted'] == 'False' and n['online'] == 'True' and n['responsive'] == 'True'): status = 'up' else: status = 'down' print "%20s %6s %11s %6s %10s %15s %10s %3s(Q) %6s %6s %8s %7s %10s %-8s" % (n['name'], status, n['blacklisted'], n['online'], n['responsive'], n['nodepool'], n['memory'], n['share_order'], n['shares_left'], n['assignments'], n['np_assignments'], n['quantum'], n['reservable'], n['classes']) if ( shares.has_key(n['name']) ): for s in shares[n['name']]: type = typemap[s['jobtype']] fmt = '%19s ' + type +':%-8s ShareId:%-8s Shares:%-s InitTime:%-8s Investment:%-8s Evicted:%-5s Purged:%-5s Fixed:%-5s State:%-10s' state = s['state'] if ( state == 'null' ): state = "Assigned" print fmt % ('', s['job_id'], s['ducc_dbid'], s['share_order'], s['init_time'], s['investment'], s['evicted'], s['purged'], s['fixed'], state) print '' def parse_header(self, header): ret = [] parts = header.split('|') for p in parts: ret.append(p.strip()) return ret def parse_node(self, header, line): parts = line.split('|') ret = {} for k, v in zip(header, parts): ret[k] = v.strip() return ret def parse_share(self, header, line): parts = line.split('|') ret = {} for k, v in zip(header, parts): ret[k] = v.strip() return ret def rmnodes(self, lines): nodes = [] shares = {} header = [] for l in lines: if ( l == '' ): continue if ( '---' in l ): continue; if ( 'rows)' in l ): continue; if ( 'assignments' in l ): doing_nodes = True doing_shares = False header = self.parse_header(l) continue if ( 'investment' in l ): doing_nodes = False doing_shares = True header = self.parse_header(l) continue if ( doing_nodes ): nodes.append(self.parse_node(header, l)) continue if ( doing_shares ): s = self.parse_share(header, l) k = s['node'] if ( shares.has_key(k) ): share_list = shares[k] else: share_list = [] shares[k] = share_list share_list.append(s) continue return nodes, shares def main(self, argv): if len(argv) > 0: print 'rm_qoccupancy queries and formats the current state of the RM scheduling tables. It takes no parameters.' sys.exit(1); DH = self.DUCC_HOME dbn = self.ducc_properties.get('ducc.database.host') guest_pw = self.db_password_guest os.environ['TERM'] = 'dumb' # insure no colors. --no-color isn't inhibiting colors in this shell for some reason. CMD = [DH + '/cassandra-server/bin/cqlsh', dbn, '-u', 'guest', '-p', guest_pw, '-e', '"select * from ducc.rmnodes; select * from ducc.rmshares;"'] CMD = ' '.join(CMD) lines = [] proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True) for line in proc.stdout: # print line.strip() lines.append(line.strip()) nodes, shares = self.rmnodes(lines) self.format(nodes, shares) if __name__ == "__main__": stopper = DuccRmQOccupancy() stopper.main(sys.argv[1:])