Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ ae130c81

History | View | Annotate | Download (11.7 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 856c67e1 Michael Hanselmann
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Global Configuration data for Ganeti.
23 a8083063 Iustin Pop

24 a8083063 Iustin Pop
This module provides the interface to a special case of cluster
25 a8083063 Iustin Pop
configuration data, which is mostly static and available to all nodes.
26 a8083063 Iustin Pop

27 a8083063 Iustin Pop
"""
28 a8083063 Iustin Pop
29 5675cd1f Iustin Pop
import sys
30 03d1dba2 Michael Hanselmann
import re
31 7bcc78e4 Guido Trotter
import os
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
from ganeti import errors
34 a8083063 Iustin Pop
from ganeti import constants
35 41a57aab Michael Hanselmann
from ganeti import utils
36 856c67e1 Michael Hanselmann
from ganeti import serializer
37 a8083063 Iustin Pop
38 a8083063 Iustin Pop
39 0c223ea9 Michael Hanselmann
SSCONF_LOCK_TIMEOUT = 10
40 0c223ea9 Michael Hanselmann
41 03d1dba2 Michael Hanselmann
RE_VALID_SSCONF_NAME = re.compile(r'^[-_a-z0-9]+$')
42 03d1dba2 Michael Hanselmann
43 0c223ea9 Michael Hanselmann
44 02f99608 Oleksiy Mishchenko
class SimpleConfigReader(object):
45 856c67e1 Michael Hanselmann
  """Simple class to read configuration file.
46 856c67e1 Michael Hanselmann

47 856c67e1 Michael Hanselmann
  """
48 856c67e1 Michael Hanselmann
  def __init__(self, file_name=constants.CLUSTER_CONF_FILE):
49 856c67e1 Michael Hanselmann
    """Initializes this class.
50 856c67e1 Michael Hanselmann

51 856c67e1 Michael Hanselmann
    @type file_name: string
52 856c67e1 Michael Hanselmann
    @param file_name: Configuration file path
53 856c67e1 Michael Hanselmann

54 856c67e1 Michael Hanselmann
    """
55 856c67e1 Michael Hanselmann
    self._file_name = file_name
56 7bcc78e4 Guido Trotter
    self._last_inode = None
57 7bcc78e4 Guido Trotter
    self._last_mtime = None
58 7bcc78e4 Guido Trotter
    self._last_size = None
59 7bcc78e4 Guido Trotter
    # we need a forced reload at class init time, to initialize _last_*
60 7bcc78e4 Guido Trotter
    self._Load(force=True)
61 1fe93c75 Guido Trotter
62 7bcc78e4 Guido Trotter
  def _Load(self, force=False):
63 ad8b2f9b Guido Trotter
    """Loads (or reloads) the config file.
64 1fe93c75 Guido Trotter

65 7bcc78e4 Guido Trotter
    @type force: boolean
66 7bcc78e4 Guido Trotter
    @param force: whether to force the reload without checking the mtime
67 7bcc78e4 Guido Trotter
    @rtype: boolean
68 7bcc78e4 Guido Trotter
    @return: boolean values that says whether we reloaded the configuration or not
69 7bcc78e4 Guido Trotter
             (because we decided it was already up-to-date)
70 7bcc78e4 Guido Trotter

71 1fe93c75 Guido Trotter
    """
72 7bcc78e4 Guido Trotter
    cfg_stat = os.stat(self._file_name)
73 7bcc78e4 Guido Trotter
    inode = cfg_stat.st_ino
74 7bcc78e4 Guido Trotter
    mtime = cfg_stat.st_mtime
75 7bcc78e4 Guido Trotter
    size = cfg_stat.st_size
76 7bcc78e4 Guido Trotter
77 7bcc78e4 Guido Trotter
    reload = False
78 7bcc78e4 Guido Trotter
    if force or inode != self._last_inode or \
79 7bcc78e4 Guido Trotter
       mtime > self._last_mtime or \
80 7bcc78e4 Guido Trotter
       size != self._last_size:
81 7bcc78e4 Guido Trotter
      self._last_inode = inode
82 7bcc78e4 Guido Trotter
      self._last_mtime = mtime
83 7bcc78e4 Guido Trotter
      self._last_size = size
84 7bcc78e4 Guido Trotter
      reload = True
85 7bcc78e4 Guido Trotter
86 7bcc78e4 Guido Trotter
    if not reload:
87 7bcc78e4 Guido Trotter
      return False
88 7bcc78e4 Guido Trotter
89 01cf7dbe Guido Trotter
    try:
90 1fe93c75 Guido Trotter
      self._config_data = serializer.Load(utils.ReadFile(self._file_name))
91 01cf7dbe Guido Trotter
    except IOError, err:
92 01cf7dbe Guido Trotter
      raise errors.ConfigurationError("Cannot read config file %s: %s" %
93 1fe93c75 Guido Trotter
                                      (self._file_name, err))
94 01cf7dbe Guido Trotter
    except ValueError, err:
95 01cf7dbe Guido Trotter
      raise errors.ConfigurationError("Cannot load config file %s: %s" %
96 1fe93c75 Guido Trotter
                                      (self._file_name, err))
97 856c67e1 Michael Hanselmann
98 ae130c81 Guido Trotter
    self._ip_to_instance = {}
99 ae130c81 Guido Trotter
    for iname in self._config_data['instances']:
100 ae130c81 Guido Trotter
      instance = self._config_data['instances'][iname]
101 ae130c81 Guido Trotter
      for nic in instance['nics']:
102 ae130c81 Guido Trotter
        if 'ip' in nic and nic['ip']:
103 ae130c81 Guido Trotter
          self._ip_to_instance[nic['ip']] = iname
104 ae130c81 Guido Trotter
105 7bcc78e4 Guido Trotter
    return True
106 7bcc78e4 Guido Trotter
107 ad8b2f9b Guido Trotter
  # Clients can request a reload of the config file, so we export our internal
108 ad8b2f9b Guido Trotter
  # _Load function as Reload.
109 ad8b2f9b Guido Trotter
  Reload = _Load
110 ad8b2f9b Guido Trotter
111 856c67e1 Michael Hanselmann
  def GetClusterName(self):
112 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["cluster_name"]
113 856c67e1 Michael Hanselmann
114 856c67e1 Michael Hanselmann
  def GetHostKey(self):
115 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["rsahostkeypub"]
116 856c67e1 Michael Hanselmann
117 856c67e1 Michael Hanselmann
  def GetMasterNode(self):
118 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["master_node"]
119 856c67e1 Michael Hanselmann
120 856c67e1 Michael Hanselmann
  def GetMasterIP(self):
121 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["master_ip"]
122 856c67e1 Michael Hanselmann
123 856c67e1 Michael Hanselmann
  def GetMasterNetdev(self):
124 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["master_netdev"]
125 856c67e1 Michael Hanselmann
126 856c67e1 Michael Hanselmann
  def GetFileStorageDir(self):
127 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["file_storage_dir"]
128 856c67e1 Michael Hanselmann
129 856c67e1 Michael Hanselmann
  def GetHypervisorType(self):
130 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["hypervisor"]
131 856c67e1 Michael Hanselmann
132 856c67e1 Michael Hanselmann
  def GetNodeList(self):
133 856c67e1 Michael Hanselmann
    return self._config_data["nodes"].keys()
134 856c67e1 Michael Hanselmann
135 a0c26bdb Guido Trotter
  def GetConfigSerialNo(self):
136 a0c26bdb Guido Trotter
    return self._config_data["serial_no"]
137 a0c26bdb Guido Trotter
138 a0c26bdb Guido Trotter
  def GetClusterSerialNo(self):
139 a0c26bdb Guido Trotter
    return self._config_data["cluster"]["serial_no"]
140 a0c26bdb Guido Trotter
141 e843991b Guido Trotter
  def GetNodeStatusFlags(self, node):
142 e843991b Guido Trotter
    """Get a node's status flags
143 e843991b Guido Trotter

144 e843991b Guido Trotter
    @type node: string
145 e843991b Guido Trotter
    @param node: node name
146 e843991b Guido Trotter
    @rtype: (bool, bool, bool)
147 e843991b Guido Trotter
    @return: (master_candidate, drained, offline) (or None if no such node)
148 e843991b Guido Trotter

149 e843991b Guido Trotter
    """
150 e843991b Guido Trotter
    if node not in self._config_data["nodes"]:
151 e843991b Guido Trotter
      return None
152 e843991b Guido Trotter
153 e843991b Guido Trotter
    master_candidate = self._config_data["nodes"][node]["master_candidate"]
154 e843991b Guido Trotter
    drained = self._config_data["nodes"][node]["drained"]
155 e843991b Guido Trotter
    offline = self._config_data["nodes"][node]["offline"]
156 e843991b Guido Trotter
    return master_candidate, drained, offline
157 e843991b Guido Trotter
158 ae130c81 Guido Trotter
  def GetInstanceByIp(self, ip):
159 ae130c81 Guido Trotter
    if ip not in self._ip_to_instance:
160 ae130c81 Guido Trotter
      return None
161 ae130c81 Guido Trotter
    return self._ip_to_instance[ip]
162 ae130c81 Guido Trotter
163 ae130c81 Guido Trotter
  def GetNodePrimaryIp(self, node):
164 ae130c81 Guido Trotter
    """Get a node's primary ip
165 ae130c81 Guido Trotter

166 ae130c81 Guido Trotter
    @type node: string
167 ae130c81 Guido Trotter
    @param node: node name
168 ae130c81 Guido Trotter
    @rtype: string, or None
169 ae130c81 Guido Trotter
    @return: node's primary ip, or None if no such node
170 ae130c81 Guido Trotter

171 ae130c81 Guido Trotter
    """
172 ae130c81 Guido Trotter
    if node not in self._config_data["nodes"]:
173 ae130c81 Guido Trotter
      return None
174 ae130c81 Guido Trotter
    return self._config_data["nodes"][node]["primary_ip"]
175 ae130c81 Guido Trotter
176 ae130c81 Guido Trotter
  def GetInstancePrimaryNode(self, instance):
177 ae130c81 Guido Trotter
    """Get an instance's primary node
178 ae130c81 Guido Trotter

179 ae130c81 Guido Trotter
    @type instance: string
180 ae130c81 Guido Trotter
    @param instance: instance name
181 ae130c81 Guido Trotter
    @rtype: string, or None
182 ae130c81 Guido Trotter
    @return: primary node, or None if no such instance
183 ae130c81 Guido Trotter

184 ae130c81 Guido Trotter
    """
185 ae130c81 Guido Trotter
    if instance not in self._config_data["instances"]:
186 ae130c81 Guido Trotter
      return None
187 ae130c81 Guido Trotter
    return self._config_data["instances"][instance]["primary_node"]
188 ae130c81 Guido Trotter
189 856c67e1 Michael Hanselmann
190 93384844 Iustin Pop
class SimpleStore(object):
191 93384844 Iustin Pop
  """Interface to static cluster data.
192 93384844 Iustin Pop

193 93384844 Iustin Pop
  This is different that the config.ConfigWriter and
194 93384844 Iustin Pop
  SimpleConfigReader classes in that it holds data that will always be
195 93384844 Iustin Pop
  present, even on nodes which don't have all the cluster data.
196 93384844 Iustin Pop

197 93384844 Iustin Pop
  Other particularities of the datastore:
198 93384844 Iustin Pop
    - keys are restricted to predefined values
199 93384844 Iustin Pop

200 93384844 Iustin Pop
  """
201 93384844 Iustin Pop
  _SS_FILEPREFIX = "ssconf_"
202 93384844 Iustin Pop
  _VALID_KEYS = (
203 93384844 Iustin Pop
    constants.SS_CLUSTER_NAME,
204 5d60b3bd Iustin Pop
    constants.SS_CLUSTER_TAGS,
205 93384844 Iustin Pop
    constants.SS_FILE_STORAGE_DIR,
206 f56618e0 Iustin Pop
    constants.SS_MASTER_CANDIDATES,
207 8113a52e Luca Bigliardi
    constants.SS_MASTER_CANDIDATES_IPS,
208 93384844 Iustin Pop
    constants.SS_MASTER_IP,
209 93384844 Iustin Pop
    constants.SS_MASTER_NETDEV,
210 93384844 Iustin Pop
    constants.SS_MASTER_NODE,
211 93384844 Iustin Pop
    constants.SS_NODE_LIST,
212 f9780ccd Luca Bigliardi
    constants.SS_NODE_PRIMARY_IPS,
213 f9780ccd Luca Bigliardi
    constants.SS_NODE_SECONDARY_IPS,
214 a3316e4a Iustin Pop
    constants.SS_OFFLINE_NODES,
215 81a49123 Iustin Pop
    constants.SS_ONLINE_NODES,
216 81a49123 Iustin Pop
    constants.SS_INSTANCE_LIST,
217 8a113c7a Iustin Pop
    constants.SS_RELEASE_VERSION,
218 93384844 Iustin Pop
    )
219 93384844 Iustin Pop
  _MAX_SIZE = 131072
220 93384844 Iustin Pop
221 93384844 Iustin Pop
  def __init__(self, cfg_location=None):
222 93384844 Iustin Pop
    if cfg_location is None:
223 93384844 Iustin Pop
      self._cfg_dir = constants.DATA_DIR
224 93384844 Iustin Pop
    else:
225 93384844 Iustin Pop
      self._cfg_dir = cfg_location
226 93384844 Iustin Pop
227 93384844 Iustin Pop
  def KeyToFilename(self, key):
228 93384844 Iustin Pop
    """Convert a given key into filename.
229 93384844 Iustin Pop

230 93384844 Iustin Pop
    """
231 93384844 Iustin Pop
    if key not in self._VALID_KEYS:
232 93384844 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
233 93384844 Iustin Pop
                                   % str(key))
234 93384844 Iustin Pop
235 93384844 Iustin Pop
    filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
236 93384844 Iustin Pop
    return filename
237 93384844 Iustin Pop
238 93384844 Iustin Pop
  def _ReadFile(self, key):
239 93384844 Iustin Pop
    """Generic routine to read keys.
240 93384844 Iustin Pop

241 93384844 Iustin Pop
    This will read the file which holds the value requested. Errors
242 93384844 Iustin Pop
    will be changed into ConfigurationErrors.
243 93384844 Iustin Pop

244 93384844 Iustin Pop
    """
245 93384844 Iustin Pop
    filename = self.KeyToFilename(key)
246 93384844 Iustin Pop
    try:
247 920b5878 Guido Trotter
      data = utils.ReadFile(filename, size=self._MAX_SIZE)
248 93384844 Iustin Pop
    except EnvironmentError, err:
249 93384844 Iustin Pop
      raise errors.ConfigurationError("Can't read from the ssconf file:"
250 93384844 Iustin Pop
                                      " '%s'" % str(err))
251 920b5878 Guido Trotter
    data = data.rstrip('\n')
252 93384844 Iustin Pop
    return data
253 93384844 Iustin Pop
254 89b14f05 Iustin Pop
  def WriteFiles(self, values):
255 89b14f05 Iustin Pop
    """Writes ssconf files used by external scripts.
256 89b14f05 Iustin Pop

257 89b14f05 Iustin Pop
    @type values: dict
258 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
259 89b14f05 Iustin Pop

260 89b14f05 Iustin Pop
    """
261 89b14f05 Iustin Pop
    ssconf_lock = utils.FileLock(constants.SSCONF_LOCK_FILE)
262 89b14f05 Iustin Pop
263 89b14f05 Iustin Pop
    # Get lock while writing files
264 89b14f05 Iustin Pop
    ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
265 89b14f05 Iustin Pop
    try:
266 89b14f05 Iustin Pop
      for name, value in values.iteritems():
267 02b31f32 Iustin Pop
        if value and not value.endswith("\n"):
268 89b14f05 Iustin Pop
          value += "\n"
269 81a49123 Iustin Pop
        utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444)
270 89b14f05 Iustin Pop
    finally:
271 89b14f05 Iustin Pop
      ssconf_lock.Unlock()
272 89b14f05 Iustin Pop
273 93384844 Iustin Pop
  def GetFileList(self):
274 93384844 Iustin Pop
    """Return the list of all config files.
275 93384844 Iustin Pop

276 93384844 Iustin Pop
    This is used for computing node replication data.
277 93384844 Iustin Pop

278 93384844 Iustin Pop
    """
279 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
280 93384844 Iustin Pop
281 93384844 Iustin Pop
  def GetClusterName(self):
282 93384844 Iustin Pop
    """Get the cluster name.
283 93384844 Iustin Pop

284 93384844 Iustin Pop
    """
285 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
286 93384844 Iustin Pop
287 93384844 Iustin Pop
  def GetFileStorageDir(self):
288 93384844 Iustin Pop
    """Get the file storage dir.
289 93384844 Iustin Pop

290 93384844 Iustin Pop
    """
291 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
292 93384844 Iustin Pop
293 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
294 f56618e0 Iustin Pop
    """Return the list of master candidates.
295 f56618e0 Iustin Pop

296 f56618e0 Iustin Pop
    """
297 f56618e0 Iustin Pop
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES)
298 f56618e0 Iustin Pop
    nl = data.splitlines(False)
299 f56618e0 Iustin Pop
    return nl
300 f56618e0 Iustin Pop
301 8113a52e Luca Bigliardi
  def GetMasterCandidatesIPList(self):
302 8113a52e Luca Bigliardi
    """Return the list of master candidates' primary IP.
303 8113a52e Luca Bigliardi

304 8113a52e Luca Bigliardi
    """
305 8113a52e Luca Bigliardi
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES_IPS)
306 8113a52e Luca Bigliardi
    nl = data.splitlines(False)
307 8113a52e Luca Bigliardi
    return nl
308 8113a52e Luca Bigliardi
309 93384844 Iustin Pop
  def GetMasterIP(self):
310 93384844 Iustin Pop
    """Get the IP of the master node for this cluster.
311 93384844 Iustin Pop

312 93384844 Iustin Pop
    """
313 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
314 93384844 Iustin Pop
315 93384844 Iustin Pop
  def GetMasterNetdev(self):
316 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
317 93384844 Iustin Pop

318 93384844 Iustin Pop
    """
319 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
320 93384844 Iustin Pop
321 93384844 Iustin Pop
  def GetMasterNode(self):
322 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
323 93384844 Iustin Pop

324 93384844 Iustin Pop
    """
325 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
326 93384844 Iustin Pop
327 93384844 Iustin Pop
  def GetNodeList(self):
328 93384844 Iustin Pop
    """Return the list of cluster nodes.
329 93384844 Iustin Pop

330 93384844 Iustin Pop
    """
331 93384844 Iustin Pop
    data = self._ReadFile(constants.SS_NODE_LIST)
332 93384844 Iustin Pop
    nl = data.splitlines(False)
333 93384844 Iustin Pop
    return nl
334 93384844 Iustin Pop
335 f9780ccd Luca Bigliardi
  def GetNodePrimaryIPList(self):
336 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' primary IP.
337 f9780ccd Luca Bigliardi

338 f9780ccd Luca Bigliardi
    """
339 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_PRIMARY_IPS)
340 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
341 f9780ccd Luca Bigliardi
    return nl
342 f9780ccd Luca Bigliardi
343 f9780ccd Luca Bigliardi
  def GetNodeSecondaryIPList(self):
344 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' secondary IP.
345 f9780ccd Luca Bigliardi

346 f9780ccd Luca Bigliardi
    """
347 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
348 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
349 f9780ccd Luca Bigliardi
    return nl
350 f9780ccd Luca Bigliardi
351 25e39bfa Iustin Pop
  def GetClusterTags(self):
352 25e39bfa Iustin Pop
    """Return the cluster tags.
353 25e39bfa Iustin Pop

354 25e39bfa Iustin Pop
    """
355 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
356 25e39bfa Iustin Pop
    nl = data.splitlines(False)
357 25e39bfa Iustin Pop
    return nl
358 25e39bfa Iustin Pop
359 93384844 Iustin Pop
360 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
361 b33e986b Iustin Pop
  """Get the master node and my own hostname.
362 b33e986b Iustin Pop

363 b33e986b Iustin Pop
  This can be either used for a 'soft' check (compared to CheckMaster,
364 b33e986b Iustin Pop
  which exits) or just for computing both at the same time.
365 b33e986b Iustin Pop

366 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
367 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
368 b33e986b Iustin Pop

369 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
370 8135a2db Iustin Pop
      sstore.SimpleStore instance
371 8135a2db Iustin Pop
  @rtype: tuple
372 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
373 8135a2db Iustin Pop

374 b33e986b Iustin Pop
  """
375 b33e986b Iustin Pop
  if ss is None:
376 93384844 Iustin Pop
    ss = SimpleStore()
377 b33e986b Iustin Pop
  return ss.GetMasterNode(), utils.HostInfo().name
378 b33e986b Iustin Pop
379 06dc5b44 Iustin Pop
380 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
381 5675cd1f Iustin Pop
  """Checks the node setup.
382 5675cd1f Iustin Pop

383 5675cd1f Iustin Pop
  If this is the master, the function will return. Otherwise it will
384 5675cd1f Iustin Pop
  exit with an exit code based on the node status.
385 5675cd1f Iustin Pop

386 5675cd1f Iustin Pop
  """
387 5675cd1f Iustin Pop
  try:
388 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
389 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
390 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
391 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
392 5675cd1f Iustin Pop
  except errors.ResolverError, err:
393 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
394 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
395 5675cd1f Iustin Pop
396 b33e986b Iustin Pop
  if myself != master_name:
397 5675cd1f Iustin Pop
    if debug:
398 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
399 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)
400 3f71b464 Guido Trotter
401 3f71b464 Guido Trotter
402 3f71b464 Guido Trotter
def CheckMasterCandidate(debug, ss=None):
403 3f71b464 Guido Trotter
  """Checks the node setup.
404 3f71b464 Guido Trotter

405 3f71b464 Guido Trotter
  If this is a master candidate, the function will return. Otherwise it will
406 3f71b464 Guido Trotter
  exit with an exit code based on the node status.
407 3f71b464 Guido Trotter

408 3f71b464 Guido Trotter
  """
409 3f71b464 Guido Trotter
  try:
410 3f71b464 Guido Trotter
    if ss is None:
411 3f71b464 Guido Trotter
      ss = SimpleStore()
412 3f71b464 Guido Trotter
    myself = utils.HostInfo().name
413 3f71b464 Guido Trotter
    candidates = ss.GetMasterCandidates()
414 3f71b464 Guido Trotter
  except errors.ConfigurationError, err:
415 3f71b464 Guido Trotter
    print "Cluster configuration incomplete: '%s'" % str(err)
416 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
417 3f71b464 Guido Trotter
  except errors.ResolverError, err:
418 3f71b464 Guido Trotter
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
419 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
420 3f71b464 Guido Trotter
421 3f71b464 Guido Trotter
  if myself not in candidates:
422 3f71b464 Guido Trotter
    if debug:
423 3f71b464 Guido Trotter
      sys.stderr.write("Not master candidate, exiting.\n")
424 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NOTCANDIDATE)