From 97fcc7b27b9972dd43f9466f1b662ed6e8f58417 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Mon, 16 Jun 2014 17:24:14 -0400 Subject: [PATCH] add worlddump tool to devstack when we exit poorly, start building a tool for doing a capture as to why. This tool is expected to be consumed directly from grenade as well. Change-Id: Ia1bc1c2e259587035ca7252baceec25fa464cb82 --- stack.sh | 5 +++ tools/worlddump.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100755 tools/worlddump.py diff --git a/stack.sh b/stack.sh index d2f18d48c1..5e2daf6ef4 100755 --- a/stack.sh +++ b/stack.sh @@ -622,6 +622,11 @@ function exit_trap { # Kill the last spinner process kill_spinner + if [[ $r -ne 0 ]]; then + echo "Error on exit" + ./tools/worlddump.py -d $LOGDIR + fi + exit $r } diff --git a/tools/worlddump.py b/tools/worlddump.py new file mode 100755 index 0000000000..9a62c0dfbb --- /dev/null +++ b/tools/worlddump.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# +# Copyright 2014 Hewlett-Packard Development Company, L.P. +# +# 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. + +"""Dump the state of the world for post mortem.""" + +import argparse +import datetime +import os +import os.path +import sys + + +def get_options(): + parser = argparse.ArgumentParser( + description='Dump world state for debugging') + parser.add_argument('-d', '--dir', + default='.', + help='Output directory for worlddump') + return parser.parse_args() + + +def filename(dirname): + now = datetime.datetime.utcnow() + return os.path.join(dirname, now.strftime("worlddump-%Y-%m-%d-%H%M%S.txt")) + + +def warn(msg): + print "WARN: %s" % msg + + +def disk_space(): + # the df output + print """ +File System Summary +=================== +""" + dfraw = os.popen("df -Ph").read() + df = [s.split() for s in dfraw.splitlines()] + for fs in df: + try: + if int(fs[4][:-1]) > 95: + warn("Device %s (%s) is %s full, might be an issue" % ( + fs[0], fs[5], fs[4])) + except ValueError: + # if it doesn't look like an int, that's fine + pass + + print dfraw + + +def process_list(): + print """ +Process Listing +=============== +""" + psraw = os.popen("ps auxw").read() + print psraw + + +def main(): + opts = get_options() + fname = filename(opts.dir) + print "World dumping... see %s for details" % fname + sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) + with open(fname, 'w') as f: + os.dup2(f.fileno(), sys.stdout.fileno()) + disk_space() + process_list() + + +if __name__ == '__main__': + try: + sys.exit(main()) + except KeyboardInterrupt: + sys.exit(1)