Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ b43dcc5a

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

329 89b14f05 Iustin Pop
    @type values: dict
330 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
331 89b14f05 Iustin Pop

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

351 93384844 Iustin Pop
    This is used for computing node replication data.
352 93384844 Iustin Pop

353 93384844 Iustin Pop
    """
354 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
355 93384844 Iustin Pop
356 93384844 Iustin Pop
  def GetClusterName(self):
357 93384844 Iustin Pop
    """Get the cluster name.
358 93384844 Iustin Pop

359 93384844 Iustin Pop
    """
360 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
361 93384844 Iustin Pop
362 93384844 Iustin Pop
  def GetFileStorageDir(self):
363 93384844 Iustin Pop
    """Get the file storage dir.
364 93384844 Iustin Pop

365 93384844 Iustin Pop
    """
366 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
367 93384844 Iustin Pop
368 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
369 f56618e0 Iustin Pop
    """Return the list of master candidates.
370 f56618e0 Iustin Pop

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

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

387 93384844 Iustin Pop
    """
388 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
389 93384844 Iustin Pop
390 93384844 Iustin Pop
  def GetMasterNetdev(self):
391 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
392 93384844 Iustin Pop

393 93384844 Iustin Pop
    """
394 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
395 93384844 Iustin Pop
396 93384844 Iustin Pop
  def GetMasterNode(self):
397 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
398 93384844 Iustin Pop

399 93384844 Iustin Pop
    """
400 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
401 93384844 Iustin Pop
402 93384844 Iustin Pop
  def GetNodeList(self):
403 93384844 Iustin Pop
    """Return the list of cluster nodes.
404 93384844 Iustin Pop

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

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

421 f9780ccd Luca Bigliardi
    """
422 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
423 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
424 f9780ccd Luca Bigliardi
    return nl
425 f9780ccd Luca Bigliardi
426 25e39bfa Iustin Pop
  def GetClusterTags(self):
427 25e39bfa Iustin Pop
    """Return the cluster tags.
428 25e39bfa Iustin Pop

429 25e39bfa Iustin Pop
    """
430 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
431 25e39bfa Iustin Pop
    nl = data.splitlines(False)
432 25e39bfa Iustin Pop
    return nl
433 25e39bfa Iustin Pop
434 4f7a6a10 Iustin Pop
  def GetHypervisorList(self):
435 4f7a6a10 Iustin Pop
    """Return the list of enabled hypervisors.
436 4f7a6a10 Iustin Pop

437 4f7a6a10 Iustin Pop
    """
438 4f7a6a10 Iustin Pop
    data = self._ReadFile(constants.SS_HYPERVISOR_LIST)
439 4f7a6a10 Iustin Pop
    nl = data.splitlines(False)
440 4f7a6a10 Iustin Pop
    return nl
441 4f7a6a10 Iustin Pop
442 5c465a95 Iustin Pop
  def GetMaintainNodeHealth(self):
443 5c465a95 Iustin Pop
    """Return the value of the maintain_node_health option.
444 5c465a95 Iustin Pop

445 5c465a95 Iustin Pop
    """
446 5c465a95 Iustin Pop
    data = self._ReadFile(constants.SS_MAINTAIN_NODE_HEALTH)
447 5c465a95 Iustin Pop
    # we rely on the bool serialization here
448 5c465a95 Iustin Pop
    return data == "True"
449 5c465a95 Iustin Pop
450 0fbae49a Balazs Lecz
  def GetUidPool(self):
451 0fbae49a Balazs Lecz
    """Return the user-id pool definition string.
452 0fbae49a Balazs Lecz

453 0fbae49a Balazs Lecz
    The separator character is a newline.
454 0fbae49a Balazs Lecz

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

457 0fbae49a Balazs Lecz
      ss = ssconf.SimpleStore()
458 d3b790bb Balazs Lecz
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\\n")
459 0fbae49a Balazs Lecz

460 0fbae49a Balazs Lecz
    """
461 0fbae49a Balazs Lecz
    data = self._ReadFile(constants.SS_UID_POOL)
462 0fbae49a Balazs Lecz
    return data
463 0fbae49a Balazs Lecz
464 868a98ca Manuel Franceschini
  def GetPrimaryIPFamily(self):
465 868a98ca Manuel Franceschini
    """Return the cluster-wide primary address family.
466 868a98ca Manuel Franceschini

467 868a98ca Manuel Franceschini
    """
468 868a98ca Manuel Franceschini
    try:
469 868a98ca Manuel Franceschini
      return int(self._ReadFile(constants.SS_PRIMARY_IP_FAMILY))
470 868a98ca Manuel Franceschini
    except (ValueError, TypeError), err:
471 868a98ca Manuel Franceschini
      raise errors.ConfigurationError("Error while trying to parse primary ip"
472 868a98ca Manuel Franceschini
                                      " family: %s" % err)
473 868a98ca Manuel Franceschini
474 93384844 Iustin Pop
475 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
476 b33e986b Iustin Pop
  """Get the master node and my own hostname.
477 b33e986b Iustin Pop

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

481 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
482 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
483 b33e986b Iustin Pop

484 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
485 8135a2db Iustin Pop
      sstore.SimpleStore instance
486 8135a2db Iustin Pop
  @rtype: tuple
487 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
488 8135a2db Iustin Pop

489 b33e986b Iustin Pop
  """
490 b33e986b Iustin Pop
  if ss is None:
491 93384844 Iustin Pop
    ss = SimpleStore()
492 b705c7a6 Manuel Franceschini
  return ss.GetMasterNode(), netutils.Hostname.GetSysName()
493 b33e986b Iustin Pop
494 06dc5b44 Iustin Pop
495 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
496 5675cd1f Iustin Pop
  """Checks the node setup.
497 5675cd1f Iustin Pop

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

501 5675cd1f Iustin Pop
  """
502 5675cd1f Iustin Pop
  try:
503 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
504 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
505 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
506 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
507 5675cd1f Iustin Pop
  except errors.ResolverError, err:
508 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
509 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
510 5675cd1f Iustin Pop
511 b33e986b Iustin Pop
  if myself != master_name:
512 5675cd1f Iustin Pop
    if debug:
513 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
514 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)