Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ cd195419

History | View | Annotate | Download (13.4 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 856c67e1 Michael Hanselmann
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Global Configuration data for Ganeti.
23 a8083063 Iustin Pop

24 a8083063 Iustin Pop
This module provides the interface to a special case of cluster
25 a8083063 Iustin Pop
configuration data, which is mostly static and available to all nodes.
26 a8083063 Iustin Pop

27 a8083063 Iustin Pop
"""
28 a8083063 Iustin Pop
29 5675cd1f Iustin Pop
import sys
30 03d1dba2 Michael Hanselmann
import re
31 7bcc78e4 Guido Trotter
import os
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
from ganeti import errors
34 a8083063 Iustin Pop
from ganeti import constants
35 41a57aab Michael Hanselmann
from ganeti import utils
36 856c67e1 Michael Hanselmann
from ganeti import serializer
37 23824641 Luca Bigliardi
from ganeti import objects
38 a8083063 Iustin Pop
39 a8083063 Iustin Pop
40 0c223ea9 Michael Hanselmann
SSCONF_LOCK_TIMEOUT = 10
41 0c223ea9 Michael Hanselmann
42 03d1dba2 Michael Hanselmann
RE_VALID_SSCONF_NAME = re.compile(r'^[-_a-z0-9]+$')
43 03d1dba2 Michael Hanselmann
44 0c223ea9 Michael Hanselmann
45 02f99608 Oleksiy Mishchenko
class SimpleConfigReader(object):
46 856c67e1 Michael Hanselmann
  """Simple class to read configuration file.
47 856c67e1 Michael Hanselmann

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

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

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

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

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

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

178 e843991b Guido Trotter
    """
179 e843991b Guido Trotter
    if node not in self._config_data["nodes"]:
180 e843991b Guido Trotter
      return None
181 e843991b Guido Trotter
182 e843991b Guido Trotter
    master_candidate = self._config_data["nodes"][node]["master_candidate"]
183 e843991b Guido Trotter
    drained = self._config_data["nodes"][node]["drained"]
184 e843991b Guido Trotter
    offline = self._config_data["nodes"][node]["offline"]
185 e843991b Guido Trotter
    return master_candidate, drained, offline
186 e843991b Guido Trotter
187 cd195419 Guido Trotter
  def GetInstanceByLinkIp(self, ip, link):
188 cd195419 Guido Trotter
    if not link:
189 cd195419 Guido Trotter
      link = self.GetDefaultNicLink()
190 cd195419 Guido Trotter
    if not link in self._ip_to_inst_by_link:
191 ae130c81 Guido Trotter
      return None
192 cd195419 Guido Trotter
    if not ip in self._ip_to_inst_by_link[link]:
193 cd195419 Guido Trotter
      return None
194 cd195419 Guido Trotter
    return self._ip_to_inst_by_link[link][ip]
195 ae130c81 Guido Trotter
196 ae130c81 Guido Trotter
  def GetNodePrimaryIp(self, node):
197 ae130c81 Guido Trotter
    """Get a node's primary ip
198 ae130c81 Guido Trotter

199 ae130c81 Guido Trotter
    @type node: string
200 ae130c81 Guido Trotter
    @param node: node name
201 ae130c81 Guido Trotter
    @rtype: string, or None
202 ae130c81 Guido Trotter
    @return: node's primary ip, or None if no such node
203 ae130c81 Guido Trotter

204 ae130c81 Guido Trotter
    """
205 ae130c81 Guido Trotter
    if node not in self._config_data["nodes"]:
206 ae130c81 Guido Trotter
      return None
207 ae130c81 Guido Trotter
    return self._config_data["nodes"][node]["primary_ip"]
208 ae130c81 Guido Trotter
209 ae130c81 Guido Trotter
  def GetInstancePrimaryNode(self, instance):
210 ae130c81 Guido Trotter
    """Get an instance's primary node
211 ae130c81 Guido Trotter

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

217 ae130c81 Guido Trotter
    """
218 ae130c81 Guido Trotter
    if instance not in self._config_data["instances"]:
219 ae130c81 Guido Trotter
      return None
220 ae130c81 Guido Trotter
    return self._config_data["instances"][instance]["primary_node"]
221 ae130c81 Guido Trotter
222 efbb4fd2 Luca Bigliardi
  def GetNodesPrimaryIps(self):
223 efbb4fd2 Luca Bigliardi
    return self._nodes_primary_ips
224 efbb4fd2 Luca Bigliardi
225 efbb4fd2 Luca Bigliardi
  def GetMasterCandidatesPrimaryIps(self):
226 efbb4fd2 Luca Bigliardi
    return self._mc_primary_ips
227 efbb4fd2 Luca Bigliardi
228 23824641 Luca Bigliardi
  def GetInstancesIps(self, link):
229 cd195419 Guido Trotter
    if not link:
230 cd195419 Guido Trotter
      link = self.GetDefaultNicLink()
231 cd195419 Guido Trotter
232 23824641 Luca Bigliardi
    if link in self._inst_ips_by_link:
233 23824641 Luca Bigliardi
      return self._inst_ips_by_link[link]
234 23824641 Luca Bigliardi
    else:
235 23824641 Luca Bigliardi
      return []
236 d01ae714 Luca Bigliardi
237 856c67e1 Michael Hanselmann
238 93384844 Iustin Pop
class SimpleStore(object):
239 93384844 Iustin Pop
  """Interface to static cluster data.
240 93384844 Iustin Pop

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

245 93384844 Iustin Pop
  Other particularities of the datastore:
246 93384844 Iustin Pop
    - keys are restricted to predefined values
247 93384844 Iustin Pop

248 93384844 Iustin Pop
  """
249 93384844 Iustin Pop
  _SS_FILEPREFIX = "ssconf_"
250 93384844 Iustin Pop
  _VALID_KEYS = (
251 93384844 Iustin Pop
    constants.SS_CLUSTER_NAME,
252 5d60b3bd Iustin Pop
    constants.SS_CLUSTER_TAGS,
253 93384844 Iustin Pop
    constants.SS_FILE_STORAGE_DIR,
254 f56618e0 Iustin Pop
    constants.SS_MASTER_CANDIDATES,
255 8113a52e Luca Bigliardi
    constants.SS_MASTER_CANDIDATES_IPS,
256 93384844 Iustin Pop
    constants.SS_MASTER_IP,
257 93384844 Iustin Pop
    constants.SS_MASTER_NETDEV,
258 93384844 Iustin Pop
    constants.SS_MASTER_NODE,
259 93384844 Iustin Pop
    constants.SS_NODE_LIST,
260 f9780ccd Luca Bigliardi
    constants.SS_NODE_PRIMARY_IPS,
261 f9780ccd Luca Bigliardi
    constants.SS_NODE_SECONDARY_IPS,
262 a3316e4a Iustin Pop
    constants.SS_OFFLINE_NODES,
263 81a49123 Iustin Pop
    constants.SS_ONLINE_NODES,
264 81a49123 Iustin Pop
    constants.SS_INSTANCE_LIST,
265 8a113c7a Iustin Pop
    constants.SS_RELEASE_VERSION,
266 93384844 Iustin Pop
    )
267 93384844 Iustin Pop
  _MAX_SIZE = 131072
268 93384844 Iustin Pop
269 93384844 Iustin Pop
  def __init__(self, cfg_location=None):
270 93384844 Iustin Pop
    if cfg_location is None:
271 93384844 Iustin Pop
      self._cfg_dir = constants.DATA_DIR
272 93384844 Iustin Pop
    else:
273 93384844 Iustin Pop
      self._cfg_dir = cfg_location
274 93384844 Iustin Pop
275 93384844 Iustin Pop
  def KeyToFilename(self, key):
276 93384844 Iustin Pop
    """Convert a given key into filename.
277 93384844 Iustin Pop

278 93384844 Iustin Pop
    """
279 93384844 Iustin Pop
    if key not in self._VALID_KEYS:
280 93384844 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
281 93384844 Iustin Pop
                                   % str(key))
282 93384844 Iustin Pop
283 93384844 Iustin Pop
    filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
284 93384844 Iustin Pop
    return filename
285 93384844 Iustin Pop
286 93384844 Iustin Pop
  def _ReadFile(self, key):
287 93384844 Iustin Pop
    """Generic routine to read keys.
288 93384844 Iustin Pop

289 93384844 Iustin Pop
    This will read the file which holds the value requested. Errors
290 93384844 Iustin Pop
    will be changed into ConfigurationErrors.
291 93384844 Iustin Pop

292 93384844 Iustin Pop
    """
293 93384844 Iustin Pop
    filename = self.KeyToFilename(key)
294 93384844 Iustin Pop
    try:
295 920b5878 Guido Trotter
      data = utils.ReadFile(filename, size=self._MAX_SIZE)
296 93384844 Iustin Pop
    except EnvironmentError, err:
297 93384844 Iustin Pop
      raise errors.ConfigurationError("Can't read from the ssconf file:"
298 93384844 Iustin Pop
                                      " '%s'" % str(err))
299 920b5878 Guido Trotter
    data = data.rstrip('\n')
300 93384844 Iustin Pop
    return data
301 93384844 Iustin Pop
302 89b14f05 Iustin Pop
  def WriteFiles(self, values):
303 89b14f05 Iustin Pop
    """Writes ssconf files used by external scripts.
304 89b14f05 Iustin Pop

305 89b14f05 Iustin Pop
    @type values: dict
306 89b14f05 Iustin Pop
    @param values: Dictionary of (name, value)
307 89b14f05 Iustin Pop

308 89b14f05 Iustin Pop
    """
309 89b14f05 Iustin Pop
    ssconf_lock = utils.FileLock(constants.SSCONF_LOCK_FILE)
310 89b14f05 Iustin Pop
311 89b14f05 Iustin Pop
    # Get lock while writing files
312 89b14f05 Iustin Pop
    ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
313 89b14f05 Iustin Pop
    try:
314 89b14f05 Iustin Pop
      for name, value in values.iteritems():
315 02b31f32 Iustin Pop
        if value and not value.endswith("\n"):
316 89b14f05 Iustin Pop
          value += "\n"
317 81a49123 Iustin Pop
        utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444)
318 89b14f05 Iustin Pop
    finally:
319 89b14f05 Iustin Pop
      ssconf_lock.Unlock()
320 89b14f05 Iustin Pop
321 93384844 Iustin Pop
  def GetFileList(self):
322 93384844 Iustin Pop
    """Return the list of all config files.
323 93384844 Iustin Pop

324 93384844 Iustin Pop
    This is used for computing node replication data.
325 93384844 Iustin Pop

326 93384844 Iustin Pop
    """
327 93384844 Iustin Pop
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
328 93384844 Iustin Pop
329 93384844 Iustin Pop
  def GetClusterName(self):
330 93384844 Iustin Pop
    """Get the cluster name.
331 93384844 Iustin Pop

332 93384844 Iustin Pop
    """
333 93384844 Iustin Pop
    return self._ReadFile(constants.SS_CLUSTER_NAME)
334 93384844 Iustin Pop
335 93384844 Iustin Pop
  def GetFileStorageDir(self):
336 93384844 Iustin Pop
    """Get the file storage dir.
337 93384844 Iustin Pop

338 93384844 Iustin Pop
    """
339 93384844 Iustin Pop
    return self._ReadFile(constants.SS_FILE_STORAGE_DIR)
340 93384844 Iustin Pop
341 f56618e0 Iustin Pop
  def GetMasterCandidates(self):
342 f56618e0 Iustin Pop
    """Return the list of master candidates.
343 f56618e0 Iustin Pop

344 f56618e0 Iustin Pop
    """
345 f56618e0 Iustin Pop
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES)
346 f56618e0 Iustin Pop
    nl = data.splitlines(False)
347 f56618e0 Iustin Pop
    return nl
348 f56618e0 Iustin Pop
349 8113a52e Luca Bigliardi
  def GetMasterCandidatesIPList(self):
350 8113a52e Luca Bigliardi
    """Return the list of master candidates' primary IP.
351 8113a52e Luca Bigliardi

352 8113a52e Luca Bigliardi
    """
353 8113a52e Luca Bigliardi
    data = self._ReadFile(constants.SS_MASTER_CANDIDATES_IPS)
354 8113a52e Luca Bigliardi
    nl = data.splitlines(False)
355 8113a52e Luca Bigliardi
    return nl
356 8113a52e Luca Bigliardi
357 93384844 Iustin Pop
  def GetMasterIP(self):
358 93384844 Iustin Pop
    """Get the IP of the master node for this cluster.
359 93384844 Iustin Pop

360 93384844 Iustin Pop
    """
361 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_IP)
362 93384844 Iustin Pop
363 93384844 Iustin Pop
  def GetMasterNetdev(self):
364 93384844 Iustin Pop
    """Get the netdev to which we'll add the master ip.
365 93384844 Iustin Pop

366 93384844 Iustin Pop
    """
367 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NETDEV)
368 93384844 Iustin Pop
369 93384844 Iustin Pop
  def GetMasterNode(self):
370 93384844 Iustin Pop
    """Get the hostname of the master node for this cluster.
371 93384844 Iustin Pop

372 93384844 Iustin Pop
    """
373 93384844 Iustin Pop
    return self._ReadFile(constants.SS_MASTER_NODE)
374 93384844 Iustin Pop
375 93384844 Iustin Pop
  def GetNodeList(self):
376 93384844 Iustin Pop
    """Return the list of cluster nodes.
377 93384844 Iustin Pop

378 93384844 Iustin Pop
    """
379 93384844 Iustin Pop
    data = self._ReadFile(constants.SS_NODE_LIST)
380 93384844 Iustin Pop
    nl = data.splitlines(False)
381 93384844 Iustin Pop
    return nl
382 93384844 Iustin Pop
383 f9780ccd Luca Bigliardi
  def GetNodePrimaryIPList(self):
384 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' primary IP.
385 f9780ccd Luca Bigliardi

386 f9780ccd Luca Bigliardi
    """
387 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_PRIMARY_IPS)
388 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
389 f9780ccd Luca Bigliardi
    return nl
390 f9780ccd Luca Bigliardi
391 f9780ccd Luca Bigliardi
  def GetNodeSecondaryIPList(self):
392 f9780ccd Luca Bigliardi
    """Return the list of cluster nodes' secondary IP.
393 f9780ccd Luca Bigliardi

394 f9780ccd Luca Bigliardi
    """
395 f9780ccd Luca Bigliardi
    data = self._ReadFile(constants.SS_NODE_SECONDARY_IPS)
396 f9780ccd Luca Bigliardi
    nl = data.splitlines(False)
397 f9780ccd Luca Bigliardi
    return nl
398 f9780ccd Luca Bigliardi
399 25e39bfa Iustin Pop
  def GetClusterTags(self):
400 25e39bfa Iustin Pop
    """Return the cluster tags.
401 25e39bfa Iustin Pop

402 25e39bfa Iustin Pop
    """
403 25e39bfa Iustin Pop
    data = self._ReadFile(constants.SS_CLUSTER_TAGS)
404 25e39bfa Iustin Pop
    nl = data.splitlines(False)
405 25e39bfa Iustin Pop
    return nl
406 25e39bfa Iustin Pop
407 93384844 Iustin Pop
408 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
409 b33e986b Iustin Pop
  """Get the master node and my own hostname.
410 b33e986b Iustin Pop

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

414 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
415 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
416 b33e986b Iustin Pop

417 8135a2db Iustin Pop
  @param ss: either a sstore.SimpleConfigReader or a
418 8135a2db Iustin Pop
      sstore.SimpleStore instance
419 8135a2db Iustin Pop
  @rtype: tuple
420 8135a2db Iustin Pop
  @return: a tuple (master node name, my own name)
421 8135a2db Iustin Pop

422 b33e986b Iustin Pop
  """
423 b33e986b Iustin Pop
  if ss is None:
424 93384844 Iustin Pop
    ss = SimpleStore()
425 b33e986b Iustin Pop
  return ss.GetMasterNode(), utils.HostInfo().name
426 b33e986b Iustin Pop
427 06dc5b44 Iustin Pop
428 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
429 5675cd1f Iustin Pop
  """Checks the node setup.
430 5675cd1f Iustin Pop

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

434 5675cd1f Iustin Pop
  """
435 5675cd1f Iustin Pop
  try:
436 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
437 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
438 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
439 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
440 5675cd1f Iustin Pop
  except errors.ResolverError, err:
441 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
442 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
443 5675cd1f Iustin Pop
444 b33e986b Iustin Pop
  if myself != master_name:
445 5675cd1f Iustin Pop
    if debug:
446 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
447 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)
448 3f71b464 Guido Trotter
449 3f71b464 Guido Trotter
450 3f71b464 Guido Trotter
def CheckMasterCandidate(debug, ss=None):
451 3f71b464 Guido Trotter
  """Checks the node setup.
452 3f71b464 Guido Trotter

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

456 3f71b464 Guido Trotter
  """
457 3f71b464 Guido Trotter
  try:
458 3f71b464 Guido Trotter
    if ss is None:
459 3f71b464 Guido Trotter
      ss = SimpleStore()
460 3f71b464 Guido Trotter
    myself = utils.HostInfo().name
461 3f71b464 Guido Trotter
    candidates = ss.GetMasterCandidates()
462 3f71b464 Guido Trotter
  except errors.ConfigurationError, err:
463 3f71b464 Guido Trotter
    print "Cluster configuration incomplete: '%s'" % str(err)
464 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
465 3f71b464 Guido Trotter
  except errors.ResolverError, err:
466 3f71b464 Guido Trotter
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
467 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NODESETUP_ERROR)
468 3f71b464 Guido Trotter
469 3f71b464 Guido Trotter
  if myself not in candidates:
470 3f71b464 Guido Trotter
    if debug:
471 3f71b464 Guido Trotter
      sys.stderr.write("Not master candidate, exiting.\n")
472 3f71b464 Guido Trotter
    sys.exit(constants.EXIT_NOTCANDIDATE)