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

Source Code for Module omero.plugins.prefs

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  """ 
  4     prefs plugin 
  5   
  6     Plugin read by omero.cli.Cli during initialization. The method(s) 
  7     defined here will be added to the Cli class for later use. 
  8   
  9     The pref plugin makes use of prefs.class from the common component. 
 10   
 11     Copyright 2007 Glencoe Software, Inc. All rights reserved. 
 12     Use is subject to license terms supplied in LICENSE.txt 
 13   
 14  """ 
 15   
 16  import sys 
 17  import portalocker 
 18   
 19  from path import path 
 20  from omero.cli import CLI 
 21  from omero.cli import BaseControl 
 22  from omero.cli import ExistingFile 
 23  from omero.cli import NonZeroReturnCode 
 24  from omero.config import ConfigXml 
 25  from omero.util import edit_path, get_user_dir 
 26  from omero.util.decorators import wraps 
 27  import omero.java 
 28   
 29  HELP = """Commands for server configuration 
 30   
 31  A config.xml file will be modified under your etc/grid directory. If you do 
 32  not have one, "upgrade" will create a new 4.2 configuration file. 
 33   
 34  The configuration values are used by bin/omero admin {start,deploy} to set 
 35  properties on launch. See etc/grid/(win)default.xml. The "Profile" block 
 36  contains a reference to "__ACTIVE__" which is the current value in config.xml 
 37   
 38  Environment variables: 
 39      OMERO_CONFIG - Changes the active profile 
 40   
 41  """ 
42 43 44 -def getprefs(args, dir):
45 """ 46 Kept around temporarily for upgrading users from pre-4.2 configurations. 47 """ 48 if not isinstance(args, list): 49 raise Exception("Not a list") 50 cmd = ["prefs"]+list(args) 51 return omero.java.run(cmd, chdir=dir)
52
53 54 -def _make_open_and_close_config(func, allow_readonly):
55 def open_and_close_config(*args, **kwargs): 56 args = list(args) 57 self = args[0] 58 argp = args[1] 59 config = None 60 if len(args) == 2: 61 config = self.open_config(argp) 62 if not allow_readonly: 63 self.die_on_ro(config) 64 args.append(config) 65 try: 66 return func(*args, **kwargs) 67 finally: 68 if config: 69 config.close()
70 return open_and_close_config 71
72 73 -def with_config(func):
74 """ 75 opens a config and passes it as the second argument. 76 """ 77 return wraps(func)(_make_open_and_close_config(func, True))
78
79 80 -def with_rw_config(func):
81 """ 82 opens a config and passes it as the second argument. 83 Requires that the returned config be writeable 84 """ 85 return wraps(func)(_make_open_and_close_config(func, False))
86
87 88 -class PrefsControl(BaseControl):
89
90 - def _configure(self, parser):
91 parser.add_argument( 92 "--source", help="Which configuration file should be used. " 93 "By default, OMERO.grid will use the file in etc/grid/config.xml." 94 " If you would like to configure your system to use " 95 "$HOME/omero/config.xml, you will need to modify the application " 96 " descriptor") 97 98 sub = parser.sub() 99 100 all = sub.add_parser( 101 "all", help="List all profiles in the current config.xml file.") 102 all.set_defaults(func=self.all) 103 104 default = sub.add_parser( 105 "def", help="""List (or set) the current active profile.""") 106 default.set_defaults(func=self.default) 107 default.add_argument( 108 "NAME", nargs="?", 109 help="Name of the profile which should be made the new active" 110 " profile.") 111 112 get = sub.add_parser( 113 "get", help="Get keys from the current profile. All by default") 114 get.set_defaults(func=self.get) 115 get.add_argument("KEY", nargs="*") 116 117 set = sub.add_parser( 118 "set", help="Set key-value pair in the current profile. Omit the" 119 " value to remove the key.") 120 set.set_defaults(func=self.set) 121 set.add_argument("KEY") 122 set.add_argument( 123 "VALUE", nargs="?", 124 help="Value to be set. If it is missing, the key will be removed") 125 126 drop = sub.add_parser( 127 "drop", help="Removes the profile from the configuration file") 128 drop.set_defaults(func=self.drop) 129 drop.add_argument("NAME") 130 131 keys = sub.add_parser( 132 "keys", help="""List all keys for the current profile""") 133 keys.set_defaults(func=self.keys) 134 135 load = sub.add_parser( 136 "load", 137 help="""Read into current profile from a file or standard in""") 138 load.set_defaults(func=self.load) 139 load.add_argument( 140 "-q", action="store_true", help="No error on conflict") 141 load.add_argument( 142 "file", nargs="*", type=ExistingFile('r'), default="-", 143 help="Files to read from. Default to standard in if not" 144 " specified") 145 146 parser.add(sub, self.edit, "Presents the properties for the current" 147 " profile in your editor. Saving them will update your" 148 " profile.") 149 parser.add(sub, self.version, "Prints the configuration version for" 150 " the current profile.") 151 parser.add(sub, self.path, "Prints the file that is used for " 152 " configuration") 153 parser.add(sub, self.lock, "Acquires the config file lock and holds" 154 " it") 155 parser.add(sub, self.upgrade, "Creates a 4.2 config.xml file based on" 156 " your current Java Preferences") 157 old = parser.add(sub, self.old, "Delegates to the old configuration" 158 " system using Java preferences") 159 old.add_argument("target", nargs="*")
160
161 - def die_on_ro(self, config):
162 if not config.save_on_close: 163 self.ctx.die(333, "Cannot modify %s" % config.filename)
164
165 - def open_config(self, args):
166 if args.source: 167 cfg_xml = path(args.source) 168 if not cfg_xml.exists(): 169 self.ctx.die(124, "File not found: %s" % args.source) 170 else: 171 grid_dir = self.ctx.dir / "etc" / "grid" 172 if grid_dir.exists(): 173 cfg_xml = grid_dir / "config.xml" 174 else: 175 userdir = path(get_user_dir()) 176 usr_xml = userdir / "omero" / "config.xml" 177 self.ctx.err("%s not found; using %s" % (grid_dir, usr_xml)) 178 cfg_xml = usr_xml 179 try: 180 return ConfigXml(str(cfg_xml)) 181 except portalocker.LockException: 182 self.ctx.die(112, "Could not acquire lock on %s" % cfg_xml) 183 except Exception, e: 184 self.ctx.die(113, str(e))
185 186 @with_config
187 - def all(self, args, config):
188 for k, v in config.properties(None, True): 189 self.ctx.out(k)
190 191 @with_config
192 - def default(self, args, config):
193 if args.NAME is not None: 194 self.die_on_ro(config) 195 self.ctx.out(config.default(args.NAME))
196 197 @with_config
198 - def drop(self, args, config):
199 try: 200 config.remove(args.NAME) 201 except KeyError: 202 self.ctx.err("Unknown configuration: %s" % args.NAME)
203 204 @with_config
205 - def get(self, args, config):
206 orig = sorted(list(config.keys())) 207 keys = sorted(list(args.KEY)) 208 if not keys: 209 keys = orig 210 for k in config.IGNORE: 211 k in keys and keys.remove(k) 212 213 for k in keys: 214 if k not in orig: 215 continue 216 if args.KEY and len(args.KEY) == 1: 217 self.ctx.out(config[k]) 218 else: 219 self.ctx.out("%s=%s" % (k, config[k]))
220 221 @with_rw_config
222 - def set(self, args, config):
223 if "=" in args.KEY and args.VALUE is None: 224 k, v = args.KEY.split("=", 1) 225 self.ctx.err(""" "=" in key name. Did you mean "...set %s %s"?""" 226 % (k, v)) 227 elif args.VALUE is None: 228 del config[args.KEY] 229 else: 230 config[args.KEY] = args.VALUE
231 232 @with_config
233 - def keys(self, args, config):
234 for k in config.keys(): 235 if k not in config.IGNORE: 236 self.ctx.out(k)
237 238 @with_rw_config
239 - def load(self, args, config):
240 keys = None 241 if not args.q: 242 keys = config.keys() 243 244 try: 245 for f in args.file: 246 if f == "-": 247 # Read from standard input 248 import fileinput 249 f = fileinput.input(f) 250 251 try: 252 previous = None 253 for line in f: 254 if previous: 255 line = previous + line 256 previous = self.handle_line(line, config, keys) 257 finally: 258 if f != "-": 259 f.close() 260 except NonZeroReturnCode: 261 raise 262 except Exception, e: 263 self.ctx.die(968, "Cannot read %s: %s" % (args.file, e))
264 265 @with_rw_config
266 - def edit(self, args, config, edit_path=edit_path):
267 from omero.util.temp_files import create_path, remove_path 268 start_text = "# Edit your preferences below. Comments are ignored\n" 269 for k in sorted(config.keys()): 270 start_text += ("%s=%s\n" % (k, config[k])) 271 temp_file = create_path() 272 try: 273 edit_path(temp_file, start_text) 274 except RuntimeError, re: 275 self.ctx.die(954, "%s: Failed to edit %s" 276 % (getattr(re, "pid", "Unknown"), temp_file)) 277 args.NAME = config.default() 278 self.drop(args, config) 279 args.file = [open(str(temp_file), "r")] 280 args.q = True 281 self.load(args, config) 282 remove_path(temp_file)
283 284 @with_config
285 - def version(self, args, config):
286 self.ctx.out(config.version(config.default()))
287 288 @with_config
289 - def path(self, args, config):
290 self.ctx.out(config.filename)
291 292 @with_rw_config
293 - def lock(self, args, config):
294 self.ctx.input("Press enter to unlock")
295 296 @with_rw_config
297 - def upgrade(self, args, config):
298 self.ctx.out("Importing pre-4.2 preferences") 299 txt = getprefs(["get"], str(self.ctx.dir / "lib")) 300 for line in txt.split("\n"): 301 self.handle_line(line, config, None) 302 303 # Upgrade procedure for 4.2 304 MSG = """Manually modify them via "omero config old set ..." and \ 305 re-run""" 306 m = config.as_map() 307 for x in ("keyStore", "keyStorePassword", "trustStore", 308 "trustStorePassword"): 309 old = "omero.ldap." + x 310 new = "omero.security." + x 311 if old in m: 312 config[new] = config[old] 313 314 attributes, values = [], [] 315 if "omero.ldap.attributes" in m: 316 attributes = config["omero.ldap.attributes"] 317 attributes = attributes.split(",") 318 if "omero.ldap.values" in m: 319 values = config["omero.ldap.values"] 320 values = values.split(",") 321 322 if len(attributes) != len(values): 323 raise ValueError("%s != %s\nLDAP properties in pre-4.2" 324 " configuration are invalid.\n%s" 325 % (attributes, values, MSG)) 326 pairs = zip(attributes, values) 327 if pairs: 328 if len(pairs) == 1: 329 user_filter = "(%s=%s)" % (tuple(pairs[0])) 330 else: 331 user_filter = "(&%s)" % ["(%s=%s)" % tuple(pair) 332 for pair in pairs] 333 config["omero.ldap.user_filter"] = user_filter 334 335 if "omero.ldap.groups" in m: 336 raise ValueError("Not currently handling omero.ldap.groups\n%s" 337 % MSG) 338 339 config["omero.config.upgraded"] = "4.2.0"
340
341 - def handle_line(self, line, config, keys):
342 line = line.strip() 343 if not line or line.startswith("#"): 344 return None 345 if line.endswith("\\"): 346 return line[:-1] 347 348 parts = line.split("=", 1) 349 if len(parts[0]) == 0: 350 return 351 if len(parts) == 1: 352 parts.append("") 353 354 _key = parts[0] 355 _new = parts[1] 356 if _key in config.keys(): 357 _old = config[_key] 358 else: 359 _old = None 360 361 if keys and _key in keys and _new != _old: 362 363 self.ctx.die(502, "Duplicate property: %s ('%s' => '%s')" 364 % (_key, _old, _new)) 365 keys.append(_key) 366 367 config[_key] = _new
368
369 - def old(self, args):
370 self.ctx.out(getprefs(args.target, str(self.ctx.dir / "lib")))
371 372 try: 373 register("config", PrefsControl, HELP) 374 except NameError: 375 if __name__ == "__main__": 376 cli = CLI() 377 cli.register("config", PrefsControl, HELP) 378 cli.invoke(sys.argv[1:]) 379