]> scripts.mit.edu Git - wizard.git/blob - wizard/scripts.py
Check for vos in /usr/sbin; also fix docs.
[wizard.git] / wizard / scripts.py
1 import os
2 import shlex
3 import errno
4 import logging
5
6 import wizard
7 from wizard import shell, util
8
9 def get_web_host_and_path(dir=None):
10     """
11     Attempts to determine webhost and path for the current directory
12     as it would be accessible from the web.  Works only for scripts
13     servers.  Returns a tuple web_host, web_path, or None if it failed.
14     """
15     # XXX: THIS CODE SUCKS
16     host = os.getenv("WIZARD_WEB_HOST")
17     path = os.getenv("WIZARD_WEB_PATH")
18     if host is not None and path is not None:
19         return (host, path.rstrip('/'))
20     if not dir:
21         dir = os.getcwd()
22     # XXX: possible security risk?
23     homedir, _, web_path = dir.partition("/web_scripts")
24     if not web_path:
25         return None
26     return (util.get_dir_owner(homedir) + ".scripts.mit.edu", web_path.rstrip('/'))
27
28 def get_quota_usage_and_limit(dir=None):
29     """
30     Returns a tuple (quota usage, quota limit).  Works only for scripts
31     servers.  Values are in KiB.  Returns ``(0, None)`` if we couldn't figure it out.
32     """
33     # XXX: The correct way is to implement Python modules implementing
34     # bindings for all the appropriate interfaces
35     def parse_last_quote(ret):
36         return ret.rstrip('\'').rpartition('\'')[2]
37     if dir is None:
38         dir = os.getcwd()
39     sh = shell.Shell()
40     try:
41         cell = parse_last_quote(sh.eval("fs", "whichcell", "-path", dir))
42     except shell.CallError:
43         return (0, None)
44     except OSError as e:
45         if e.errno == errno.ENOENT:
46             return (0, None)
47         raise
48     mount = None
49     while dir:
50         try:
51             volume = parse_last_quote(sh.eval("fs", "lsmount", dir))[1:]
52             break
53         except shell.CallError:
54             dir = os.path.dirname(dir)
55         except OSError as e:
56             if e.errno == errno.ENOENT:
57                 return (0, None)
58             raise
59     if not volume: return (0, None)
60     try:
61         result = sh.eval("vos", "examine", "-id", volume, "-cell", cell).splitlines()
62     except OSError:
63         try:
64             result = sh.eval("/usr/sbin/vos", "examine", "-id", volume, "-cell", cell).splitlines()
65         except OSError:
66             return (0, None)
67     except shell.CallError:
68         return (0, None)
69     try:
70         usage = int(result[0].split()[3])
71         limit = int(result[3].split()[1]) # XXX: FRAGILE
72     except ValueError:
73         raise QuotaParseError("vos examine output was:\n\n" + "\n".join(result))
74     return (usage, limit)
75
76 # XXX: Possibly in the wrong module
77 def get_disk_usage(dir=None, excluded_dir=".git"):
78     """
79     Recursively determines the disk usage of a directory, excluding
80     .git directories.  Value is in bytes.
81     """
82     if dir is None: dir = os.getcwd()
83     sum_sizes = 0
84     for root, _, files in os.walk(dir):
85         for name in files:
86             if not os.path.join(root, name).startswith(dir + excluded_dir):
87                 sum_sizes += os.path.getsize(os.path.join(root, name))
88     return sum_sizes
89 class QuotaParseError(wizard.Error):
90     def __init__(self, msg):
91         self.msg = msg
92     def __str__(self):
93         return """
94
95 ERROR: Could not parse quota. %s
96 """ % self.msg