]> scripts.mit.edu Git - wizard.git/blob - plugins/scripts/wizard_scripts.py
4a9a0841457337d434f92911a97b204bdbb63cbf
[wizard.git] / plugins / scripts / wizard_scripts.py
1 """
2 This is ostensibly the place where Scripts specific code should live.
3 """
4
5 import os
6 import shlex
7 import errno
8 import logging
9 import urlparse
10 import time
11 import errno
12
13 import wizard
14 from wizard import shell, util
15
16 def deploy_web(dir):
17     # try the directory
18     homedir, _, web_path = dir.partition("/web_scripts")
19     if web_path:
20         yield urlparse.ParseResult(
21                 "http",
22                 util.get_dir_owner(homedir) + ".scripts.mit.edu",
23                 web_path.rstrip('/'),
24                 "", "", "")
25         yield urlparse.ParseResult(
26                 "http",
27                 "scripts.mit.edu",
28                 "/~" + util.get_dir_owner(homedir) + web_path.rstrip('/'),
29                 "", "", "")
30     else:
31         logging.info("Directory location did not contain web_scripts: %s", dir)
32
33 def user_quota(dir=None):
34     """
35     Returns a tuple (quota usage, quota limit).  Works only for scripts
36     servers.  Values are in KiB.  Returns ``(0, None)`` if we couldn't figure it out.
37     """
38     end = 2
39     # sometimes the volume is busy; so we try several times
40     for i in range(0, end + 1):
41         try:
42             return _user_quota(dir)
43         except QuotaParseError as e:
44             if i == end:
45                 raise e
46             time.sleep(3) # give it a chance to unbusy
47     assert False # should not get here
48
49 def _user_quota(dir=None):
50     # XXX: The correct way is to implement Python modules implementing
51     # bindings for all the appropriate interfaces
52     unknown = (0, None)
53     def parse_last_quote(ret):
54         return ret.rstrip('\'').rpartition('\'')[2]
55     if dir is None:
56         dir = os.getcwd()
57     sh = shell.Shell()
58     try:
59         cell = parse_last_quote(sh.eval("fs", "whichcell", "-path", dir))
60     except shell.CallError:
61         return unknown
62     except OSError as e:
63         if e.errno == errno.ENOENT:
64             return unknown
65         raise
66     mount = None
67     while dir:
68         try:
69             volume = parse_last_quote(sh.eval("fs", "lsmount", dir))[1:]
70             break
71         except shell.CallError:
72             dir = os.path.dirname(dir)
73         except OSError as e:
74             if e.errno == errno.ENOENT:
75                 return unknown
76             raise
77     if not volume: return unknown
78     try:
79         result = sh.eval("vos", "examine", "-id", volume, "-cell", cell).splitlines()
80     except OSError:
81         try:
82             result = sh.eval("/usr/sbin/vos", "examine", "-id", volume, "-cell", cell).splitlines()
83         except OSError:
84             return unknown
85     except shell.CallError:
86         return unknown
87     try:
88         usage = int(result[0].split()[3])
89         limit = int(result[3].split()[1]) # XXX: FRAGILE
90     except ValueError:
91         raise QuotaParseError("vos examine output was:\n\n" + "\n".join(result))
92     return (usage, limit)
93
94 class QuotaParseError(wizard.Error):
95     """Could not parse quota information."""
96     def __init__(self, msg):
97         self.msg = msg
98     def __str__(self):
99         return """
100
101 ERROR: Could not parse quota. %s
102 """ % self.msg
103
104 def sql_auth(url):
105     if url.driver == "mysql":
106         try:
107             url.host, url.username, url.password = shell.Shell().eval("/mit/scripts/sql/bin/get-password").split()
108             return url
109         except shell.CallError:
110             pass
111     return None