Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ 84e344d4

History | View | Annotate | Download (12.9 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 23824641 Luca Bigliardi
from ganeti import objects
38 a8083063 Iustin Pop
39 a8083063 Iustin Pop
40 0c223ea9 Michael Hanselmann
SSCONF_LOCK_TIMEOUT = 10
41 0c223ea9 Michael Hanselmann
42 03d1dba2 Michael Hanselmann
RE_VALID_SSCONF_NAME = re.compile(r'^[-_a-z0-9]+$')
43 03d1dba2 Michael Hanselmann
44 0c223ea9 Michael Hanselmann
45 02f99608 Oleksiy Mishchenko
class SimpleConfigReader(object):
46 856c67e1 Michael Hanselmann
  """Simple class to read configuration file.
47 856c67e1 Michael Hanselmann

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

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

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

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

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

162 e843991b Guido Trotter
    @type node: string
163 e843991b Guido Trotter
    @param node: node name
164 e843991b Guido Trotter
    @rtype: (bool, bool, bool)
165 e843991b Guido Trotter
    @return: (master_candidate, drained, offline) (or None if no such node)
166 e843991b Guido Trotter

167 e843991b Guido Trotter
    """
168 e843991b Guido Trotter
    if node not in self._config_data["nodes"]:
169 e843991b Guido Trotter
      return None
170 e843991b Guido Trotter
171 e843991b Guido Trotter
    master_candidate = self._config_data["nodes"][node]["master_candidate"]
172 e843991b Guido Trotter
    drained = self._config_data["nodes"][node]["drained"]
173 e843991b Guido Trotter
    offline = self._config_data["nodes"][node]["offline"]
174 e843991b Guido Trotter
    return master_candidate, drained, offline
175 e843991b Guido Trotter
176 ae130c81 Guido Trotter
  def GetInstanceByIp(self, ip):
177 ae130c81 Guido Trotter
    if ip not in self._ip_to_instance:
178 ae130c81 Guido Trotter
      return None
179 ae130c81 Guido Trotter
    return self._ip_to_instance[ip]
180 ae130c81 Guido Trotter
181 ae130c81 Guido Trotter
  def GetNodePrimaryIp(self, node):
182 ae130c81 Guido Trotter
    """Get a node's primary ip
183 ae130c81 Guido Trotter

184 ae130c81 Guido Trotter
    @type node: string
185 ae130c81 Guido Trotter
    @param node: node name
186 ae130c81 Guido Trotter
    @rtype: string, or None
187 ae130c81 Guido Trotter
    @return: node's primary ip, or None if no such node
188 ae130c81 Guido Trotter

189 ae130c81 Guido Trotter
    """
190 ae130c81 Guido Trotter
    if node not in self._config_data["nodes"]:
191 ae130c81 Guido Trotter
      return None
192 ae130c81 Guido Trotter
    return self._config_data["nodes"][node]["primary_ip"]
193 ae130c81 Guido Trotter
194 ae130c81 Guido Trotter
  def GetInstancePrimaryNode(self, instance):
195 ae130c81 Guido Trotter
    """Get an instance's primary node
196 ae130c81 Guido Trotter

197 ae130c81 Guido Trotter
    @type instance: string
198 ae130c81 Guido Trotter
    @param instance: instance name
199 ae130c81 Guido Trotter
    @rtype: string, or None
200 ae130c81 Guido Trotter
    @return: primary node, or None if no such instance
201 ae130c81 Guido Trotter

202 ae130c81 Guido Trotter
    """
203 ae130c81 Guido Trotter
    if instance not in self._config_data["instances"]:
204 ae130c81 Guido Trotter
      return None
205 ae130c81 Guido Trotter
    return self._config_data["instances"][instance]["primary_node"]
206 ae130c81 Guido Trotter
207 efbb4fd2 Luca Bigliardi
  def GetNodesPrimaryIps(self):
208 efbb4fd2 Luca Bigliardi
    return self._nodes_primary_ips
209 efbb4fd2 Luca Bigliardi
210 efbb4fd2 Luca Bigliardi
  def GetMasterCandidatesPrimaryIps(self):
211 efbb4fd2 Luca Bigliardi
    return self._mc_primary_ips
212 efbb4fd2 Luca Bigliardi
213 23824641 Luca Bigliardi
  def GetInstancesIps(self, link):
214 23824641 Luca Bigliardi
    if link is None:
215 23824641 Luca Bigliardi
      return self._instances_ips
216 23824641 Luca Bigliardi
    if link in self._inst_ips_by_link:
217 23824641 Luca Bigliardi
      return self._inst_ips_by_link[link]
218 23824641 Luca Bigliardi
    else:
219 23824641 Luca Bigliardi
      return []
220 d01ae714 Luca Bigliardi
221 856c67e1 Michael Hanselmann
222 93384844 Iustin Pop
class SimpleStore(object):
223 93384844 Iustin Pop
  """Interface to static cluster data.
224 93384844 Iustin Pop

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

229 93384844 Iustin Pop
  Other particularities of the datastore:
230 93384844 Iustin Pop
    - keys are restricted to predefined values
231 93384844 Iustin Pop

232 93384844 Iustin Pop
  """
233 93384844 Iustin Pop
  _SS_FILEPREFIX = "ssconf_"
234 93384844 Iustin Pop
  _VALID_KEYS = (
235 93384844 Iustin Pop
    constants.SS_CLUSTER_NAME,
236 5d60b3bd Iustin Pop
    constants.SS_CLUSTER_TAGS,
237 93384844 Iustin Pop
    constants.SS_FILE_STORAGE_DIR,
238 f56618e0 Iustin Pop
    constants.SS_MASTER_CANDIDATES,
239 8113a52e Luca Bigliardi
    constants.SS_MASTER_CANDIDATES_IPS,
240 93384844 Iustin Pop
    constants.SS_MASTER_IP,
241 93384844 Iustin Pop
    constants.SS_MASTER_NETDEV,
242 93384844 Iustin Pop
    constants.SS_MASTER_NODE,
243 93384844 Iustin Pop
    constants.SS_NODE_LIST,
244 f9780ccd Luca Bigliardi
    constants.SS_NODE_PRIMARY_IPS,
245 f9780ccd Luca Bigliardi
    constants.SS_NODE_SECONDARY_IPS,
246 a3316e4a Iustin Pop
    constants.SS_OFFLINE_NODES,
247 81a49123 Iustin Pop
    constants.SS_ONLINE_NODES,
248 81a49123 Iustin Pop
    constants.SS_INSTANCE_LIST,
249 8a113c7a Iustin Pop
    constants.SS_RELEASE_VERSION,
250 93384844 Iustin Pop
    )
251 93384844 Iustin Pop
  _MAX_SIZE = 131072
252 93384844 Iustin Pop
253 93384844 Iustin Pop
  def __init__(self, cfg_location=None):
254 93384844 Iustin Pop
    if cfg_location is None:
255 93384844 Iustin Pop
      self._cfg_dir = constants.DATA_DIR
256 93384844 Iustin Pop
    else:
257 93384844 Iustin Pop
      self._cfg_dir = cfg_location
258 93384844 Iustin Pop
259 93384844 Iustin Pop
  def KeyToFilename(self, key):
260 93384844 Iustin Pop
    """Convert a given key into filename.
261 93384844 Iustin Pop

262 93384844 Iustin Pop
    """
263 93384844 Iustin Pop
    if key not in self._VALID_KEYS:
264 93384844 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
265 93384844 Iustin Pop
                                   % str(key))
266 93384844 Iustin Pop
267 93384844 Iustin Pop
    filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
268 93384844 Iustin Pop
    return filename
269 93384844 Iustin Pop
270 93384844 Iustin Pop
  def _ReadFile(self, key):
271 93384844 Iustin Pop
    """Generic routine to read keys.
272 93384844 Iustin Pop

273 93384844 Iustin Pop
    This will read the file which holds the value requested. Errors
274 93384844 Iustin Pop
    will be changed into ConfigurationErrors.
275 93384844 Iustin Pop

276 93384844 Iustin Pop
    """
277 93384844 Iustin Pop
    filename = self.KeyToFilename(key)
278 93384844 Iustin Pop
    try:
279 920b5878 Guido Trotter
      data = utils.ReadFile(filename, size=self._MAX_SIZE)
280 93384844 Iustin Pop
    except EnvironmentError, err:
281 93384844 Iustin Pop
      raise errors.ConfigurationError("Can't read from the ssconf file:"
282 93384844 Iustin Pop
                                      " '%s'" % str(err))
283 920b5878 Guido Trotter
    data = data.rstrip('\n')
284 93384844 Iustin Pop
    return data
285 93384844 Iustin Pop
286 89b14f05 Iustin Pop
  def WriteFiles(self, values):
287 89b14f05 Iustin Pop
    """Writes ssconf files used by external scripts.
288 89b14f05 Iustin Pop

289 89b14f05 Iustin Pop
    @type values: dict
290 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
291 89b14f05 Iustin Pop

292 89b14f05 Iustin Pop
    """
293 89b14f05 Iustin Pop
    ssconf_lock = utils.FileLock(constants.SSCONF_LOCK_FILE)
294 89b14f05 Iustin Pop
295 89b14f05 Iustin Pop
    # Get lock while writing files
296 89b14f05 Iustin Pop
    ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
297 89b14f05 Iustin Pop
    try:
298 89b14f05 Iustin Pop
      for name, value in values.iteritems():
299 02b31f32 Iustin Pop
        if value and not value.endswith("\n"):
300 89b14f05 Iustin Pop
          value += "\n"
301 81a49123 Iustin Pop
        utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444)
302 89b14f05 Iustin Pop
    finally:
303 89b14f05 Iustin Pop
      ssconf_lock.Unlock()
304 89b14f05 Iustin Pop
305 93384844 Iustin Pop
  def GetFileList(self):
306 93384844 Iustin Pop
    """Return the list of all config files.
307 93384844 Iustin Pop

308 93384844 Iustin Pop
    This is used for computing node replication data.
309 93384844 Iustin Pop

310 93384844 Iustin Pop
    """
311 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
312 93384844 Iustin Pop
313 93384844 Iustin Pop
  def GetClusterName(self):
314 93384844 Iustin Pop
    """Get the cluster name.
315 93384844 Iustin Pop

316 93384844 Iustin Pop
    """
317 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
318 93384844 Iustin Pop
319 93384844 Iustin Pop
  def GetFileStorageDir(self):
320 93384844 Iustin Pop
    """Get the file storage dir.
321 93384844 Iustin Pop

322 93384844 Iustin Pop
    """
323 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
324 93384844 Iustin Pop
325 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
326 f56618e0 Iustin Pop
    """Return the list of master candidates.
327 f56618e0 Iustin Pop

328 f56618e0 Iustin Pop
    """
329 f56618e0 Iustin Pop
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES)
330 f56618e0 Iustin Pop
    nl = data.splitlines(False)
331 f56618e0 Iustin Pop
    return nl
332 f56618e0 Iustin Pop
333 8113a52e Luca Bigliardi
  def GetMasterCandidatesIPList(self):
334 8113a52e Luca Bigliardi
    """Return the list of master candidates' primary IP.
335 8113a52e Luca Bigliardi

336 8113a52e Luca Bigliardi
    """
337 8113a52e Luca Bigliardi
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES_IPS)
338 8113a52e Luca Bigliardi
    nl = data.splitlines(False)
339 8113a52e Luca Bigliardi
    return nl
340 8113a52e Luca Bigliardi
341 93384844 Iustin Pop
  def GetMasterIP(self):
342 93384844 Iustin Pop
    """Get the IP of the master node for this cluster.
343 93384844 Iustin Pop

344 93384844 Iustin Pop
    """
345 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
346 93384844 Iustin Pop
347 93384844 Iustin Pop
  def GetMasterNetdev(self):
348 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
349 93384844 Iustin Pop

350 93384844 Iustin Pop
    """
351 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
352 93384844 Iustin Pop
353 93384844 Iustin Pop
  def GetMasterNode(self):
354 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
355 93384844 Iustin Pop

356 93384844 Iustin Pop
    """
357 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
358 93384844 Iustin Pop
359 93384844 Iustin Pop
  def GetNodeList(self):
360 93384844 Iustin Pop
    """Return the list of cluster nodes.
361 93384844 Iustin Pop

362 93384844 Iustin Pop
    """
363 93384844 Iustin Pop
    data = self._ReadFile(constants.SS_NODE_LIST)
364 93384844 Iustin Pop
    nl = data.splitlines(False)
365 93384844 Iustin Pop
    return nl
366 93384844 Iustin Pop
367 f9780ccd Luca Bigliardi
  def GetNodePrimaryIPList(self):
368 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' primary IP.
369 f9780ccd Luca Bigliardi

370 f9780ccd Luca Bigliardi
    """
371 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_PRIMARY_IPS)
372 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
373 f9780ccd Luca Bigliardi
    return nl
374 f9780ccd Luca Bigliardi
375 f9780ccd Luca Bigliardi
  def GetNodeSecondaryIPList(self):
376 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' secondary IP.
377 f9780ccd Luca Bigliardi

378 f9780ccd Luca Bigliardi
    """
379 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
380 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
381 f9780ccd Luca Bigliardi
    return nl
382 f9780ccd Luca Bigliardi
383 25e39bfa Iustin Pop
  def GetClusterTags(self):
384 25e39bfa Iustin Pop
    """Return the cluster tags.
385 25e39bfa Iustin Pop

386 25e39bfa Iustin Pop
    """
387 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
388 25e39bfa Iustin Pop
    nl = data.splitlines(False)
389 25e39bfa Iustin Pop
    return nl
390 25e39bfa Iustin Pop
391 93384844 Iustin Pop
392 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
393 b33e986b Iustin Pop
  """Get the master node and my own hostname.
394 b33e986b Iustin Pop

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

398 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
399 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
400 b33e986b Iustin Pop

401 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
402 8135a2db Iustin Pop
      sstore.SimpleStore instance
403 8135a2db Iustin Pop
  @rtype: tuple
404 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
405 8135a2db Iustin Pop

406 b33e986b Iustin Pop
  """
407 b33e986b Iustin Pop
  if ss is None:
408 93384844 Iustin Pop
    ss = SimpleStore()
409 b33e986b Iustin Pop
  return ss.GetMasterNode(), utils.HostInfo().name
410 b33e986b Iustin Pop
411 06dc5b44 Iustin Pop
412 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
413 5675cd1f Iustin Pop
  """Checks the node setup.
414 5675cd1f Iustin Pop

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

418 5675cd1f Iustin Pop
  """
419 5675cd1f Iustin Pop
  try:
420 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
421 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
422 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
423 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
424 5675cd1f Iustin Pop
  except errors.ResolverError, err:
425 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
426 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
427 5675cd1f Iustin Pop
428 b33e986b Iustin Pop
  if myself != master_name:
429 5675cd1f Iustin Pop
    if debug:
430 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
431 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)
432 3f71b464 Guido Trotter
433 3f71b464 Guido Trotter
434 3f71b464 Guido Trotter
def CheckMasterCandidate(debug, ss=None):
435 3f71b464 Guido Trotter
  """Checks the node setup.
436 3f71b464 Guido Trotter

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

440 3f71b464 Guido Trotter
  """
441 3f71b464 Guido Trotter
  try:
442 3f71b464 Guido Trotter
    if ss is None:
443 3f71b464 Guido Trotter
      ss = SimpleStore()
444 3f71b464 Guido Trotter
    myself = utils.HostInfo().name
445 3f71b464 Guido Trotter
    candidates = ss.GetMasterCandidates()
446 3f71b464 Guido Trotter
  except errors.ConfigurationError, err:
447 3f71b464 Guido Trotter
    print "Cluster configuration incomplete: '%s'" % str(err)
448 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
449 3f71b464 Guido Trotter
  except errors.ResolverError, err:
450 3f71b464 Guido Trotter
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
451 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
452 3f71b464 Guido Trotter
453 3f71b464 Guido Trotter
  if myself not in candidates:
454 3f71b464 Guido Trotter
    if debug:
455 3f71b464 Guido Trotter
      sys.stderr.write("Not master candidate, exiting.\n")
456 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NOTCANDIDATE)