summaryrefslogtreecommitdiffstats
path: root/nova/utils.py
diff options
context:
space:
mode:
authorSoren Hansen <soren@linux2go.dk>2011-02-28 15:28:49 +0100
committerSoren Hansen <soren@linux2go.dk>2011-02-28 15:28:49 +0100
commitd488e18a4dd99ddfb77e39f5be4b270e46b2fd42 (patch)
treea3bfc5a8e527013521889fcdddd59693fe83f669 /nova/utils.py
parent8b0e8b155eab313e0caece48eee609d12df5e5d4 (diff)
parent8b3e9ad11c2f5c425701f1eb4abb7b3f577ae1cc (diff)
downloadnova-d488e18a4dd99ddfb77e39f5be4b270e46b2fd42.tar.gz
nova-d488e18a4dd99ddfb77e39f5be4b270e46b2fd42.tar.xz
nova-d488e18a4dd99ddfb77e39f5be4b270e46b2fd42.zip
Merge sync branch.
Diffstat (limited to 'nova/utils.py')
-rw-r--r--nova/utils.py62
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)