diff options
| author | Soren Hansen <soren@linux2go.dk> | 2011-02-28 15:28:49 +0100 |
|---|---|---|
| committer | Soren Hansen <soren@linux2go.dk> | 2011-02-28 15:28:49 +0100 |
| commit | d488e18a4dd99ddfb77e39f5be4b270e46b2fd42 (patch) | |
| tree | a3bfc5a8e527013521889fcdddd59693fe83f669 /nova/utils.py | |
| parent | 8b0e8b155eab313e0caece48eee609d12df5e5d4 (diff) | |
| parent | 8b3e9ad11c2f5c425701f1eb4abb7b3f577ae1cc (diff) | |
| download | nova-d488e18a4dd99ddfb77e39f5be4b270e46b2fd42.tar.gz nova-d488e18a4dd99ddfb77e39f5be4b270e46b2fd42.tar.xz nova-d488e18a4dd99ddfb77e39f5be4b270e46b2fd42.zip | |
Merge sync branch.
Diffstat (limited to 'nova/utils.py')
| -rw-r--r-- | nova/utils.py | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/nova/utils.py b/nova/utils.py index 85141e8d2..1198c1360 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -2,6 +2,7 @@ # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. +# Copyright 2011 Justin Santa Barbara # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -24,6 +25,7 @@ import base64 import datetime import inspect import json +import lockfile import os import random import socket @@ -31,6 +33,7 @@ import string import struct import sys import time +import types from xml.sax import saxutils import re import netaddr @@ -498,6 +501,16 @@ def loads(s): return json.loads(s) +def synchronized(name): + def wrap(f): + def inner(*args, **kwargs): + lock = lockfile.FileLock('nova-%s.lock' % name) + with lock: + return f(*args, **kwargs) + return inner + return wrap + + def ensure_b64_encoding(val): """Safety method to ensure that values expected to be base64-encoded actually are. If they are, the value is returned unchanged. Otherwise, @@ -508,3 +521,52 @@ def ensure_b64_encoding(val): return val except TypeError: return base64.b64encode(val) + + +def get_from_path(items, path): + """ Returns a list of items matching the specified path. Takes an + XPath-like expression e.g. prop1/prop2/prop3, and for each item in items, + looks up items[prop1][prop2][prop3]. Like XPath, if any of the + intermediate results are lists it will treat each list item individually. + A 'None' in items or any child expressions will be ignored, this function + will not throw because of None (anywhere) in items. The returned list + will contain no None values.""" + + if path is None: + raise exception.Error("Invalid mini_xpath") + + (first_token, sep, remainder) = path.partition("/") + + if first_token == "": + raise exception.Error("Invalid mini_xpath") + + results = [] + + if items is None: + return results + + if not isinstance(items, types.ListType): + # Wrap single objects in a list + items = [items] + + for item in items: + if item is None: + continue + get_method = getattr(item, "get", None) + if get_method is None: + continue + child = get_method(first_token) + if child is None: + continue + if isinstance(child, types.ListType): + # Flatten intermediate lists + for x in child: + results.append(x) + else: + results.append(child) + + if not sep: + # No more tokens + return results + else: + return get_from_path(results, remainder) |
