1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 Plugin for our managing the OMERO database.
24
25 Plugin read by omero.cli.Cli during initialization. The method(s)
26 defined here will be added to the Cli class for later use.
27 """
28
29 from omero.cli import BaseControl
30 from omero.cli import CLI
31
32 from omero_ext.argparse import FileType
33
34 from path import path
35
36 import omero.java
37 import time
38 import sys
39
40 HELP = """Database tools for creating scripts, setting passwords, etc."""
41
42
44
72
73 - def _lookup(self, data, data2, key, map, hidden=False):
91
93 return args and "user_id" in args and args.user_id is not None
94
96
97 prompt = " for OMERO "
98 if self._has_user_id(args) and not old_prompt:
99 prompt += "user %s" % args.user_id
100 else:
101 prompt += "root user"
102 root_pass = self._ask_for_password(prompt, root_pass)
103
104 server_jar = self.ctx.dir / "lib" / "server" / "server.jar"
105 cmd = ["ome.security.auth.PasswordUtil", root_pass]
106 if not args.no_salt and self._has_user_id(args):
107 cmd.append(args.user_id)
108 p = omero.java.popen(["-cp", str(server_jar)] + cmd)
109 rc = p.wait()
110 if rc != 0:
111 out, err = p.communicate()
112 self.ctx.die(rc, "PasswordUtil failed: %s" % err)
113 value = p.communicate()[0]
114 if not value or len(value) == 0:
115 self.ctx.die(100, "Encoded password is empty")
116 return value.strip()
117
118 - def _copy(self, input_path, output, func, cfg=None):
119 input = open(str(input_path))
120 try:
121 for s in input.xreadlines():
122 try:
123 if cfg:
124 output.write(func(s) % cfg)
125 else:
126 output.write(func(s))
127 except Exception, e:
128 self.ctx.die(
129 154, "Failed to map line: %s\nError: %s"
130 % (s, e))
131 finally:
132 input.close()
133
135 def replace_method(str_in):
136 str_out = str_in.replace("@ROOTPASS@", root_pass)
137 str_out = str_out.replace("@DBVERSION@", db_vers)
138 str_out = str_out.replace("@DBPATCH@", db_patch)
139 return str_out
140 return replace_method
141
143 import re
144 server_lib = self.ctx.dir / "lib" / "server"
145 model_jars = server_lib.glob("model-*.jar")
146 if len(model_jars) != 1:
147 self.ctx.die(200, "Invalid model-*.jar state: %s"
148 % ",".join(model_jars))
149 model_jar = model_jars[0]
150 model_jar = str(model_jar.basename())
151 match = re.search("model-(.*?).jar", model_jar)
152 return match.group(1)
153
155 """
156 See #2689
157 """
158 dbprofile = self._db_profile()
159 sql_directory = self.ctx.dir / "sql" / dbprofile / \
160 ("%s__%s" % (db_vers, db_patch))
161 if not sql_directory.exists():
162 self.ctx.die(2, "Invalid Database version/patch: %s does not"
163 " exist" % sql_directory)
164 return sql_directory
165
166 - def _create(self, sql_directory, db_vers, db_patch, password_hash, args,
167 location=None):
168 sql_directory = self._sql_directory(db_vers, db_patch)
169 if not sql_directory.exists():
170 self.ctx.die(2, "Invalid Database version/patch: %s does not"
171 " exist" % sql_directory)
172
173 if args and args.file:
174 output = args.file
175 script = "<filename here>"
176 else:
177 script = "%s__%s.sql" % (db_vers, db_patch)
178 location = path.getcwd() / script
179 output = open(location, 'w')
180 self.ctx.out("Saving to " + location)
181
182 try:
183 dbprofile = self._db_profile()
184 header = sql_directory / ("%s-header.sql" % dbprofile)
185 footer = sql_directory / ("%s-footer.sql" % dbprofile)
186 if header.exists():
187
188 cfg = {
189 "TIME": time.ctime(time.time()),
190 "DIR": sql_directory,
191 "SCRIPT": script}
192 self._copy(header, output, str, cfg)
193 self._copy(sql_directory/"schema.sql", output, str)
194 self._copy(sql_directory/"views.sql", output, str)
195 self._copy(
196 footer, output,
197 self._make_replace(password_hash, db_vers, db_patch), cfg)
198 else:
199
200 output.write("""
201 --
202 -- GENERATED %s from %s
203 --
204 -- This file was created by the bin/omero db script command
205 -- and contains an MD5 version of your OMERO root users's password.
206 -- You should think about deleting it as soon as possible.
207 --
208 -- To create your database:
209 --
210 -- createdb omero
211 -- createlang plpgsql omero
212 -- psql omero < %s
213 --
214
215 BEGIN;
216 """ % (time.ctime(time.time()), sql_directory, script))
217 self._copy(sql_directory/"schema.sql", output, str)
218 self._copy(
219 sql_directory/"data.sql", output,
220 self._make_replace(password_hash, db_vers, db_patch))
221 self._copy(sql_directory/"views.sql", output, str)
222 output.write("COMMIT;\n")
223
224 finally:
225 output.flush()
226 if output != sys.stdout:
227 output.close()
228
230 root_pass = None
231 user_id = 0
232 old_prompt = True
233 if self._has_user_id(args):
234 user_id = args.user_id
235 if user_id != '0':
236 old_prompt = False
237 try:
238 root_pass = args.password
239 except Exception, e:
240 self.ctx.dbg("While getting arguments:" + str(e))
241 password_hash = self._get_password_hash(args, root_pass, old_prompt)
242 self.ctx.out("UPDATE password SET hash = '%s' "
243 "WHERE experimenter_id = %s;""" %
244 (password_hash, user_id))
245
247 try:
248 data2 = self.ctx.initData({})
249 output = self.ctx.readDefaults()
250 self.ctx.parsePropertyFile(data2, output)
251 except Exception, e:
252 self.ctx.dbg(str(e))
253 data2 = None
254 return data2
255
257
258 data = self.ctx.initData({})
259 data2 = self.loaddefaults()
260 map = {}
261 root_pass = None
262 try:
263 db_vers = args.dbversion
264 db_patch = args.dbpatch
265 if data2:
266 if len(db_vers) == 0:
267 db_vers = data2.properties.getProperty("omero.db.version")
268 if len(db_patch) == 0:
269 db_patch = data2.properties.getProperty("omero.db.patch")
270 data.properties.setProperty("omero.db.version", db_vers)
271 self.ctx.err("Using %s for version" % db_vers)
272 data.properties.setProperty("omero.db.patch", db_patch)
273 self.ctx.err("Using %s for patch" % db_patch)
274 root_pass = args.password
275 self.ctx.err("Using password from commandline")
276 except Exception, e:
277 self.ctx.dbg("While getting arguments:"+str(e))
278 self._lookup(data, data2, "version", map)
279 self._lookup(data, data2, "patch", map)
280 args.user_id = "0"
281 sql = self._sql_directory(map["version"], map["patch"])
282 map["pass"] = self._get_password_hash(args, root_pass, True)
283 self._create(sql, map["version"], map["patch"], map["pass"], args)
284
285 try:
286 register("db", DatabaseControl, HELP)
287 except NameError:
288 if __name__ == "__main__":
289 cli = CLI()
290 cli.register("db", DatabaseControl, HELP)
291 cli.invoke(sys.argv[1:])
292