Package omero :: Package plugins :: Module db
[hide private]
[frames] | no frames]

Source Code for Module omero.plugins.db

  1  #!/usr/bin/env python 
  2  """ 
  3     Plugin for our managing the OMERO database. 
  4   
  5     Plugin read by omero.cli.Cli during initialization. The method(s) 
  6     defined here will be added to the Cli class for later use. 
  7   
  8     Copyright 2008 Glencoe Software, Inc. All rights reserved. 
  9     Use is subject to license terms supplied in LICENSE.txt 
 10   
 11  """ 
 12   
 13  from exceptions import Exception 
 14   
 15  from omero.cli import BaseControl 
 16  from omero.cli import CLI 
 17  from omero.cli import VERSION 
 18   
 19  from omero_ext.argparse import FileType 
 20   
 21  from path import path 
 22   
 23  import omero.java 
 24  import time 
 25   
 26  HELP="""Database tools for creating scripts, setting passwords, etc.""" 
 27   
 28   
29 -class DatabaseControl(BaseControl):
30
31 - def _configure(self, parser):
32 sub = parser.sub() 33 34 script = sub.add_parser("script", help="Generates a DB creation script") 35 script.set_defaults(func=self.script) 36 script.add_argument("-f", "--file", type=FileType(mode="w"), help="Optional file to save to. Use '-' for stdout.") 37 script.add_argument("dbversion", nargs="?") 38 script.add_argument("dbpatch", nargs="?") 39 script.add_argument("password", nargs="?") 40 41 pw = sub.add_parser("password", help="Prints SQL command for updating your root password") 42 pw.add_argument("password", nargs="?") 43 pw.set_defaults(func=self.password)
44
45 - def _lookup(self, data, data2, key, map, hidden = False):
46 """ 47 Read values from data and data2. If value is contained in data 48 then use it without question. If the value is in data2, offer 49 it as a default 50 """ 51 map[key] = data.properties.getProperty("omero.db."+key) 52 if not map[key] or map[key] == "": 53 if data2: 54 default = data2.properties.getProperty("omero.db."+key) 55 else: 56 default = "" 57 map[key] = self.ctx.input("Please enter omero.db.%s [%s]: " % (key, default), hidden) 58 if not map[key] or map[key] == "": 59 map[key] = default 60 if not map[key] or map[key] == "": 61 self.ctx.die(1, "No value entered")
62
63 - def _get_password_hash(self, root_pass = None):
64 65 root_pass = self._ask_for_password(" for OMERO root user", root_pass) 66 67 server_jar = self.ctx.dir / "lib" / "server" / "server.jar" 68 p = omero.java.popen(["-cp",str(server_jar),"ome.security.auth.PasswordUtil",root_pass]) 69 rc = p.wait() 70 if rc != 0: 71 self.ctx.die(rc, "PasswordUtil failed: %s" % p.communicate() ) 72 value = p.communicate()[0] 73 if not value or len(value) == 0: 74 self.ctx.die(100, "Encoded password is empty") 75 return value.strip()
76
77 - def _copy(self, input_path, output, func, cfg = None):
78 input = open(str(input_path)) 79 try: 80 for s in input.xreadlines(): 81 try: 82 if cfg: 83 output.write(func(s) % cfg) 84 else: 85 output.write(func(s)) 86 except Exception, e: 87 self.ctx.die(154, "Failed to map line: %s\nError: %s" % (s, e)) 88 finally: 89 input.close()
90
91 - def _make_replace(self, root_pass, db_vers, db_patch):
92 def replace_method(str_in): 93 str_out = str_in.replace("@ROOTPASS@",root_pass) 94 str_out = str_out.replace("@DBVERSION@",db_vers) 95 str_out = str_out.replace("@DBPATCH@",db_patch) 96 return str_out
97 return replace_method
98
99 - def _db_profile(self):
100 import re 101 server_lib = self.ctx.dir / "lib" / "server" 102 model_jars = server_lib.glob("model-*.jar") 103 if len(model_jars) != 1: 104 self.ctx.die(200, "Invalid model-*.jar state: %s" % ",".join(model_jars)) 105 model_jar = model_jars[0] 106 model_jar = str(model_jar.basename()) 107 match = re.search("model-(.*?).jar", model_jar) 108 return match.group(1)
109
110 - def _sql_directory(self, db_vers, db_patch):
111 """ 112 See #2689 113 """ 114 dbprofile = self._db_profile() 115 sql_directory = self.ctx.dir / "sql" / dbprofile / ("%s__%s" % (db_vers, db_patch)) 116 if not sql_directory.exists(): 117 self.ctx.die(2, "Invalid Database version/patch: %s does not exist" % sql_directory) 118 return sql_directory
119
120 - def _create(self, sql_directory, db_vers, db_patch, password_hash, args, location = None):
121 sql_directory = self._sql_directory(db_vers, db_patch) 122 if not sql_directory.exists(): 123 self.ctx.die(2, "Invalid Database version/patch: %s does not exist" % sql_directory) 124 125 if args and args.file: 126 output = args.file 127 script = "<filename here>" 128 else: 129 script = "%s__%s.sql" % (db_vers, db_patch) 130 location = path.getcwd() / script 131 output = open(location, 'w') 132 self.ctx.out("Saving to " + location) 133 134 try: 135 dbprofile = self._db_profile() 136 header = sql_directory / ("%s-header.sql" % dbprofile) 137 footer = sql_directory / ("%s-footer.sql" % dbprofile) 138 if header.exists(): 139 # 73 multiple DB support. OMERO 4.3+ 140 cfg = {"TIME":time.ctime(time.time()), 141 "DIR":sql_directory, 142 "SCRIPT":script} 143 self._copy(header, output, str, cfg) 144 self._copy(sql_directory/"schema.sql", output, str) 145 self._copy(sql_directory/"views.sql", output, str) 146 self._copy(footer, output, 147 self._make_replace(password_hash, db_vers, db_patch), cfg) 148 else: 149 # OMERO 4.2.x and before 150 output.write(""" 151 -- 152 -- GENERATED %s from %s 153 -- 154 -- This file was created by the bin/omero db script command 155 -- and contains an MD5 version of your OMERO root users's password. 156 -- You should think about deleting it as soon as possible. 157 -- 158 -- To create your database: 159 -- 160 -- createdb omero 161 -- createlang plpgsql omero 162 -- psql omero < %s 163 -- 164 165 BEGIN; 166 """ % ( time.ctime(time.time()), sql_directory, script ) ) 167 self._copy(sql_directory/"schema.sql", output, str) 168 self._copy(sql_directory/"data.sql", output, self._make_replace(password_hash, db_vers, db_patch)) 169 self._copy(sql_directory/"views.sql", output, str) 170 output.write("COMMIT;\n") 171 172 finally: 173 output.flush() 174 output.close()
175
176 - def password(self, args):
177 root_pass = None 178 try: 179 root_pass = args.password 180 except Exception, e: 181 self.ctx.dbg("While getting arguments:" + str(e)) 182 password_hash = self._get_password_hash(root_pass) 183 self.ctx.out("""UPDATE password SET hash = '%s' WHERE experimenter_id = 0;""" % password_hash)
184
185 - def script(self, args):
186 187 data = self.ctx.initData({}) 188 try: 189 data2 = self.ctx.initData({}) 190 output = self.ctx.readDefaults() 191 self.ctx.parsePropertyFile(data2, output) 192 except Exception, e: 193 self.ctx.dbg(str(e)) 194 data2 = None 195 map = {} 196 root_pass = None 197 try: 198 db_vers = args.dbversion 199 db_patch = args.dbpatch 200 if data2: 201 if len(db_vers) == 0: 202 db_vers = data2.properties.getProperty("omero.db.version") 203 if len(db_patch) == 0: 204 db_patch = data2.properties.getProperty("omero.db.patch") 205 data.properties.setProperty("omero.db.version", db_vers) 206 self.ctx.err("Using %s for version" % db_vers) 207 data.properties.setProperty("omero.db.patch", db_patch) 208 self.ctx.err("Using %s for patch" % db_patch) 209 root_pass = args.password 210 self.ctx.err("Using password from commandline") 211 except Exception, e: 212 self.ctx.dbg("While getting arguments:"+str(e)) 213 self._lookup(data, data2, "version", map) 214 self._lookup(data, data2, "patch", map) 215 sql = self._sql_directory(map["version"],map["patch"]) 216 map["pass"] = self._get_password_hash(root_pass) 217 self._create(sql, map["version"], map["patch"], map["pass"], args)
218 219 try: 220 register("db", DatabaseControl, HELP) 221 except NameError: 222 import sys 223 cli = CLI() 224 cli.register("db", DatabaseControl, HELP) 225 cli.invoke(sys.argv[1:]) 226