Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ fdad8c4d

History | View | Annotate | Download (14.3 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 69b99987 Michael Hanselmann
61 69b99987 Michael Hanselmann
    self._config_data = None
62 69b99987 Michael Hanselmann
    self._inst_ips_by_link = None
63 cd195419 Guido Trotter
    self._ip_to_inst_by_link = None
64 099c52ad Iustin Pop
    self._instances_ips = None
65 69b99987 Michael Hanselmann
    self._mc_primary_ips = None
66 69b99987 Michael Hanselmann
    self._nodes_primary_ips = None
67 69b99987 Michael Hanselmann
68 7bcc78e4 Guido Trotter
    # we need a forced reload at class init time, to initialize _last_*
69 7bcc78e4 Guido Trotter
    self._Load(force=True)
70 1fe93c75 Guido Trotter
71 7bcc78e4 Guido Trotter
  def _Load(self, force=False):
72 ad8b2f9b Guido Trotter
    """Loads (or reloads) the config file.
73 1fe93c75 Guido Trotter

74 7bcc78e4 Guido Trotter
    @type force: boolean
75 7bcc78e4 Guido Trotter
    @param force: whether to force the reload without checking the mtime
76 7bcc78e4 Guido Trotter
    @rtype: boolean
77 4d4a651d Michael Hanselmann
    @return: boolean value that says whether we reloaded the configuration or
78 4d4a651d Michael Hanselmann
             not (because we decided it was already up-to-date)
79 7bcc78e4 Guido Trotter

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

174 e843991b Guido Trotter
    @type node: string
175 e843991b Guido Trotter
    @param node: node name
176 e843991b Guido Trotter
    @rtype: (bool, bool, bool)
177 e843991b Guido Trotter
    @return: (master_candidate, drained, offline) (or None if no such node)
178 e843991b Guido Trotter

179 e843991b Guido Trotter
    """
180 e843991b Guido Trotter
    if node not in self._config_data["nodes"]:
181 e843991b Guido Trotter
      return None
182 e843991b Guido Trotter
183 e843991b Guido Trotter
    master_candidate = self._config_data["nodes"][node]["master_candidate"]
184 e843991b Guido Trotter
    drained = self._config_data["nodes"][node]["drained"]
185 e843991b Guido Trotter
    offline = self._config_data["nodes"][node]["offline"]
186 e843991b Guido Trotter
    return master_candidate, drained, offline
187 e843991b Guido Trotter
188 cd195419 Guido Trotter
  def GetInstanceByLinkIp(self, ip, link):
189 9d099698 Guido Trotter
    """Get instance name from its link and ip address.
190 9d099698 Guido Trotter

191 9d099698 Guido Trotter
    @type ip: string
192 9d099698 Guido Trotter
    @param ip: ip address
193 9d099698 Guido Trotter
    @type link: string
194 9d099698 Guido Trotter
    @param link: nic link
195 9d099698 Guido Trotter
    @rtype: string
196 9d099698 Guido Trotter
    @return: instance name
197 9d099698 Guido Trotter

198 9d099698 Guido Trotter
    """
199 cd195419 Guido Trotter
    if not link:
200 cd195419 Guido Trotter
      link = self.GetDefaultNicLink()
201 cd195419 Guido Trotter
    if not link in self._ip_to_inst_by_link:
202 ae130c81 Guido Trotter
      return None
203 cd195419 Guido Trotter
    if not ip in self._ip_to_inst_by_link[link]:
204 cd195419 Guido Trotter
      return None
205 cd195419 Guido Trotter
    return self._ip_to_inst_by_link[link][ip]
206 ae130c81 Guido Trotter
207 ae130c81 Guido Trotter
  def GetNodePrimaryIp(self, node):
208 ae130c81 Guido Trotter
    """Get a node's primary ip
209 ae130c81 Guido Trotter

210 ae130c81 Guido Trotter
    @type node: string
211 ae130c81 Guido Trotter
    @param node: node name
212 ae130c81 Guido Trotter
    @rtype: string, or None
213 ae130c81 Guido Trotter
    @return: node's primary ip, or None if no such node
214 ae130c81 Guido Trotter

215 ae130c81 Guido Trotter
    """
216 ae130c81 Guido Trotter
    if node not in self._config_data["nodes"]:
217 ae130c81 Guido Trotter
      return None
218 ae130c81 Guido Trotter
    return self._config_data["nodes"][node]["primary_ip"]
219 ae130c81 Guido Trotter
220 ae130c81 Guido Trotter
  def GetInstancePrimaryNode(self, instance):
221 ae130c81 Guido Trotter
    """Get an instance's primary node
222 ae130c81 Guido Trotter

223 ae130c81 Guido Trotter
    @type instance: string
224 ae130c81 Guido Trotter
    @param instance: instance name
225 ae130c81 Guido Trotter
    @rtype: string, or None
226 ae130c81 Guido Trotter
    @return: primary node, or None if no such instance
227 ae130c81 Guido Trotter

228 ae130c81 Guido Trotter
    """
229 ae130c81 Guido Trotter
    if instance not in self._config_data["instances"]:
230 ae130c81 Guido Trotter
      return None
231 ae130c81 Guido Trotter
    return self._config_data["instances"][instance]["primary_node"]
232 ae130c81 Guido Trotter
233 efbb4fd2 Luca Bigliardi
  def GetNodesPrimaryIps(self):
234 efbb4fd2 Luca Bigliardi
    return self._nodes_primary_ips
235 efbb4fd2 Luca Bigliardi
236 efbb4fd2 Luca Bigliardi
  def GetMasterCandidatesPrimaryIps(self):
237 efbb4fd2 Luca Bigliardi
    return self._mc_primary_ips
238 efbb4fd2 Luca Bigliardi
239 23824641 Luca Bigliardi
  def GetInstancesIps(self, link):
240 9d099698 Guido Trotter
    """Get list of nic ips connected to a certain link.
241 9d099698 Guido Trotter

242 9d099698 Guido Trotter
    @type link: string
243 9d099698 Guido Trotter
    @param link: nic link
244 9d099698 Guido Trotter
    @rtype: list
245 9d099698 Guido Trotter
    @return: list of ips connected to that link
246 9d099698 Guido Trotter

247 9d099698 Guido Trotter
    """
248 cd195419 Guido Trotter
    if not link:
249 cd195419 Guido Trotter
      link = self.GetDefaultNicLink()
250 cd195419 Guido Trotter
251 23824641 Luca Bigliardi
    if link in self._inst_ips_by_link:
252 23824641 Luca Bigliardi
      return self._inst_ips_by_link[link]
253 23824641 Luca Bigliardi
    else:
254 23824641 Luca Bigliardi
      return []
255 d01ae714 Luca Bigliardi
256 856c67e1 Michael Hanselmann
257 93384844 Iustin Pop
class SimpleStore(object):
258 93384844 Iustin Pop
  """Interface to static cluster data.
259 93384844 Iustin Pop

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

264 93384844 Iustin Pop
  Other particularities of the datastore:
265 93384844 Iustin Pop
    - keys are restricted to predefined values
266 93384844 Iustin Pop

267 93384844 Iustin Pop
  """
268 93384844 Iustin Pop
  _SS_FILEPREFIX = "ssconf_"
269 93384844 Iustin Pop
  _VALID_KEYS = (
270 93384844 Iustin Pop
    constants.SS_CLUSTER_NAME,
271 5d60b3bd Iustin Pop
    constants.SS_CLUSTER_TAGS,
272 93384844 Iustin Pop
    constants.SS_FILE_STORAGE_DIR,
273 f56618e0 Iustin Pop
    constants.SS_MASTER_CANDIDATES,
274 8113a52e Luca Bigliardi
    constants.SS_MASTER_CANDIDATES_IPS,
275 93384844 Iustin Pop
    constants.SS_MASTER_IP,
276 93384844 Iustin Pop
    constants.SS_MASTER_NETDEV,
277 93384844 Iustin Pop
    constants.SS_MASTER_NODE,
278 93384844 Iustin Pop
    constants.SS_NODE_LIST,
279 f9780ccd Luca Bigliardi
    constants.SS_NODE_PRIMARY_IPS,
280 f9780ccd Luca Bigliardi
    constants.SS_NODE_SECONDARY_IPS,
281 a3316e4a Iustin Pop
    constants.SS_OFFLINE_NODES,
282 81a49123 Iustin Pop
    constants.SS_ONLINE_NODES,
283 81a49123 Iustin Pop
    constants.SS_INSTANCE_LIST,
284 8a113c7a Iustin Pop
    constants.SS_RELEASE_VERSION,
285 4f7a6a10 Iustin Pop
    constants.SS_HYPERVISOR_LIST,
286 5c465a95 Iustin Pop
    constants.SS_MAINTAIN_NODE_HEALTH,
287 93384844 Iustin Pop
    )
288 93384844 Iustin Pop
  _MAX_SIZE = 131072
289 93384844 Iustin Pop
290 93384844 Iustin Pop
  def __init__(self, cfg_location=None):
291 93384844 Iustin Pop
    if cfg_location is None:
292 93384844 Iustin Pop
      self._cfg_dir = constants.DATA_DIR
293 93384844 Iustin Pop
    else:
294 93384844 Iustin Pop
      self._cfg_dir = cfg_location
295 93384844 Iustin Pop
296 93384844 Iustin Pop
  def KeyToFilename(self, key):
297 93384844 Iustin Pop
    """Convert a given key into filename.
298 93384844 Iustin Pop

299 93384844 Iustin Pop
    """
300 93384844 Iustin Pop
    if key not in self._VALID_KEYS:
301 93384844 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
302 93384844 Iustin Pop
                                   % str(key))
303 93384844 Iustin Pop
304 93384844 Iustin Pop
    filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
305 93384844 Iustin Pop
    return filename
306 93384844 Iustin Pop
307 93384844 Iustin Pop
  def _ReadFile(self, key):
308 93384844 Iustin Pop
    """Generic routine to read keys.
309 93384844 Iustin Pop

310 93384844 Iustin Pop
    This will read the file which holds the value requested. Errors
311 93384844 Iustin Pop
    will be changed into ConfigurationErrors.
312 93384844 Iustin Pop

313 93384844 Iustin Pop
    """
314 93384844 Iustin Pop
    filename = self.KeyToFilename(key)
315 93384844 Iustin Pop
    try:
316 920b5878 Guido Trotter
      data = utils.ReadFile(filename, size=self._MAX_SIZE)
317 93384844 Iustin Pop
    except EnvironmentError, err:
318 93384844 Iustin Pop
      raise errors.ConfigurationError("Can't read from the ssconf file:"
319 93384844 Iustin Pop
                                      " '%s'" % str(err))
320 920b5878 Guido Trotter
    data = data.rstrip('\n')
321 93384844 Iustin Pop
    return data
322 93384844 Iustin Pop
323 89b14f05 Iustin Pop
  def WriteFiles(self, values):
324 89b14f05 Iustin Pop
    """Writes ssconf files used by external scripts.
325 89b14f05 Iustin Pop

326 89b14f05 Iustin Pop
    @type values: dict
327 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
328 89b14f05 Iustin Pop

329 89b14f05 Iustin Pop
    """
330 b4478d34 Michael Hanselmann
    ssconf_lock = utils.FileLock.Open(constants.SSCONF_LOCK_FILE)
331 89b14f05 Iustin Pop
332 89b14f05 Iustin Pop
    # Get lock while writing files
333 89b14f05 Iustin Pop
    ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
334 89b14f05 Iustin Pop
    try:
335 89b14f05 Iustin Pop
      for name, value in values.iteritems():
336 02b31f32 Iustin Pop
        if value and not value.endswith("\n"):
337 89b14f05 Iustin Pop
          value += "\n"
338 81a49123 Iustin Pop
        utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444)
339 89b14f05 Iustin Pop
    finally:
340 89b14f05 Iustin Pop
      ssconf_lock.Unlock()
341 89b14f05 Iustin Pop
342 93384844 Iustin Pop
  def GetFileList(self):
343 93384844 Iustin Pop
    """Return the list of all config files.
344 93384844 Iustin Pop

345 93384844 Iustin Pop
    This is used for computing node replication data.
346 93384844 Iustin Pop

347 93384844 Iustin Pop
    """
348 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
349 93384844 Iustin Pop
350 93384844 Iustin Pop
  def GetClusterName(self):
351 93384844 Iustin Pop
    """Get the cluster name.
352 93384844 Iustin Pop

353 93384844 Iustin Pop
    """
354 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
355 93384844 Iustin Pop
356 93384844 Iustin Pop
  def GetFileStorageDir(self):
357 93384844 Iustin Pop
    """Get the file storage dir.
358 93384844 Iustin Pop

359 93384844 Iustin Pop
    """
360 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
361 93384844 Iustin Pop
362 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
363 f56618e0 Iustin Pop
    """Return the list of master candidates.
364 f56618e0 Iustin Pop

365 f56618e0 Iustin Pop
    """
366 f56618e0 Iustin Pop
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES)
367 f56618e0 Iustin Pop
    nl = data.splitlines(False)
368 f56618e0 Iustin Pop
    return nl
369 f56618e0 Iustin Pop
370 8113a52e Luca Bigliardi
  def GetMasterCandidatesIPList(self):
371 8113a52e Luca Bigliardi
    """Return the list of master candidates' primary IP.
372 8113a52e Luca Bigliardi

373 8113a52e Luca Bigliardi
    """
374 8113a52e Luca Bigliardi
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES_IPS)
375 8113a52e Luca Bigliardi
    nl = data.splitlines(False)
376 8113a52e Luca Bigliardi
    return nl
377 8113a52e Luca Bigliardi
378 93384844 Iustin Pop
  def GetMasterIP(self):
379 93384844 Iustin Pop
    """Get the IP of the master node for this cluster.
380 93384844 Iustin Pop

381 93384844 Iustin Pop
    """
382 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
383 93384844 Iustin Pop
384 93384844 Iustin Pop
  def GetMasterNetdev(self):
385 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
386 93384844 Iustin Pop

387 93384844 Iustin Pop
    """
388 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
389 93384844 Iustin Pop
390 93384844 Iustin Pop
  def GetMasterNode(self):
391 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
392 93384844 Iustin Pop

393 93384844 Iustin Pop
    """
394 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
395 93384844 Iustin Pop
396 93384844 Iustin Pop
  def GetNodeList(self):
397 93384844 Iustin Pop
    """Return the list of cluster nodes.
398 93384844 Iustin Pop

399 93384844 Iustin Pop
    """
400 93384844 Iustin Pop
    data = self._ReadFile(constants.SS_NODE_LIST)
401 93384844 Iustin Pop
    nl = data.splitlines(False)
402 93384844 Iustin Pop
    return nl
403 93384844 Iustin Pop
404 f9780ccd Luca Bigliardi
  def GetNodePrimaryIPList(self):
405 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' primary IP.
406 f9780ccd Luca Bigliardi

407 f9780ccd Luca Bigliardi
    """
408 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_PRIMARY_IPS)
409 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
410 f9780ccd Luca Bigliardi
    return nl
411 f9780ccd Luca Bigliardi
412 f9780ccd Luca Bigliardi
  def GetNodeSecondaryIPList(self):
413 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' secondary IP.
414 f9780ccd Luca Bigliardi

415 f9780ccd Luca Bigliardi
    """
416 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
417 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
418 f9780ccd Luca Bigliardi
    return nl
419 f9780ccd Luca Bigliardi
420 25e39bfa Iustin Pop
  def GetClusterTags(self):
421 25e39bfa Iustin Pop
    """Return the cluster tags.
422 25e39bfa Iustin Pop

423 25e39bfa Iustin Pop
    """
424 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
425 25e39bfa Iustin Pop
    nl = data.splitlines(False)
426 25e39bfa Iustin Pop
    return nl
427 25e39bfa Iustin Pop
428 4f7a6a10 Iustin Pop
  def GetHypervisorList(self):
429 4f7a6a10 Iustin Pop
    """Return the list of enabled hypervisors.
430 4f7a6a10 Iustin Pop

431 4f7a6a10 Iustin Pop
    """
432 4f7a6a10 Iustin Pop
    data = self._ReadFile(constants.SS_HYPERVISOR_LIST)
433 4f7a6a10 Iustin Pop
    nl = data.splitlines(False)
434 4f7a6a10 Iustin Pop
    return nl
435 4f7a6a10 Iustin Pop
436 5c465a95 Iustin Pop
  def GetMaintainNodeHealth(self):
437 5c465a95 Iustin Pop
    """Return the value of the maintain_node_health option.
438 5c465a95 Iustin Pop

439 5c465a95 Iustin Pop
    """
440 5c465a95 Iustin Pop
    data = self._ReadFile(constants.SS_MAINTAIN_NODE_HEALTH)
441 5c465a95 Iustin Pop
    # we rely on the bool serialization here
442 5c465a95 Iustin Pop
    return data == "True"
443 5c465a95 Iustin Pop
444 93384844 Iustin Pop
445 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
446 b33e986b Iustin Pop
  """Get the master node and my own hostname.
447 b33e986b Iustin Pop

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

451 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
452 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
453 b33e986b Iustin Pop

454 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
455 8135a2db Iustin Pop
      sstore.SimpleStore instance
456 8135a2db Iustin Pop
  @rtype: tuple
457 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
458 8135a2db Iustin Pop

459 b33e986b Iustin Pop
  """
460 b33e986b Iustin Pop
  if ss is None:
461 93384844 Iustin Pop
    ss = SimpleStore()
462 b33e986b Iustin Pop
  return ss.GetMasterNode(), utils.HostInfo().name
463 b33e986b Iustin Pop
464 06dc5b44 Iustin Pop
465 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
466 5675cd1f Iustin Pop
  """Checks the node setup.
467 5675cd1f Iustin Pop

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

471 5675cd1f Iustin Pop
  """
472 5675cd1f Iustin Pop
  try:
473 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
474 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
475 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
476 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
477 5675cd1f Iustin Pop
  except errors.ResolverError, err:
478 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
479 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
480 5675cd1f Iustin Pop
481 b33e986b Iustin Pop
  if myself != master_name:
482 5675cd1f Iustin Pop
    if debug:
483 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
484 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)
485 3f71b464 Guido Trotter
486 3f71b464 Guido Trotter
487 3f71b464 Guido Trotter
def CheckMasterCandidate(debug, ss=None):
488 3f71b464 Guido Trotter
  """Checks the node setup.
489 3f71b464 Guido Trotter

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

493 3f71b464 Guido Trotter
  """
494 3f71b464 Guido Trotter
  try:
495 3f71b464 Guido Trotter
    if ss is None:
496 3f71b464 Guido Trotter
      ss = SimpleStore()
497 3f71b464 Guido Trotter
    myself = utils.HostInfo().name
498 3f71b464 Guido Trotter
    candidates = ss.GetMasterCandidates()
499 3f71b464 Guido Trotter
  except errors.ConfigurationError, err:
500 3f71b464 Guido Trotter
    print "Cluster configuration incomplete: '%s'" % str(err)
501 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
502 3f71b464 Guido Trotter
  except errors.ResolverError, err:
503 3f71b464 Guido Trotter
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
504 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
505 3f71b464 Guido Trotter
506 3f71b464 Guido Trotter
  if myself not in candidates:
507 3f71b464 Guido Trotter
    if debug:
508 3f71b464 Guido Trotter
      sys.stderr.write("Not master candidate, exiting.\n")
509 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NOTCANDIDATE)