| #!/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.get_db_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:]) |
| |
| |