Useful directory argument to environ.homepath
[nepi.git] / src / nepi / util / environ.py
1 # vim:ts=4:sw=4:et:ai:sts=4
2
3 import os, subprocess, os.path
4
5 __all__ =  ["python", "ssh_path"]
6 __all__ += ["rsh", "tcpdump_path", "sshd_path"]
7 __all__ += ["execute", "backticks"]
8
9 def find_bin(name, extra_path = None):
10     search = []
11     if "PATH" in os.environ:
12         search += os.environ["PATH"].split(":")
13     for pref in ("/", "/usr/", "/usr/local/"):
14         for d in ("bin", "sbin"):
15             search.append(pref + d)
16     if extra_path:
17         search += extra_path
18
19     for d in search:
20             try:
21                 os.stat(d + "/" + name)
22                 return d + "/" + name
23             except OSError, e:
24                 if e.errno != os.errno.ENOENT:
25                     raise
26     return None
27
28 def find_bin_or_die(name, extra_path = None):
29     r = find_bin(name)
30     if not r:
31         raise RuntimeError(("Cannot find `%s' command, impossible to " +
32                 "continue.") % name)
33     return r
34
35 ssh_path = find_bin_or_die("ssh")
36 python_path = find_bin_or_die("python")
37
38 # Optional tools
39 rsh_path = find_bin("rsh")
40 tcpdump_path = find_bin("tcpdump")
41 sshd_path = find_bin("sshd")
42
43 def execute(cmd):
44     # FIXME: create a global debug variable
45     #print "[pid %d]" % os.getpid(), " ".join(cmd)
46     null = open("/dev/null", "r+")
47     p = subprocess.Popen(cmd, stdout = null, stderr = subprocess.PIPE)
48     out, err = p.communicate()
49     if p.returncode != 0:
50         raise RuntimeError("Error executing `%s': %s" % (" ".join(cmd), err))
51
52 def backticks(cmd):
53     p = subprocess.Popen(cmd, stdout = subprocess.PIPE,
54             stderr = subprocess.PIPE)
55     out, err = p.communicate()
56     if p.returncode != 0:
57         raise RuntimeError("Error executing `%s': %s" % (" ".join(cmd), err))
58     return out
59
60 def homepath(path, app='.nepi', mode = 0500, directory = False):
61     home = os.environ.get('HOME')
62     if home is None:
63         home = os.path.join(os.sep, 'home', os.getlogin())
64     
65     path = os.path.join(home, app, path)
66     if directory:
67         dirname = path
68     else:
69         dirname = os.path.dirname(path)
70     if not os.path.exists(dirname):
71         os.makedirs(dirname)
72     
73     return path
74
75 def find_testbed(testbed_id):
76     mod_name = None
77     
78     # look for environment-specified testbeds
79     if 'NEPI_TESTBEDS' in os.environ:
80         try:
81             # parse testbed map
82             #   split space-separated items, filter empty items
83             testbed_map = filter(bool,os.environ['NEPI_TESTBEDS'].strip().split(' '))
84             #   split items, keep pairs only, build map
85             testbed_map = dict([map(str.strip,i.split(':',1)) for i in testbed_map if ':' in i])
86         except:
87             import traceback, sys
88             traceback.print_exc(file=sys.stderr)
89             
90             # ignore malformed environment
91             testbed_map = {}
92         
93         mod_name = testbed_map.get(testbed_id)
94     
95     if mod_name is None:
96         # no explicit map, load built-in testbeds
97         mod_name = "nepi.testbeds.%s" % (testbed_id.lower())
98
99     return mod_name
100