Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ 66e884e1

History | View | Annotate | Download (14.9 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 b705c7a6 Manuel Franceschini
# Copyright (C) 2006, 2007, 2008, 2010 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 7dd999fc Manuel Franceschini
import errno
33 a8083063 Iustin Pop
34 a8083063 Iustin Pop
from ganeti import errors
35 a8083063 Iustin Pop
from ganeti import constants
36 41a57aab Michael Hanselmann
from ganeti import utils
37 856c67e1 Michael Hanselmann
from ganeti import serializer
38 23824641 Luca Bigliardi
from ganeti import objects
39 a744b676 Manuel Franceschini
from ganeti import netutils
40 a8083063 Iustin Pop
41 a8083063 Iustin Pop
42 0c223ea9 Michael Hanselmann
SSCONF_LOCK_TIMEOUT = 10
43 0c223ea9 Michael Hanselmann
44 03d1dba2 Michael Hanselmann
RE_VALID_SSCONF_NAME = re.compile(r'^[-_a-z0-9]+$')
45 03d1dba2 Michael Hanselmann
46 0c223ea9 Michael Hanselmann
47 02f99608 Oleksiy Mishchenko
class SimpleConfigReader(object):
48 856c67e1 Michael Hanselmann
  """Simple class to read configuration file.
49 856c67e1 Michael Hanselmann

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

54 856c67e1 Michael Hanselmann
    @type file_name: string
55 856c67e1 Michael Hanselmann
    @param file_name: Configuration file path
56 856c67e1 Michael Hanselmann

57 856c67e1 Michael Hanselmann
    """
58 856c67e1 Michael Hanselmann
    self._file_name = file_name
59 7bcc78e4 Guido Trotter
    self._last_inode = None
60 7bcc78e4 Guido Trotter
    self._last_mtime = None
61 7bcc78e4 Guido Trotter
    self._last_size = None
62 69b99987 Michael Hanselmann
63 69b99987 Michael Hanselmann
    self._config_data = None
64 69b99987 Michael Hanselmann
    self._inst_ips_by_link = None
65 cd195419 Guido Trotter
    self._ip_to_inst_by_link = None
66 099c52ad Iustin Pop
    self._instances_ips = None
67 69b99987 Michael Hanselmann
    self._mc_primary_ips = None
68 69b99987 Michael Hanselmann
    self._nodes_primary_ips = None
69 69b99987 Michael Hanselmann
70 7bcc78e4 Guido Trotter
    # we need a forced reload at class init time, to initialize _last_*
71 7bcc78e4 Guido Trotter
    self._Load(force=True)
72 1fe93c75 Guido Trotter
73 7bcc78e4 Guido Trotter
  def _Load(self, force=False):
74 ad8b2f9b Guido Trotter
    """Loads (or reloads) the config file.
75 1fe93c75 Guido Trotter

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

304 93384844 Iustin Pop
    """
305 93384844 Iustin Pop
    if key not in self._VALID_KEYS:
306 93384844 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
307 93384844 Iustin Pop
                                   % str(key))
308 93384844 Iustin Pop
309 93384844 Iustin Pop
    filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
310 93384844 Iustin Pop
    return filename
311 93384844 Iustin Pop
312 7dd999fc Manuel Franceschini
  def _ReadFile(self, key, default=None):
313 93384844 Iustin Pop
    """Generic routine to read keys.
314 93384844 Iustin Pop

315 93384844 Iustin Pop
    This will read the file which holds the value requested. Errors
316 93384844 Iustin Pop
    will be changed into ConfigurationErrors.
317 93384844 Iustin Pop

318 93384844 Iustin Pop
    """
319 93384844 Iustin Pop
    filename = self.KeyToFilename(key)
320 93384844 Iustin Pop
    try:
321 920b5878 Guido Trotter
      data = utils.ReadFile(filename, size=self._MAX_SIZE)
322 93384844 Iustin Pop
    except EnvironmentError, err:
323 7dd999fc Manuel Franceschini
      if err.errno == errno.ENOENT and default is not None:
324 7dd999fc Manuel Franceschini
        return default
325 93384844 Iustin Pop
      raise errors.ConfigurationError("Can't read from the ssconf file:"
326 93384844 Iustin Pop
                                      " '%s'" % str(err))
327 920b5878 Guido Trotter
    data = data.rstrip('\n')
328 93384844 Iustin Pop
    return data
329 93384844 Iustin Pop
330 89b14f05 Iustin Pop
  def WriteFiles(self, values):
331 89b14f05 Iustin Pop
    """Writes ssconf files used by external scripts.
332 89b14f05 Iustin Pop

333 89b14f05 Iustin Pop
    @type values: dict
334 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
335 89b14f05 Iustin Pop

336 89b14f05 Iustin Pop
    """
337 b4478d34 Michael Hanselmann
    ssconf_lock = utils.FileLock.Open(constants.SSCONF_LOCK_FILE)
338 89b14f05 Iustin Pop
339 89b14f05 Iustin Pop
    # Get lock while writing files
340 89b14f05 Iustin Pop
    ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
341 89b14f05 Iustin Pop
    try:
342 89b14f05 Iustin Pop
      for name, value in values.iteritems():
343 02b31f32 Iustin Pop
        if value and not value.endswith("\n"):
344 89b14f05 Iustin Pop
          value += "\n"
345 999847c8 Guido Trotter
        if len(value) > self._MAX_SIZE:
346 999847c8 Guido Trotter
          raise errors.ConfigurationError("ssconf file %s above maximum size" %
347 999847c8 Guido Trotter
                                          name)
348 81a49123 Iustin Pop
        utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444)
349 89b14f05 Iustin Pop
    finally:
350 89b14f05 Iustin Pop
      ssconf_lock.Unlock()
351 89b14f05 Iustin Pop
352 93384844 Iustin Pop
  def GetFileList(self):
353 93384844 Iustin Pop
    """Return the list of all config files.
354 93384844 Iustin Pop

355 93384844 Iustin Pop
    This is used for computing node replication data.
356 93384844 Iustin Pop

357 93384844 Iustin Pop
    """
358 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
359 93384844 Iustin Pop
360 93384844 Iustin Pop
  def GetClusterName(self):
361 93384844 Iustin Pop
    """Get the cluster name.
362 93384844 Iustin Pop

363 93384844 Iustin Pop
    """
364 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
365 93384844 Iustin Pop
366 93384844 Iustin Pop
  def GetFileStorageDir(self):
367 93384844 Iustin Pop
    """Get the file storage dir.
368 93384844 Iustin Pop

369 93384844 Iustin Pop
    """
370 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
371 93384844 Iustin Pop
372 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
373 f56618e0 Iustin Pop
    """Return the list of master candidates.
374 f56618e0 Iustin Pop

375 f56618e0 Iustin Pop
    """
376 f56618e0 Iustin Pop
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES)
377 f56618e0 Iustin Pop
    nl = data.splitlines(False)
378 f56618e0 Iustin Pop
    return nl
379 f56618e0 Iustin Pop
380 8113a52e Luca Bigliardi
  def GetMasterCandidatesIPList(self):
381 8113a52e Luca Bigliardi
    """Return the list of master candidates' primary IP.
382 8113a52e Luca Bigliardi

383 8113a52e Luca Bigliardi
    """
384 8113a52e Luca Bigliardi
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES_IPS)
385 8113a52e Luca Bigliardi
    nl = data.splitlines(False)
386 8113a52e Luca Bigliardi
    return nl
387 8113a52e Luca Bigliardi
388 93384844 Iustin Pop
  def GetMasterIP(self):
389 93384844 Iustin Pop
    """Get the IP of the master node for this cluster.
390 93384844 Iustin Pop

391 93384844 Iustin Pop
    """
392 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
393 93384844 Iustin Pop
394 93384844 Iustin Pop
  def GetMasterNetdev(self):
395 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
396 93384844 Iustin Pop

397 93384844 Iustin Pop
    """
398 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
399 93384844 Iustin Pop
400 93384844 Iustin Pop
  def GetMasterNode(self):
401 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
402 93384844 Iustin Pop

403 93384844 Iustin Pop
    """
404 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
405 93384844 Iustin Pop
406 93384844 Iustin Pop
  def GetNodeList(self):
407 93384844 Iustin Pop
    """Return the list of cluster nodes.
408 93384844 Iustin Pop

409 93384844 Iustin Pop
    """
410 93384844 Iustin Pop
    data = self._ReadFile(constants.SS_NODE_LIST)
411 93384844 Iustin Pop
    nl = data.splitlines(False)
412 93384844 Iustin Pop
    return nl
413 93384844 Iustin Pop
414 f9780ccd Luca Bigliardi
  def GetNodePrimaryIPList(self):
415 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' primary IP.
416 f9780ccd Luca Bigliardi

417 f9780ccd Luca Bigliardi
    """
418 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_PRIMARY_IPS)
419 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
420 f9780ccd Luca Bigliardi
    return nl
421 f9780ccd Luca Bigliardi
422 f9780ccd Luca Bigliardi
  def GetNodeSecondaryIPList(self):
423 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' secondary IP.
424 f9780ccd Luca Bigliardi

425 f9780ccd Luca Bigliardi
    """
426 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
427 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
428 f9780ccd Luca Bigliardi
    return nl
429 f9780ccd Luca Bigliardi
430 6f076453 Guido Trotter
  def GetNodegroupList(self):
431 6f076453 Guido Trotter
    """Return the list of nodegroups.
432 6f076453 Guido Trotter

433 6f076453 Guido Trotter
    """
434 6f076453 Guido Trotter
    data = self._ReadFile(constants.SS_NODEGROUPS)
435 6f076453 Guido Trotter
    nl = data.splitlines(False)
436 6f076453 Guido Trotter
    return nl
437 6f076453 Guido Trotter
438 25e39bfa Iustin Pop
  def GetClusterTags(self):
439 25e39bfa Iustin Pop
    """Return the cluster tags.
440 25e39bfa Iustin Pop

441 25e39bfa Iustin Pop
    """
442 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
443 25e39bfa Iustin Pop
    nl = data.splitlines(False)
444 25e39bfa Iustin Pop
    return nl
445 25e39bfa Iustin Pop
446 4f7a6a10 Iustin Pop
  def GetHypervisorList(self):
447 4f7a6a10 Iustin Pop
    """Return the list of enabled hypervisors.
448 4f7a6a10 Iustin Pop

449 4f7a6a10 Iustin Pop
    """
450 4f7a6a10 Iustin Pop
    data = self._ReadFile(constants.SS_HYPERVISOR_LIST)
451 4f7a6a10 Iustin Pop
    nl = data.splitlines(False)
452 4f7a6a10 Iustin Pop
    return nl
453 4f7a6a10 Iustin Pop
454 5c465a95 Iustin Pop
  def GetMaintainNodeHealth(self):
455 5c465a95 Iustin Pop
    """Return the value of the maintain_node_health option.
456 5c465a95 Iustin Pop

457 5c465a95 Iustin Pop
    """
458 5c465a95 Iustin Pop
    data = self._ReadFile(constants.SS_MAINTAIN_NODE_HEALTH)
459 5c465a95 Iustin Pop
    # we rely on the bool serialization here
460 5c465a95 Iustin Pop
    return data == "True"
461 5c465a95 Iustin Pop
462 0fbae49a Balazs Lecz
  def GetUidPool(self):
463 0fbae49a Balazs Lecz
    """Return the user-id pool definition string.
464 0fbae49a Balazs Lecz

465 0fbae49a Balazs Lecz
    The separator character is a newline.
466 0fbae49a Balazs Lecz

467 d3b790bb Balazs Lecz
    The return value can be parsed using uidpool.ParseUidPool()::
468 d3b790bb Balazs Lecz

469 0fbae49a Balazs Lecz
      ss = ssconf.SimpleStore()
470 d3b790bb Balazs Lecz
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\\n")
471 0fbae49a Balazs Lecz

472 0fbae49a Balazs Lecz
    """
473 0fbae49a Balazs Lecz
    data = self._ReadFile(constants.SS_UID_POOL)
474 0fbae49a Balazs Lecz
    return data
475 0fbae49a Balazs Lecz
476 868a98ca Manuel Franceschini
  def GetPrimaryIPFamily(self):
477 868a98ca Manuel Franceschini
    """Return the cluster-wide primary address family.
478 868a98ca Manuel Franceschini

479 868a98ca Manuel Franceschini
    """
480 868a98ca Manuel Franceschini
    try:
481 7dd999fc Manuel Franceschini
      return int(self._ReadFile(constants.SS_PRIMARY_IP_FAMILY,
482 7dd999fc Manuel Franceschini
                                default=netutils.IP4Address.family))
483 868a98ca Manuel Franceschini
    except (ValueError, TypeError), err:
484 868a98ca Manuel Franceschini
      raise errors.ConfigurationError("Error while trying to parse primary ip"
485 868a98ca Manuel Franceschini
                                      " family: %s" % err)
486 868a98ca Manuel Franceschini
487 93384844 Iustin Pop
488 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
489 b33e986b Iustin Pop
  """Get the master node and my own hostname.
490 b33e986b Iustin Pop

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

494 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
495 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
496 b33e986b Iustin Pop

497 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
498 8135a2db Iustin Pop
      sstore.SimpleStore instance
499 8135a2db Iustin Pop
  @rtype: tuple
500 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
501 8135a2db Iustin Pop

502 b33e986b Iustin Pop
  """
503 b33e986b Iustin Pop
  if ss is None:
504 93384844 Iustin Pop
    ss = SimpleStore()
505 b705c7a6 Manuel Franceschini
  return ss.GetMasterNode(), netutils.Hostname.GetSysName()
506 b33e986b Iustin Pop
507 06dc5b44 Iustin Pop
508 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
509 5675cd1f Iustin Pop
  """Checks the node setup.
510 5675cd1f Iustin Pop

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

514 5675cd1f Iustin Pop
  """
515 5675cd1f Iustin Pop
  try:
516 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
517 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
518 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
519 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
520 5675cd1f Iustin Pop
  except errors.ResolverError, err:
521 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
522 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
523 5675cd1f Iustin Pop
524 b33e986b Iustin Pop
  if myself != master_name:
525 5675cd1f Iustin Pop
    if debug:
526 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
527 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)