Last active
September 29, 2015 22:04
-
-
Save jpeyret/a34792e6bf142b90c0ea to your computer and use it in GitHub Desktop.
small Python script to diagnose vagrant chef installations. plop in some things you want to check for and it'll export them in directory /vagrant/diag.out, as seen from the guest.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import subprocess | |
import shutil | |
import pdb | |
import pprint | |
from subprocess import Popen, PIPE | |
from shlex import split | |
dn_out = "/vagrant/diag.out" | |
dn_conf = "/vagrant/diag.conf" | |
try: | |
os.makedirs(dn_out) | |
except OSError: | |
pass | |
pp = pprint.PrettyPrinter(indent=4) | |
class module_settings(object): | |
USE_PDB = True | |
def debug(o, msg=""): | |
print(msg) | |
pp.pprint(o) | |
def do_tree(dn_in): | |
try: | |
li = dn_in.split() | |
dn = li[0] | |
flag = " ".join(li[1:]) | |
except Exception, e: | |
if module_settings.USE_PDB: pdb.set_trace() | |
raise | |
s_out = dn.strip("/").replace("/",".") | |
if s_out: | |
s_out = ".%s" % (s_out) | |
fn_o = "tree%s.txt" % (s_out) | |
# debug(locals(),"do_tree") | |
# return | |
if not os.path.isdir(dn): | |
fn_o = "missing.%s" % (fn_o) | |
fnp_o = os.path.join(dn_out, fn_o) | |
with open(fnp_o, "w") as fo: | |
pass | |
return | |
fnp_o = os.path.join(dn_out, fn_o) | |
cmd = "tree %s %s" % (dn, flag) | |
try: | |
exitcode = subprocess.call(cmd.split(), | |
shell=False, | |
# executable="/bin/bash", | |
stdout=open(fnp_o, 'w'), | |
) | |
except OSError, e: | |
try: | |
exitcode = subprocess.call("tree") | |
except OSError, e2: | |
#ok, tree doesnt seem installed. | |
os.remove(fnp_o) | |
fnp_o = os.path.join(dn_out, "not_installed.tree.txt") | |
with open(fnp_o, "w") as fo: | |
fo.write("has the tree utility been installed?") | |
def do_copy(): | |
fnp_i = os.path.join(dn_conf, "copy.txt") | |
dn_o = os.path.join(dn_out, "copy") | |
try: | |
os.makedirs(dn_o) | |
except OSError: | |
pass | |
# except Exception, e: | |
# if module_settings.USE_PDB: pdb.set_trace() | |
# raise | |
with open(fnp_i) as fi: | |
for line in fi.readlines(): | |
fnp_i = line.split("#")[0].strip() | |
if not fnp_i: | |
continue | |
dn, fn = os.path.split(fnp_i) | |
# print "locals:" | |
fn_prefix = dn[1:].replace("/",".") | |
fn_o = "%s.%s" % (fn_prefix, fn) | |
fnp_o = os.path.join(dn_o, fn_o) | |
# debug(locals(), "locals:") | |
try: | |
shutil.copyfile(fnp_i, fnp_o) | |
except IOError: | |
fnp_o = os.path.join(dn_o, "missing.%s" % fn_o) | |
# debug(fnp_o) | |
with open(fnp_o, "w") as dummy: | |
pass | |
# break | |
def fmt_line(line): | |
line = line.split("#")[0].strip() | |
return line | |
def get_commands(fnp_i): | |
li_res = [] | |
with open(fnp_i) as fi: | |
for line in fi.readlines(): | |
line = fmt_line(line) | |
if line: | |
li_res.append(line) | |
return li_res | |
def do_ls_1(dn): | |
dn_n = "dir.%s.txt" % dn.strip("/").replace("/", ".") | |
if not os.path.isdir(dn): | |
fnp_o = os.path.join(dn_out, "missing.%s" % dn_n) | |
with open(fnp_o, "w") as fo: | |
pass | |
return | |
fnp_o = os.path.join(dn_out, dn_n) | |
cmd = "ls -lan %s" % (dn) | |
proc = subprocess.Popen( | |
cmd.split(), | |
shell=False, | |
stdout=subprocess.PIPE | |
) | |
with open(fnp_o, "w") as fo: | |
while True: | |
line = proc.stdout.readline() | |
if line != '': | |
#the real code does filtering here | |
# print "test:", line.rstrip() | |
li_field = line.split() | |
perm, fn = li_field[0], li_field[-1] | |
line_o = "\n%s %s" % (perm, fn) | |
# debug(locals(),"do_ls_1.locals") | |
# debug(li_field, "li_field") | |
fo.write(line_o) | |
else: | |
break | |
def do_listdir(): | |
fnp_i = os.path.join(dn_conf, "listdir.txt") | |
with open(fnp_i) as fi: | |
for line in fi.readlines(): | |
dn_watch = line.split("#")[0].strip() | |
if not dn_watch: | |
continue | |
do_ls_1(dn_watch) | |
def do_trees(): | |
fnp_i = os.path.join(dn_conf, "tree.txt") | |
li_tree = get_commands(fnp_i) | |
for dn_tree in li_tree: | |
do_tree(dn_tree) | |
def do_find_proc(): | |
fnp_i = os.path.join(dn_conf, "proc.txt") | |
li = get_commands(fnp_i) | |
for i in li: | |
find_proc(i) | |
def find_proc(procname, comment=""): | |
#ps -ef | grep "[r]unsvdir" | |
fn = "proc.%s.txt" % (procname) | |
# fnp_o = os.path.join(dn_out, fn_o) | |
cmd = "pgrep -lf %s " % (procname) | |
proc = subprocess.Popen( | |
cmd.split(), | |
shell=False, | |
# executable="/bin/bash", | |
stdout=subprocess.PIPE, | |
) | |
li = [] | |
while True: | |
line = proc.stdout.readline() | |
if line != '': | |
li.append(line) | |
else: | |
break | |
if not li: | |
fn = "missing.%s" % (fn) | |
fnp_o = os.path.join(dn_out, fn) | |
with open(fnp_o, "w") as fo: | |
[fo.write("\n%s" % line) for line in li] | |
def do_command(cmd, comment=""): | |
s_cmd = cmd.strip().replace(" ", ".").replace("/",".") | |
fn = "command.%s.txt" % (s_cmd) | |
fnp_o = os.path.join(dn_out, fn) | |
try: | |
proc = subprocess.Popen( | |
cmd.split(), | |
shell=False, | |
# executable="/bin/bash", | |
stdout=open(fnp_o, "w"), | |
) | |
except OSError, e: | |
os.remove(fnp_o) | |
fnp_o = os.path.join(dn_out, "error:%s" % fn) | |
with open(fnp_o, "w") as fo: | |
fo.write(e) | |
def do_commands(): | |
fnp_i = os.path.join(dn_conf, "command.txt") | |
li = get_commands(fnp_i) | |
for i in li: | |
do_command(i) | |
def main(): | |
do_trees() | |
# return | |
do_listdir() | |
do_copy() | |
do_find_proc() | |
do_commands() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the general idea of how to use it:
configuration in diag.conf:
diag.conf
├── command.txt
├── copy.txt
├── listdir.txt
├── proc.txt
└── tree.txt
0 directories, 5 files
diag.conf/command:
run these commands and save their ouput
redis-cli ping
diag.conf/listdir.txt:
list the contents of directories
/var/run
/sbin
/usr/local/bin
/etc/service
/etc/runit
/etc/supervisor.d/
diag.conf/proc.txt:
list running processes using pgrep
runsvdir
foobar #this one will be missing
diag.conf/tree.txt:
run the tree command, if available and save the output
/ -I proc
/srv/bemyerp/current
diag.conf/copy.txt:
copy the contents of these files out.
/etc/redis/redis.conf
/etc/redis/dummy.will_be_missing
/etc/supervisord.conf
sample usage:
(but of course the point is to be able to inspect things at leisure
on your dev machine.
)
vagrant@vagrant:
$ rm -rf /vagrant/diag.out && /vagrant/diag.py$ tree /vagrant/diag.outvagrant@vagrant:
/vagrant/diag.out
├── command.redis-cli.ping.txt
├── dir.etc.service.txt
├── dir.sbin.txt
├── dir.usr.local.bin.txt
├── dir.var.run.txt
├── copy
│ ├── etc.redis.redis.conf
│ ├── missing.etc.redis.dummy.will_be_missing
│ └── missing.etc.supervisord.conf
├── missing.dir.etc.runit.txt
├── missing.dir.etc.supervisor.d.txt
├── missing.proc.foobar.txt
├── missing.tree.srv.bemyerp.current.txt
├── proc.runsvdir.txt
└── tree.txt
1 directory, 14 files