From b65b41e5957d5ded516343b3611292c9744d169f Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Thu, 4 Nov 2010 12:42:14 +0100 Subject: Add a templating mechanism in the flag parsing. Add a state_path flag that will be used as the top-level dir for all other state (such as images, instances, buckets, networks, etc). This way you only need to change one flag to put all your state in e.g. /var/lib/nova. --- nova/flags.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'nova/flags.py') diff --git a/nova/flags.py b/nova/flags.py index 4ae86d9b2..2b8bbbdb7 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -26,6 +26,8 @@ import os import socket import sys +from string import Template + import gflags @@ -134,8 +136,21 @@ class FlagValues(gflags.FlagValues): def __getattr__(self, name): if self.IsDirty(name): self.ParseNewFlags() - return gflags.FlagValues.__getattr__(self, name) + val = gflags.FlagValues.__getattr__(self, name) + if type(val) is str: + tmpl = Template(val) + return tmpl.substitute(StrWrapper(self)) + return val +class StrWrapper(object): + def __init__(self, obj): + self.wrapped = obj + + def __getitem__(self, name): + if hasattr(self.wrapped, name): + return str(getattr(self.wrapped, name)) + else: + raise KeyError(name) FLAGS = FlagValues() gflags.FLAGS = FLAGS @@ -218,8 +233,11 @@ DEFINE_string('vpn_key_suffix', DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger') +DEFINE_string('state_path', os.path.abspath("./"), + "Top-level directory for maintaining nova's state") + DEFINE_string('sql_connection', - 'sqlite:///%s/nova.sqlite' % os.path.abspath("./"), + 'sqlite:///$state_path/nova.sqlite', 'connection string for sql database') DEFINE_string('compute_manager', 'nova.compute.manager.ComputeManager', -- cgit From c8f6db354f5e8f55b432854d5259dcf84f0c8ba0 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 29 Nov 2010 15:49:12 +0100 Subject: Make sure templated flags work across calls to ParseNewFlags. ParseNewFlags creates a new FlagValues object, which doesn't have all the previously defined flags, so template lookups fail miserably. Pass the existing FlagValues object too the template mapping object to fix this. --- nova/flags.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'nova/flags.py') diff --git a/nova/flags.py b/nova/flags.py index 70a049491..641bda5f9 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -40,11 +40,12 @@ class FlagValues(gflags.FlagValues): """ - def __init__(self): + def __init__(self, extra_context=None): gflags.FlagValues.__init__(self) self.__dict__['__dirty'] = [] self.__dict__['__was_already_parsed'] = False self.__dict__['__stored_argv'] = [] + self.__dict__['__extra_context'] = extra_context def __call__(self, argv): # We're doing some hacky stuff here so that we don't have to copy @@ -114,7 +115,7 @@ class FlagValues(gflags.FlagValues): def ParseNewFlags(self): if '__stored_argv' not in self.__dict__: return - new_flags = FlagValues() + new_flags = FlagValues(self) for k in self.__dict__['__dirty']: new_flags[k] = gflags.FlagValues.__getitem__(self, k) @@ -139,18 +140,25 @@ class FlagValues(gflags.FlagValues): val = gflags.FlagValues.__getattr__(self, name) if type(val) is str: tmpl = Template(val) - return tmpl.substitute(StrWrapper(self)) + context = [self, self.__dict__['__extra_context']] + return tmpl.substitute(StrWrapper(context)) return val + class StrWrapper(object): - def __init__(self, obj): - self.wrapped = obj + """Wrapper around FlagValues objects + + Wraps FlagValues objects for string.Template so that we're + sure to return strings.""" + def __init__(self, context_objs): + self.context_objs = context_objs def __getitem__(self, name): - if hasattr(self.wrapped, name): - return str(getattr(self.wrapped, name)) - else: - raise KeyError(name) + for context in self.context_objs: + val = getattr(context, name, False) + if val: + return str(val) + raise KeyError(name) FLAGS = FlagValues() gflags.FLAGS = FLAGS -- cgit From 28927f0c9688dd7f3c84a1eda4cc646a1aff7896 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 29 Nov 2010 21:05:40 +0100 Subject: Import string instead of importing Template from string. This is how we do things. --- nova/flags.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'nova/flags.py') diff --git a/nova/flags.py b/nova/flags.py index 641bda5f9..948729449 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -24,10 +24,9 @@ where they're used. import getopt import os import socket +import string import sys -from string import Template - import gflags @@ -139,7 +138,7 @@ class FlagValues(gflags.FlagValues): self.ParseNewFlags() val = gflags.FlagValues.__getattr__(self, name) if type(val) is str: - tmpl = Template(val) + tmpl = string.Template(val) context = [self, self.__dict__['__extra_context']] return tmpl.substitute(StrWrapper(context)) return val -- cgit From 03deb0dde48a0b9c7c6c52689ecf8a70e1fa7b7e Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 29 Nov 2010 22:01:19 +0100 Subject: Adjust state_path default setting so that api unit tests find things where they used to find them. --- nova/flags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/flags.py') diff --git a/nova/flags.py b/nova/flags.py index 948729449..cb9fa105b 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -244,7 +244,7 @@ DEFINE_string('vpn_key_suffix', DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger') -DEFINE_string('state_path', os.path.abspath("./"), +DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'), "Top-level directory for maintaining nova's state") DEFINE_string('sql_connection', -- cgit