Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ 70817cee

History | View | Annotate | Download (15.6 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 c09254c2 Iustin Pop
# Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012 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 d0c8c01d Iustin Pop
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 d0c8c01d Iustin Pop
    c_nparams = self._config_data["cluster"]["nicparams"][constants.PP_DEFAULT]
115 d0c8c01d Iustin Pop
    for iname in self._config_data["instances"]:
116 d0c8c01d Iustin Pop
      instance = self._config_data["instances"][iname]
117 d0c8c01d Iustin Pop
      for nic in instance["nics"]:
118 d0c8c01d Iustin Pop
        if "ip" in nic and nic["ip"]:
119 d0c8c01d Iustin Pop
          params = objects.FillDict(c_nparams, nic["nicparams"])
120 d0c8c01d Iustin Pop
          if not params["link"] in self._inst_ips_by_link:
121 d0c8c01d Iustin Pop
            self._inst_ips_by_link[params["link"]] = []
122 d0c8c01d Iustin Pop
            self._ip_to_inst_by_link[params["link"]] = {}
123 d0c8c01d Iustin Pop
          self._ip_to_inst_by_link[params["link"]][nic["ip"]] = iname
124 d0c8c01d Iustin Pop
          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 5a8648eb Andrea Spadaccini
  def GetMasterNetmask(self):
156 5a8648eb Andrea Spadaccini
    return self._config_data["cluster"]["master_netmask"]
157 5a8648eb Andrea Spadaccini
158 856c67e1 Michael Hanselmann
  def GetFileStorageDir(self):
159 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["file_storage_dir"]
160 856c67e1 Michael Hanselmann
161 4b97f902 Apollon Oikonomopoulos
  def GetSharedFileStorageDir(self):
162 4b97f902 Apollon Oikonomopoulos
    return self._config_data["cluster"]["shared_file_storage_dir"]
163 4b97f902 Apollon Oikonomopoulos
164 856c67e1 Michael Hanselmann
  def GetNodeList(self):
165 856c67e1 Michael Hanselmann
    return self._config_data["nodes"].keys()
166 856c67e1 Michael Hanselmann
167 a0c26bdb Guido Trotter
  def GetConfigSerialNo(self):
168 a0c26bdb Guido Trotter
    return self._config_data["serial_no"]
169 a0c26bdb Guido Trotter
170 a0c26bdb Guido Trotter
  def GetClusterSerialNo(self):
171 a0c26bdb Guido Trotter
    return self._config_data["cluster"]["serial_no"]
172 a0c26bdb Guido Trotter
173 47a626b0 Guido Trotter
  def GetDefaultNicParams(self):
174 47a626b0 Guido Trotter
    return self._config_data["cluster"]["nicparams"][constants.PP_DEFAULT]
175 47a626b0 Guido Trotter
176 47a626b0 Guido Trotter
  def GetDefaultNicLink(self):
177 47a626b0 Guido Trotter
    return self.GetDefaultNicParams()[constants.NIC_LINK]
178 47a626b0 Guido Trotter
179 e843991b Guido Trotter
  def GetNodeStatusFlags(self, node):
180 e843991b Guido Trotter
    """Get a node's status flags
181 e843991b Guido Trotter

182 e843991b Guido Trotter
    @type node: string
183 e843991b Guido Trotter
    @param node: node name
184 e843991b Guido Trotter
    @rtype: (bool, bool, bool)
185 e843991b Guido Trotter
    @return: (master_candidate, drained, offline) (or None if no such node)
186 e843991b Guido Trotter

187 e843991b Guido Trotter
    """
188 e843991b Guido Trotter
    if node not in self._config_data["nodes"]:
189 e843991b Guido Trotter
      return None
190 e843991b Guido Trotter
191 e843991b Guido Trotter
    master_candidate = self._config_data["nodes"][node]["master_candidate"]
192 e843991b Guido Trotter
    drained = self._config_data["nodes"][node]["drained"]
193 e843991b Guido Trotter
    offline = self._config_data["nodes"][node]["offline"]
194 e843991b Guido Trotter
    return master_candidate, drained, offline
195 e843991b Guido Trotter
196 cd195419 Guido Trotter
  def GetInstanceByLinkIp(self, ip, link):
197 9d099698 Guido Trotter
    """Get instance name from its link and ip address.
198 9d099698 Guido Trotter

199 9d099698 Guido Trotter
    @type ip: string
200 9d099698 Guido Trotter
    @param ip: ip address
201 9d099698 Guido Trotter
    @type link: string
202 9d099698 Guido Trotter
    @param link: nic link
203 9d099698 Guido Trotter
    @rtype: string
204 9d099698 Guido Trotter
    @return: instance name
205 9d099698 Guido Trotter

206 9d099698 Guido Trotter
    """
207 cd195419 Guido Trotter
    if not link:
208 cd195419 Guido Trotter
      link = self.GetDefaultNicLink()
209 cd195419 Guido Trotter
    if not link in self._ip_to_inst_by_link:
210 ae130c81 Guido Trotter
      return None
211 cd195419 Guido Trotter
    if not ip in self._ip_to_inst_by_link[link]:
212 cd195419 Guido Trotter
      return None
213 cd195419 Guido Trotter
    return self._ip_to_inst_by_link[link][ip]
214 ae130c81 Guido Trotter
215 ae130c81 Guido Trotter
  def GetNodePrimaryIp(self, node):
216 ae130c81 Guido Trotter
    """Get a node's primary ip
217 ae130c81 Guido Trotter

218 ae130c81 Guido Trotter
    @type node: string
219 ae130c81 Guido Trotter
    @param node: node name
220 ae130c81 Guido Trotter
    @rtype: string, or None
221 ae130c81 Guido Trotter
    @return: node's primary ip, or None if no such node
222 ae130c81 Guido Trotter

223 ae130c81 Guido Trotter
    """
224 ae130c81 Guido Trotter
    if node not in self._config_data["nodes"]:
225 ae130c81 Guido Trotter
      return None
226 ae130c81 Guido Trotter
    return self._config_data["nodes"][node]["primary_ip"]
227 ae130c81 Guido Trotter
228 ae130c81 Guido Trotter
  def GetInstancePrimaryNode(self, instance):
229 ae130c81 Guido Trotter
    """Get an instance's primary node
230 ae130c81 Guido Trotter

231 ae130c81 Guido Trotter
    @type instance: string
232 ae130c81 Guido Trotter
    @param instance: instance name
233 ae130c81 Guido Trotter
    @rtype: string, or None
234 ae130c81 Guido Trotter
    @return: primary node, or None if no such instance
235 ae130c81 Guido Trotter

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

250 9d099698 Guido Trotter
    @type link: string
251 9d099698 Guido Trotter
    @param link: nic link
252 9d099698 Guido Trotter
    @rtype: list
253 9d099698 Guido Trotter
    @return: list of ips connected to that link
254 9d099698 Guido Trotter

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

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

272 93384844 Iustin Pop
  Other particularities of the datastore:
273 93384844 Iustin Pop
    - keys are restricted to predefined values
274 93384844 Iustin Pop

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

311 93384844 Iustin Pop
    """
312 93384844 Iustin Pop
    if key not in self._VALID_KEYS:
313 93384844 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
314 93384844 Iustin Pop
                                   % str(key))
315 93384844 Iustin Pop
316 c09254c2 Iustin Pop
    filename = self._cfg_dir + "/" + constants.SSCONF_FILEPREFIX + key
317 93384844 Iustin Pop
    return filename
318 93384844 Iustin Pop
319 7dd999fc Manuel Franceschini
  def _ReadFile(self, key, default=None):
320 93384844 Iustin Pop
    """Generic routine to read keys.
321 93384844 Iustin Pop

322 93384844 Iustin Pop
    This will read the file which holds the value requested. Errors
323 93384844 Iustin Pop
    will be changed into ConfigurationErrors.
324 93384844 Iustin Pop

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

340 89b14f05 Iustin Pop
    @type values: dict
341 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
342 89b14f05 Iustin Pop

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

363 93384844 Iustin Pop
    This is used for computing node replication data.
364 93384844 Iustin Pop

365 93384844 Iustin Pop
    """
366 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
367 93384844 Iustin Pop
368 93384844 Iustin Pop
  def GetClusterName(self):
369 93384844 Iustin Pop
    """Get the cluster name.
370 93384844 Iustin Pop

371 93384844 Iustin Pop
    """
372 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
373 93384844 Iustin Pop
374 93384844 Iustin Pop
  def GetFileStorageDir(self):
375 93384844 Iustin Pop
    """Get the file storage dir.
376 93384844 Iustin Pop

377 93384844 Iustin Pop
    """
378 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
379 93384844 Iustin Pop
380 4b97f902 Apollon Oikonomopoulos
  def GetSharedFileStorageDir(self):
381 4b97f902 Apollon Oikonomopoulos
    """Get the shared file storage dir.
382 4b97f902 Apollon Oikonomopoulos

383 4b97f902 Apollon Oikonomopoulos
    """
384 4b97f902 Apollon Oikonomopoulos
    return self._ReadFile(constants.SS_SHARED_FILE_STORAGE_DIR)
385 4b97f902 Apollon Oikonomopoulos
386 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
387 f56618e0 Iustin Pop
    """Return the list of master candidates.
388 f56618e0 Iustin Pop

389 f56618e0 Iustin Pop
    """
390 f56618e0 Iustin Pop
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES)
391 f56618e0 Iustin Pop
    nl = data.splitlines(False)
392 f56618e0 Iustin Pop
    return nl
393 f56618e0 Iustin Pop
394 8113a52e Luca Bigliardi
  def GetMasterCandidatesIPList(self):
395 8113a52e Luca Bigliardi
    """Return the list of master candidates' primary IP.
396 8113a52e Luca Bigliardi

397 8113a52e Luca Bigliardi
    """
398 8113a52e Luca Bigliardi
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES_IPS)
399 8113a52e Luca Bigliardi
    nl = data.splitlines(False)
400 8113a52e Luca Bigliardi
    return nl
401 8113a52e Luca Bigliardi
402 93384844 Iustin Pop
  def GetMasterIP(self):
403 93384844 Iustin Pop
    """Get the IP of the master node for this cluster.
404 93384844 Iustin Pop

405 93384844 Iustin Pop
    """
406 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
407 93384844 Iustin Pop
408 93384844 Iustin Pop
  def GetMasterNetdev(self):
409 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
410 93384844 Iustin Pop

411 93384844 Iustin Pop
    """
412 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
413 93384844 Iustin Pop
414 5a8648eb Andrea Spadaccini
  def GetMasterNetmask(self):
415 186c03b3 Andrea Spadaccini
    """Get the master netmask.
416 5a8648eb Andrea Spadaccini

417 5a8648eb Andrea Spadaccini
    """
418 186c03b3 Andrea Spadaccini
    try:
419 186c03b3 Andrea Spadaccini
      return self._ReadFile(constants.SS_MASTER_NETMASK)
420 186c03b3 Andrea Spadaccini
    except errors.ConfigurationError:
421 186c03b3 Andrea Spadaccini
      family = self.GetPrimaryIPFamily()
422 186c03b3 Andrea Spadaccini
      ipcls = netutils.IPAddress.GetClassFromIpFamily(family)
423 186c03b3 Andrea Spadaccini
      return ipcls.iplen
424 5a8648eb Andrea Spadaccini
425 93384844 Iustin Pop
  def GetMasterNode(self):
426 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
427 93384844 Iustin Pop

428 93384844 Iustin Pop
    """
429 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
430 93384844 Iustin Pop
431 93384844 Iustin Pop
  def GetNodeList(self):
432 93384844 Iustin Pop
    """Return the list of cluster nodes.
433 93384844 Iustin Pop

434 93384844 Iustin Pop
    """
435 93384844 Iustin Pop
    data = self._ReadFile(constants.SS_NODE_LIST)
436 93384844 Iustin Pop
    nl = data.splitlines(False)
437 93384844 Iustin Pop
    return nl
438 93384844 Iustin Pop
439 f9780ccd Luca Bigliardi
  def GetNodePrimaryIPList(self):
440 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' primary IP.
441 f9780ccd Luca Bigliardi

442 f9780ccd Luca Bigliardi
    """
443 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_PRIMARY_IPS)
444 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
445 f9780ccd Luca Bigliardi
    return nl
446 f9780ccd Luca Bigliardi
447 f9780ccd Luca Bigliardi
  def GetNodeSecondaryIPList(self):
448 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' secondary IP.
449 f9780ccd Luca Bigliardi

450 f9780ccd Luca Bigliardi
    """
451 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
452 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
453 f9780ccd Luca Bigliardi
    return nl
454 f9780ccd Luca Bigliardi
455 6f076453 Guido Trotter
  def GetNodegroupList(self):
456 6f076453 Guido Trotter
    """Return the list of nodegroups.
457 6f076453 Guido Trotter

458 6f076453 Guido Trotter
    """
459 6f076453 Guido Trotter
    data = self._ReadFile(constants.SS_NODEGROUPS)
460 6f076453 Guido Trotter
    nl = data.splitlines(False)
461 6f076453 Guido Trotter
    return nl
462 6f076453 Guido Trotter
463 25e39bfa Iustin Pop
  def GetClusterTags(self):
464 25e39bfa Iustin Pop
    """Return the cluster tags.
465 25e39bfa Iustin Pop

466 25e39bfa Iustin Pop
    """
467 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
468 25e39bfa Iustin Pop
    nl = data.splitlines(False)
469 25e39bfa Iustin Pop
    return nl
470 25e39bfa Iustin Pop
471 4f7a6a10 Iustin Pop
  def GetHypervisorList(self):
472 4f7a6a10 Iustin Pop
    """Return the list of enabled hypervisors.
473 4f7a6a10 Iustin Pop

474 4f7a6a10 Iustin Pop
    """
475 4f7a6a10 Iustin Pop
    data = self._ReadFile(constants.SS_HYPERVISOR_LIST)
476 4f7a6a10 Iustin Pop
    nl = data.splitlines(False)
477 4f7a6a10 Iustin Pop
    return nl
478 4f7a6a10 Iustin Pop
479 5c465a95 Iustin Pop
  def GetMaintainNodeHealth(self):
480 5c465a95 Iustin Pop
    """Return the value of the maintain_node_health option.
481 5c465a95 Iustin Pop

482 5c465a95 Iustin Pop
    """
483 5c465a95 Iustin Pop
    data = self._ReadFile(constants.SS_MAINTAIN_NODE_HEALTH)
484 5c465a95 Iustin Pop
    # we rely on the bool serialization here
485 5c465a95 Iustin Pop
    return data == "True"
486 5c465a95 Iustin Pop
487 0fbae49a Balazs Lecz
  def GetUidPool(self):
488 0fbae49a Balazs Lecz
    """Return the user-id pool definition string.
489 0fbae49a Balazs Lecz

490 0fbae49a Balazs Lecz
    The separator character is a newline.
491 0fbae49a Balazs Lecz

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

494 0fbae49a Balazs Lecz
      ss = ssconf.SimpleStore()
495 d3b790bb Balazs Lecz
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\\n")
496 0fbae49a Balazs Lecz

497 0fbae49a Balazs Lecz
    """
498 0fbae49a Balazs Lecz
    data = self._ReadFile(constants.SS_UID_POOL)
499 0fbae49a Balazs Lecz
    return data
500 0fbae49a Balazs Lecz
501 868a98ca Manuel Franceschini
  def GetPrimaryIPFamily(self):
502 868a98ca Manuel Franceschini
    """Return the cluster-wide primary address family.
503 868a98ca Manuel Franceschini

504 868a98ca Manuel Franceschini
    """
505 868a98ca Manuel Franceschini
    try:
506 7dd999fc Manuel Franceschini
      return int(self._ReadFile(constants.SS_PRIMARY_IP_FAMILY,
507 7dd999fc Manuel Franceschini
                                default=netutils.IP4Address.family))
508 868a98ca Manuel Franceschini
    except (ValueError, TypeError), err:
509 868a98ca Manuel Franceschini
      raise errors.ConfigurationError("Error while trying to parse primary ip"
510 868a98ca Manuel Franceschini
                                      " family: %s" % err)
511 868a98ca Manuel Franceschini
512 93384844 Iustin Pop
513 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
514 b33e986b Iustin Pop
  """Get the master node and my own hostname.
515 b33e986b Iustin Pop

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

519 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
520 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
521 b33e986b Iustin Pop

522 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
523 8135a2db Iustin Pop
      sstore.SimpleStore instance
524 8135a2db Iustin Pop
  @rtype: tuple
525 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
526 8135a2db Iustin Pop

527 b33e986b Iustin Pop
  """
528 b33e986b Iustin Pop
  if ss is None:
529 93384844 Iustin Pop
    ss = SimpleStore()
530 b705c7a6 Manuel Franceschini
  return ss.GetMasterNode(), netutils.Hostname.GetSysName()
531 b33e986b Iustin Pop
532 06dc5b44 Iustin Pop
533 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
534 5675cd1f Iustin Pop
  """Checks the node setup.
535 5675cd1f Iustin Pop

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

539 5675cd1f Iustin Pop
  """
540 5675cd1f Iustin Pop
  try:
541 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
542 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
543 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
544 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
545 5675cd1f Iustin Pop
  except errors.ResolverError, err:
546 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
547 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
548 5675cd1f Iustin Pop
549 b33e986b Iustin Pop
  if myself != master_name:
550 5675cd1f Iustin Pop
    if debug:
551 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
552 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)