1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
"""
sysinfo.py [host1] [host2] [options]
obtain system info from remote machine.
(c) Holger Krekel, MIT license
"""
import optparse
import re
import sys
import execnet
parser = optparse.OptionParser(usage=__doc__)
parser.add_option(
"-f",
"--sshconfig",
action="store",
dest="ssh_config",
default=None,
help="use given ssh config file,"
" and add info all contained hosts for getting info",
)
parser.add_option(
"-i",
"--ignore",
action="store",
dest="ignores",
default=None,
help="ignore hosts " "(useful if the list of hostnames come from a file list)",
)
def parsehosts(path):
host_regex = re.compile(r"Host\s*(\S+)")
l = []
with open(path) as fp:
for line in fp:
m = host_regex.match(line)
if m is not None:
(sshname,) = m.groups()
l.append(sshname)
return l
class RemoteInfo:
def __init__(self, gateway):
self.gw = gateway
self._cache = {}
def exreceive(self, execstring):
if execstring not in self._cache:
channel = self.gw.remote_exec(execstring)
self._cache[execstring] = channel.receive()
return self._cache[execstring]
def getmodattr(self, modpath):
module = modpath.split(".")[0]
return self.exreceive(
"""
import %s
channel.send(%s)
"""
% (module, modpath)
)
def islinux(self):
return self.getmodattr("sys.platform").find("linux") != -1
def getfqdn(self):
return self.exreceive(
"""
import socket
channel.send(socket.getfqdn())
"""
)
def getmemswap(self):
if self.islinux():
return self.exreceive(
r"""
import commands, re
out = commands.getoutput("free")
mem = re.search(r"Mem:\s+(\S*)", out).group(1)
swap = re.search(r"Swap:\s+(\S*)", out).group(1)
channel.send((mem, swap))
"""
)
def getcpuinfo(self):
if self.islinux():
return self.exreceive(
"""
# a hyperthreaded cpu core only counts as 1, although it
# is present as 2 in /proc/cpuinfo. Counting it as 2 is
# misleading because it is *by far* not as efficient as
# two independent cores.
cpus = {}
cpuinfo = {}
f = open("/proc/cpuinfo")
lines = f.readlines()
f.close()
for line in lines + ['']:
if line.strip():
key, value = line.split(":", 1)
cpuinfo[key.strip()] = value.strip()
else:
corekey = (cpuinfo.get("physical id"),
cpuinfo.get("core id"))
cpus[corekey] = 1
numcpus = len(cpus)
model = cpuinfo.get("model name")
channel.send((numcpus, model))
"""
)
def debug(*args):
print(" ".join(map(str, args)), file=sys.stderr)
def error(*args):
debug("ERROR", args[0] + ":", *args[1:])
def getinfo(sshname, ssh_config=None, loginfo=sys.stdout):
if ssh_config:
spec = f"ssh=-F {ssh_config} {sshname}"
else:
spec = "ssh=%s" % sshname
debug("connecting to", repr(spec))
try:
gw = execnet.makegateway(spec)
except OSError:
error("could not get sshgatway", sshname)
else:
ri = RemoteInfo(gw)
# print "%s info:" % sshname
prefix = sshname.upper() + " "
print(prefix, "fqdn:", ri.getfqdn(), file=loginfo)
for attr in ("sys.platform", "sys.version_info"):
loginfo.write(f"{prefix} {attr}: ")
loginfo.flush()
value = ri.getmodattr(attr)
loginfo.write(str(value))
loginfo.write("\n")
loginfo.flush()
memswap = ri.getmemswap()
if memswap:
mem, swap = memswap
print(prefix, "Memory:", mem, "Swap:", swap, file=loginfo)
cpuinfo = ri.getcpuinfo()
if cpuinfo:
numcpu, model = cpuinfo
print(prefix, "number of cpus:", numcpu, file=loginfo)
print(prefix, "cpu model", model, file=loginfo)
return ri
if __name__ == "__main__":
options, args = parser.parse_args()
hosts = list(args)
ssh_config = options.ssh_config
if ssh_config:
hosts.extend(parsehosts(ssh_config))
ignores = options.ignores or ()
if ignores:
ignores = ignores.split(",")
for host in hosts:
if host not in ignores:
getinfo(host, ssh_config=ssh_config)
|