]> scripts.mit.edu Git - wizard.git/blob - plugins/scripts/wizard_scripts.py
Add wizard.sql.auth function and plugin, refresh docs.
[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
31 def user_quota(dir=None):
32     """
33     Returns a tuple (quota usage, quota limit).  Works only for scripts
34     servers.  Values are in KiB.  Returns ``(0, None)`` if we couldn't figure it out.
35     """
36     end = 2
37     # sometimes the volume is busy; so we try several times
38     for i in range(0, end + 1):
39         try:
40             return _user_quota(dir)
41         except QuotaParseError as e:
42             if i == end:
43                 raise e
44             time.sleep(3) # give it a chance to unbusy
45     assert False # should not get here
46
47 def _user_quota(dir=None):
48     # XXX: The correct way is to implement Python modules implementing
49     # bindings for all the appropriate interfaces
50     unknown = (0, None)
51     def parse_last_quote(ret):
52         return ret.rstrip('\'').rpartition('\'')[2]
53     if dir is None:
54         dir = os.getcwd()
55     sh = shell.Shell()
56     try:
57         cell = parse_last_quote(sh.eval("fs", "whichcell", "-path", dir))
58     except shell.CallError:
59         return unknown
60     except OSError as e:
61         if e.errno == errno.ENOENT:
62             return unknown
63         raise
64     mount = None
65     while dir:
66         try:
67             volume = parse_last_quote(sh.eval("fs", "lsmount", dir))[1:]
68             break
69         except shell.CallError:
70             dir = os.path.dirname(dir)
71         except OSError as e:
72             if e.errno == errno.ENOENT:
73                 return unknown
74             raise
75     if not volume: return unknown
76     try:
77         result = sh.eval("vos", "examine", "-id", volume, "-cell", cell).splitlines()
78     except OSError:
79         try:
80             result = sh.eval("/usr/sbin/vos", "examine", "-id", volume, "-cell", cell).splitlines()
81         except OSError:
82             return unknown
83     except shell.CallError:
84         return unknown
85     try:
86         usage = int(result[0].split()[3])
87         limit = int(result[3].split()[1]) # XXX: FRAGILE
88     except ValueError:
89         raise QuotaParseError("vos examine output was:\n\n" + "\n".join(result))
90     return (usage, limit)
91
92 class QuotaParseError(wizard.Error):
93     """Could not parse quota information."""
94     def __init__(self, msg):
95         self.msg = msg
96     def __str__(self):
97         return """
98
99 ERROR: Could not parse quota. %s
100 """ % self.msg
101
102 def sql_auth(url):
103     if url.driver == "mysql":
104         try:
105             url.host, url.username, url.password = shell.Shell().eval("/mit/scripts/sql/bin/get-password").split()
106             return url
107         except shell.CallError:
108             pass
109     return None