Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ 73a465ee

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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