diff options
Diffstat (limited to 'kubernetes/contrib/tools/oomstat.py')
-rwxr-xr-x | kubernetes/contrib/tools/oomstat.py | 256 |
1 files changed, 0 insertions, 256 deletions
diff --git a/kubernetes/contrib/tools/oomstat.py b/kubernetes/contrib/tools/oomstat.py deleted file mode 100755 index 464290d3f6..0000000000 --- a/kubernetes/contrib/tools/oomstat.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env python - -# -# Copyright (c) 2018 Orange -# -# Licensed 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. -# - -""" -Provides utilities to display oom (sub)modules resources stats -""" - -import os -import sys -import getopt -from fnmatch import fnmatch as match -import yaml - -def info(thing): - if thing: - sys.stderr.write("{}\n".format(thing)) - -try: - from tabulate import tabulate -except ImportError as e: - info("Warning: cannot import tabulate module (): {}".format(str(e))) - def tabulate(lines, headers, tablefmt=None): - ''' basic tabulate function ''' - fmt = "" - nbco = len(headers) - lenco = map(len, headers) - for line in lines: - for i in range(nbco): - lenco[i] = max(lenco[i], len(str(line[i]))) - - fmt = map(lambda n: "{{:<{}}}".format(n), map(lambda i: i+2, lenco)) - fmt = " ".join(fmt) - sep = map(lambda x: '-'*(x+2), lenco) - - output = [fmt.format(*headers), fmt.format(*sep)] - for line in lines: - output.append(fmt.format(*line)) - return "\n".join(output) - - -def values(root='.'): - ''' Get the list of values.yaml files ''' - a = [] - for dirname, dirnames, filenames in os.walk(root): - for filename in filenames: - if filename == 'values.yaml': - a.append((dirname, filename)) - - if '.git' in dirnames: - # don't go into any .git directories. - dirnames.remove('.git') - return a - - -def keys(dic, prefix=None): - ''' recursively traverse the specified dict to collect existing keys ''' - result = [] - if dic: - for k, v in dic.items(): - if prefix: - k = '.'.join((prefix, k)) - if isinstance(v, dict): - result += keys(v, k) - else: - result.append(k) - return result - - -class Project: - ''' - class to access to oom (sub)module (aka project) resources - ''' - - def __init__(self, dirname, filename): - self.dirname = os.path.normpath(dirname) - self.name = self.explicit() - self.filename = os.path.join(dirname, filename) - self.resources = None - self.load() - - def load(self): - ''' load resources from yaml description ''' - with open(self.filename, 'r') as istream: - try: - v = yaml.load(istream) - if v: - self.resources = v.get('resources', None) - except Exception as e: - print(e) - raise - - def explicit(self): - ''' return an explicit name for the project ''' - path = [] - head, name = os.path.split(self.dirname) - if not name: - return head - while head: - head, tail = os.path.split(head) - if tail: - path.append(tail) - else: - path.append(head) - head = None - path.reverse() - index = path.index('charts') if 'charts' in path else None - if index: - name = os.path.join(path[index-1], name) - return name - - def __contains__(self, key): - params = self.resources - if key: - for k in key.split('.'): - if params and k in params: - params = params[k] - else: - return False - return True - - def __getitem__(self, key): - params = self.resources - for k in key.split('.'): - if k in params: - params = params[k] - if params != self.resources: - return params - - def get(self, key, default="-"): - """ mimic dict method """ - if key in self: - return self[key] - return default - - def keys(self): - """ mimic dict method """ - return keys(self.resources) - - -# -# -# - -def usage(status=None): - """ usage doc """ - arg0 = os.path.basename(os.path.abspath(sys.argv[0])) - print("""Usage: {} [options] <root-directory>""".format(arg0)) - print(( - "\n" - "Options:\n" - "-h, --help Show this help message and exit\n" - "-t, --table <format> Use the specified format to display the result table.\n" - " Valid formats are those from the python `tabulate'\n" - " module. When not available, a basic builtin tabular\n" - " function is used and this field has no effect\n" - "-f, --fields Comma separated list of resources fields to display.\n" - " You may use wildcard patterns, eg small.*. Implicit\n" - " value is *, ie all available fields will be used\n" - "Examples:\n" - " # {0} /opt/oom/kubernetes\n" - " # {0} -f small.\\* /opt/oom/kubernetes\n" - " # {0} -f '*requests.*' -t fancy_grid /opt/oom/kubernetes\n" - " # {0} -f small.requests.cpu,small.requests.memory /opt/oom/kubernetes\n" - ).format(arg0)) - if status is not None: - sys.exit(status) - - -def getopts(): - """ read options from cmdline """ - opts, args = getopt.getopt(sys.argv[1:], - "hf:t:", - ["help", "fields=", "table="]) - if len(args) != 1: - usage(1) - - root = args[0] - table = None - fields = ['*'] - patterns = [] - - for opt, arg in opts: - if opt in ("-h", '--help'): - usage(0) - elif opt in ("-f", "--fields"): - fields = arg.split(',') - elif opt in ("-t", "--table"): - table = arg - - return root, table, fields, patterns - - -def main(): - """ main """ - try: - root, table, fields, patterns = getopts() - except getopt.GetoptError as e: - print("Error: {}".format(e)) - usage(1) - - if not os.path.isdir(root): - info("Cannot open {}: Not a directory".format(root)) - return - - # find projects - projects = [] - for dirname, filename in values(root): - projects.append(Project(dirname, filename)) - if not projects: - info("No projects found in {} directory".format(root)) - return - - # check if we want to use pattern matching (wildcard only) - if fields and reduce(lambda x, y: x or y, - map(lambda string: '*' in string, fields)): - patterns = fields - fields = [] - - # if fields are not specified or patterns are used, discover available fields - # and use them (sort for readability) - if patterns or not fields: - avail = sorted(set(reduce(lambda x, y: x+y, - map(lambda p: p.keys(), projects)))) - if patterns: - for pattern in patterns: - fields += filter(lambda string: match(string, pattern), avail) - else: - fields = avail - - # collect values for each project - results = map(lambda project: [project.name] + map(project.get, - fields), - projects) - - # and then print - if results: - headers = ['project'] + fields - print(tabulate(sorted(results), headers, tablefmt=table)) - - -main() |