Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ 1a2eb2dc

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

505 868a98ca Manuel Franceschini
    """
506 868a98ca Manuel Franceschini
    try:
507 7dd999fc Manuel Franceschini
      return int(self._ReadFile(constants.SS_PRIMARY_IP_FAMILY,
508 7dd999fc Manuel Franceschini
                                default=netutils.IP4Address.family))
509 868a98ca Manuel Franceschini
    except (ValueError, TypeError), err:
510 868a98ca Manuel Franceschini
      raise errors.ConfigurationError("Error while trying to parse primary ip"
511 868a98ca Manuel Franceschini
                                      " family: %s" % err)
512 868a98ca Manuel Franceschini
513 93384844 Iustin Pop
514 ee501db1 Michael Hanselmann
def WriteSsconfFiles(values):
515 ee501db1 Michael Hanselmann
  """Update all ssconf files.
516 ee501db1 Michael Hanselmann

517 ee501db1 Michael Hanselmann
  Wrapper around L{SimpleStore.WriteFiles}.
518 ee501db1 Michael Hanselmann

519 ee501db1 Michael Hanselmann
  """
520 5506d7a9 Michael Hanselmann
  SimpleStore().WriteFiles(values)
521 ee501db1 Michael Hanselmann
522 ee501db1 Michael Hanselmann
523 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
524 b33e986b Iustin Pop
  """Get the master node and my own hostname.
525 b33e986b Iustin Pop

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

529 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
530 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
531 b33e986b Iustin Pop

532 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
533 8135a2db Iustin Pop
      sstore.SimpleStore instance
534 8135a2db Iustin Pop
  @rtype: tuple
535 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
536 8135a2db Iustin Pop

537 b33e986b Iustin Pop
  """
538 b33e986b Iustin Pop
  if ss is None:
539 93384844 Iustin Pop
    ss = SimpleStore()
540 b705c7a6 Manuel Franceschini
  return ss.GetMasterNode(), netutils.Hostname.GetSysName()
541 b33e986b Iustin Pop
542 06dc5b44 Iustin Pop
543 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
544 5675cd1f Iustin Pop
  """Checks the node setup.
545 5675cd1f Iustin Pop

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

549 5675cd1f Iustin Pop
  """
550 5675cd1f Iustin Pop
  try:
551 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
552 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
553 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
554 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
555 5675cd1f Iustin Pop
  except errors.ResolverError, err:
556 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
557 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
558 5675cd1f Iustin Pop
559 b33e986b Iustin Pop
  if myself != master_name:
560 5675cd1f Iustin Pop
    if debug:
561 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
562 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)