Merge branch 'stable-2.16' into stable-2.17
[ganeti-github.git] / lib / config / utils.py
1 #
2 #
3
4 # Copyright (C) 2014 Google Inc.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are
9 # met:
10 #
11 # 1. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 #
14 # 2. Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in the
16 # documentation and/or other materials provided with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19 # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
31 """Utilities used by the config module."""
32
33
34 import logging
35
36
37 def ConfigSync(shared=0):
38 """Configuration synchronization decorator.
39
40 """
41 def wrap(fn):
42 def sync_function(*args, **kwargs):
43 with args[0].GetConfigManager(shared):
44 return fn(*args, **kwargs)
45 return sync_function
46 return wrap
47
48
49 class ConfigManager(object):
50 """Locks the configuration and exposes it to be read or modified.
51
52 """
53 def __init__(self, config_writer, shared=False, forcelock=False):
54 assert hasattr(config_writer, '_ConfigData'), \
55 "invalid argument: Not a ConfigWriter"
56 self._config_writer = config_writer
57 self._shared = shared
58 self._forcelock = forcelock
59
60 def __enter__(self):
61 try:
62 self._config_writer._OpenConfig(# pylint: disable=W0212
63 self._shared,
64 force=self._forcelock)
65 except Exception:
66 logging.debug("Opening configuration failed")
67 try:
68 self._config_writer._CloseConfig(False) # pylint: disable=W0212
69 except Exception: # pylint: disable=W0703
70 logging.debug("Closing configuration failed as well")
71 raise
72
73 def __exit__(self, exc_type, exc_value, traceback):
74 # save the configuration, if this was a write opreration that succeeded
75 if exc_type is not None:
76 logging.debug("Configuration operation failed,"
77 " the changes will not be saved")
78 # pylint: disable=W0212
79 self._config_writer._CloseConfig(not self._shared and exc_type is None)
80 return False