1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """Global Configuration data for Ganeti.
23
24 This module provides the interface to a special case of cluster
25 configuration data, which is mostly static and available to all nodes.
26
27 """
28
29 import sys
30 import re
31
32 from ganeti import errors
33 from ganeti import constants
34 from ganeti import utils
35 from ganeti import serializer
36
37
38 SSCONF_LOCK_TIMEOUT = 10
39
40 RE_VALID_SSCONF_NAME = re.compile(r'^[-_a-z0-9]+$')
44 """Simple class to read configuration file.
45
46 """
48 """Initializes this class.
49
50 @type file_name: string
51 @param file_name: Configuration file path
52
53 """
54 self._file_name = file_name
55 self._config_data = serializer.Load(utils.ReadFile(file_name))
56
57
59 return self._config_data["cluster"]["cluster_name"]
60
62 return self._config_data["cluster"]["rsahostkeypub"]
63
65 return self._config_data["cluster"]["master_node"]
66
68 return self._config_data["cluster"]["master_ip"]
69
71 return self._config_data["cluster"]["master_netdev"]
72
74 return self._config_data["cluster"]["file_storage_dir"]
75
77 return self._config_data["cluster"]["hypervisor"]
78
80 return self._config_data["nodes"].keys()
81
82 @classmethod
84 """Alternative construction from a dictionary.
85
86 """
87 obj = SimpleConfigReader.__new__(cls)
88 obj._config_data = val
89 obj._file_name = cfg_file
90 return obj
91
94 """Simple class to write configuration file.
95
96 """
98 """Writes configuration file.
99
100 Warning: Doesn't take care of locking or synchronizing with other
101 processes.
102
103 """
104 utils.WriteFile(self._file_name,
105 data=serializer.Dump(self._config_data),
106 mode=0600)
107
110 """Interface to static cluster data.
111
112 This is different that the config.ConfigWriter and
113 SimpleConfigReader classes in that it holds data that will always be
114 present, even on nodes which don't have all the cluster data.
115
116 Other particularities of the datastore:
117 - keys are restricted to predefined values
118
119 """
120 _SS_FILEPREFIX = "ssconf_"
121 _VALID_KEYS = (
122 constants.SS_CLUSTER_NAME,
123 constants.SS_CLUSTER_TAGS,
124 constants.SS_FILE_STORAGE_DIR,
125 constants.SS_MASTER_CANDIDATES,
126 constants.SS_MASTER_IP,
127 constants.SS_MASTER_NETDEV,
128 constants.SS_MASTER_NODE,
129 constants.SS_NODE_LIST,
130 constants.SS_OFFLINE_NODES,
131 constants.SS_ONLINE_NODES,
132 constants.SS_INSTANCE_LIST,
133 constants.SS_RELEASE_VERSION,
134 )
135 _MAX_SIZE = 131072
136
138 if cfg_location is None:
139 self._cfg_dir = constants.DATA_DIR
140 else:
141 self._cfg_dir = cfg_location
142
144 """Convert a given key into filename.
145
146 """
147 if key not in self._VALID_KEYS:
148 raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
149 % str(key))
150
151 filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
152 return filename
153
155 """Generic routine to read keys.
156
157 This will read the file which holds the value requested. Errors
158 will be changed into ConfigurationErrors.
159
160 """
161 filename = self.KeyToFilename(key)
162 try:
163 fh = file(filename, 'r')
164 try:
165 data = fh.read(self._MAX_SIZE)
166 data = data.rstrip('\n')
167 finally:
168 fh.close()
169 except EnvironmentError, err:
170 raise errors.ConfigurationError("Can't read from the ssconf file:"
171 " '%s'" % str(err))
172 return data
173
175 """Writes ssconf files used by external scripts.
176
177 @type values: dict
178 @param values: Dictionary of (name, value)
179
180 """
181 ssconf_lock = utils.FileLock(constants.SSCONF_LOCK_FILE)
182
183
184 ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
185 try:
186 for name, value in values.iteritems():
187 if value and not value.endswith("\n"):
188 value += "\n"
189 utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444)
190 finally:
191 ssconf_lock.Unlock()
192
194 """Return the list of all config files.
195
196 This is used for computing node replication data.
197
198 """
199 return [self.KeyToFilename(key) for key in self._VALID_KEYS]
200
206
212
220
226
232
238
246
254
257 """Get the master node and my own hostname.
258
259 This can be either used for a 'soft' check (compared to CheckMaster,
260 which exits) or just for computing both at the same time.
261
262 The function does not handle any errors, these should be handled in
263 the caller (errors.ConfigurationError, errors.ResolverError).
264
265 @param ss: either a sstore.SimpleConfigReader or a
266 sstore.SimpleStore instance
267 @rtype: tuple
268 @return: a tuple (master node name, my own name)
269
270 """
271 if ss is None:
272 ss = SimpleStore()
273 return ss.GetMasterNode(), utils.HostInfo().name
274
296