Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ 4be4691d

History | View | Annotate | Download (4.7 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 a8083063 Iustin Pop
32 a8083063 Iustin Pop
from ganeti import errors
33 a8083063 Iustin Pop
from ganeti import constants
34 41a57aab Michael Hanselmann
from ganeti import utils
35 856c67e1 Michael Hanselmann
from ganeti import serializer
36 a8083063 Iustin Pop
37 a8083063 Iustin Pop
38 0c223ea9 Michael Hanselmann
SSCONF_LOCK_TIMEOUT = 10
39 0c223ea9 Michael Hanselmann
40 03d1dba2 Michael Hanselmann
RE_VALID_SSCONF_NAME = re.compile(r'^[-_a-z0-9]+$')
41 03d1dba2 Michael Hanselmann
42 0c223ea9 Michael Hanselmann
43 02f99608 Oleksiy Mishchenko
class SimpleConfigReader(object):
44 856c67e1 Michael Hanselmann
  """Simple class to read configuration file.
45 856c67e1 Michael Hanselmann

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

50 856c67e1 Michael Hanselmann
    @type file_name: string
51 856c67e1 Michael Hanselmann
    @param file_name: Configuration file path
52 856c67e1 Michael Hanselmann

53 856c67e1 Michael Hanselmann
    """
54 856c67e1 Michael Hanselmann
    self._file_name = file_name
55 856c67e1 Michael Hanselmann
    self._config_data = serializer.Load(utils.ReadFile(file_name))
56 856c67e1 Michael Hanselmann
    # TODO: Error handling
57 856c67e1 Michael Hanselmann
58 856c67e1 Michael Hanselmann
  def GetClusterName(self):
59 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["cluster_name"]
60 856c67e1 Michael Hanselmann
61 856c67e1 Michael Hanselmann
  def GetHostKey(self):
62 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["rsahostkeypub"]
63 856c67e1 Michael Hanselmann
64 856c67e1 Michael Hanselmann
  def GetMasterNode(self):
65 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["master_node"]
66 856c67e1 Michael Hanselmann
67 856c67e1 Michael Hanselmann
  def GetMasterIP(self):
68 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["master_ip"]
69 856c67e1 Michael Hanselmann
70 856c67e1 Michael Hanselmann
  def GetMasterNetdev(self):
71 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["master_netdev"]
72 856c67e1 Michael Hanselmann
73 856c67e1 Michael Hanselmann
  def GetFileStorageDir(self):
74 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["file_storage_dir"]
75 856c67e1 Michael Hanselmann
76 856c67e1 Michael Hanselmann
  def GetHypervisorType(self):
77 856c67e1 Michael Hanselmann
    return self._config_data["cluster"]["hypervisor"]
78 856c67e1 Michael Hanselmann
79 856c67e1 Michael Hanselmann
  def GetNodeList(self):
80 856c67e1 Michael Hanselmann
    return self._config_data["nodes"].keys()
81 856c67e1 Michael Hanselmann
82 02f99608 Oleksiy Mishchenko
  @classmethod
83 02f99608 Oleksiy Mishchenko
  def FromDict(cls, val, cfg_file=constants.CLUSTER_CONF_FILE):
84 02f99608 Oleksiy Mishchenko
    """Alternative construction from a dictionary.
85 02f99608 Oleksiy Mishchenko

86 02f99608 Oleksiy Mishchenko
    """
87 02f99608 Oleksiy Mishchenko
    obj = SimpleConfigReader.__new__(cls)
88 02f99608 Oleksiy Mishchenko
    obj._config_data = val
89 02f99608 Oleksiy Mishchenko
    obj._file_name = cfg_file
90 02f99608 Oleksiy Mishchenko
    return obj
91 02f99608 Oleksiy Mishchenko
92 856c67e1 Michael Hanselmann
93 856c67e1 Michael Hanselmann
class SimpleConfigWriter(SimpleConfigReader):
94 856c67e1 Michael Hanselmann
  """Simple class to write configuration file.
95 856c67e1 Michael Hanselmann

96 856c67e1 Michael Hanselmann
  """
97 856c67e1 Michael Hanselmann
  def SetMasterNode(self, node):
98 856c67e1 Michael Hanselmann
    """Change master node.
99 856c67e1 Michael Hanselmann

100 856c67e1 Michael Hanselmann
    """
101 856c67e1 Michael Hanselmann
    self._config_data["cluster"]["master_node"] = node
102 856c67e1 Michael Hanselmann
103 856c67e1 Michael Hanselmann
  def Save(self):
104 856c67e1 Michael Hanselmann
    """Writes configuration file.
105 856c67e1 Michael Hanselmann

106 856c67e1 Michael Hanselmann
    Warning: Doesn't take care of locking or synchronizing with other
107 856c67e1 Michael Hanselmann
    processes.
108 856c67e1 Michael Hanselmann

109 856c67e1 Michael Hanselmann
    """
110 856c67e1 Michael Hanselmann
    utils.WriteFile(self._file_name,
111 856c67e1 Michael Hanselmann
                    data=serializer.Dump(self._config_data),
112 856c67e1 Michael Hanselmann
                    mode=0600)
113 856c67e1 Michael Hanselmann
114 856c67e1 Michael Hanselmann
115 0c223ea9 Michael Hanselmann
def _SsconfPath(name):
116 03d1dba2 Michael Hanselmann
  if not RE_VALID_SSCONF_NAME.match(name):
117 03d1dba2 Michael Hanselmann
    raise errors.ParameterError("Invalid ssconf name: %s" % name)
118 0c223ea9 Michael Hanselmann
  return "%s/ssconf_%s" % (constants.DATA_DIR, name)
119 0c223ea9 Michael Hanselmann
120 0c223ea9 Michael Hanselmann
121 03d1dba2 Michael Hanselmann
def WriteSsconfFiles(values):
122 0c223ea9 Michael Hanselmann
  """Writes legacy ssconf files to be used by external scripts.
123 0c223ea9 Michael Hanselmann

124 03d1dba2 Michael Hanselmann
  @type values: dict
125 03d1dba2 Michael Hanselmann
  @param values: Dictionary of (name, value)
126 0c223ea9 Michael Hanselmann

127 0c223ea9 Michael Hanselmann
  """
128 0c223ea9 Michael Hanselmann
  ssconf_lock = utils.FileLock(constants.SSCONF_LOCK_FILE)
129 0c223ea9 Michael Hanselmann
130 0c223ea9 Michael Hanselmann
  # Get lock while writing files
131 0c223ea9 Michael Hanselmann
  ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT)
132 0c223ea9 Michael Hanselmann
  try:
133 03d1dba2 Michael Hanselmann
    for name, value in values.iteritems():
134 03d1dba2 Michael Hanselmann
      if not value.endswith("\n"):
135 03d1dba2 Michael Hanselmann
        value += "\n"
136 03d1dba2 Michael Hanselmann
      utils.WriteFile(_SsconfPath(name),
137 03d1dba2 Michael Hanselmann
                      data=value)
138 0c223ea9 Michael Hanselmann
  finally:
139 0c223ea9 Michael Hanselmann
    ssconf_lock.Unlock()
140 0c223ea9 Michael Hanselmann
141 0c223ea9 Michael Hanselmann
142 b33e986b Iustin Pop
def GetMasterAndMyself(ss=None):
143 b33e986b Iustin Pop
  """Get the master node and my own hostname.
144 b33e986b Iustin Pop

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

148 b33e986b Iustin Pop
  The function does not handle any errors, these should be handled in
149 b33e986b Iustin Pop
  the caller (errors.ConfigurationError, errors.ResolverError).
150 b33e986b Iustin Pop

151 b33e986b Iustin Pop
  """
152 b33e986b Iustin Pop
  if ss is None:
153 06dc5b44 Iustin Pop
    ss = SimpleConfigReader()
154 b33e986b Iustin Pop
  return ss.GetMasterNode(), utils.HostInfo().name
155 b33e986b Iustin Pop
156 06dc5b44 Iustin Pop
157 b33e986b Iustin Pop
def CheckMaster(debug, ss=None):
158 5675cd1f Iustin Pop
  """Checks the node setup.
159 5675cd1f Iustin Pop

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

163 5675cd1f Iustin Pop
  """
164 5675cd1f Iustin Pop
  try:
165 b33e986b Iustin Pop
    master_name, myself = GetMasterAndMyself(ss)
166 5675cd1f Iustin Pop
  except errors.ConfigurationError, err:
167 5675cd1f Iustin Pop
    print "Cluster configuration incomplete: '%s'" % str(err)
168 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
169 5675cd1f Iustin Pop
  except errors.ResolverError, err:
170 5675cd1f Iustin Pop
    sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
171 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NODESETUP_ERROR)
172 5675cd1f Iustin Pop
173 b33e986b Iustin Pop
  if myself != master_name:
174 5675cd1f Iustin Pop
    if debug:
175 5675cd1f Iustin Pop
      sys.stderr.write("Not master, exiting.\n")
176 5675cd1f Iustin Pop
    sys.exit(constants.EXIT_NOTMASTER)