Statistics
| Branch: | Tag: | Revision:

root / lib / ssconf.py @ b0059682

History | View | Annotate | Download (5.8 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 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 a8083063 Iustin Pop
import socket
30 a8083063 Iustin Pop
31 a8083063 Iustin Pop
from ganeti import errors
32 a8083063 Iustin Pop
from ganeti import constants
33 41a57aab Michael Hanselmann
from ganeti import utils
34 a8083063 Iustin Pop
35 a8083063 Iustin Pop
36 a8083063 Iustin Pop
class SimpleStore:
37 a8083063 Iustin Pop
  """Interface to static cluster data.
38 a8083063 Iustin Pop

39 a8083063 Iustin Pop
  This is different that the config.ConfigWriter class in that it
40 a8083063 Iustin Pop
  holds data that is (mostly) constant after the cluster
41 a8083063 Iustin Pop
  initialization. Its purpose is to allow limited customization of
42 a8083063 Iustin Pop
  things which would otherwise normally live in constants.py. Note
43 a8083063 Iustin Pop
  that this data cannot live in ConfigWriter as that is available only
44 a8083063 Iustin Pop
  on the master node, and our data must be readable by both the master
45 a8083063 Iustin Pop
  and the nodes.
46 a8083063 Iustin Pop

47 a8083063 Iustin Pop
  Other particularities of the datastore:
48 a8083063 Iustin Pop
    - keys are restricted to predefined values
49 a8083063 Iustin Pop
    - values are small (<4k)
50 05f86716 Guido Trotter
    - some keys are handled specially (read from the system)
51 a8083063 Iustin Pop

52 a8083063 Iustin Pop
  """
53 a8083063 Iustin Pop
  _SS_FILEPREFIX = "ssconf_"
54 a8083063 Iustin Pop
  SS_HYPERVISOR = "hypervisor"
55 a8083063 Iustin Pop
  SS_NODED_PASS = "node_pass"
56 880478f8 Iustin Pop
  SS_MASTER_NODE = "master_node"
57 880478f8 Iustin Pop
  SS_MASTER_IP = "master_ip"
58 880478f8 Iustin Pop
  SS_MASTER_NETDEV = "master_netdev"
59 5fcdc80d Iustin Pop
  SS_CLUSTER_NAME = "cluster_name"
60 17dfc522 Manuel Franceschini
  SS_FILE_STORAGE_DIR = "file_storage_dir"
61 742f39ac Michael Hanselmann
  SS_CONFIG_VERSION = "config_version"
62 880478f8 Iustin Pop
  _VALID_KEYS = (SS_HYPERVISOR, SS_NODED_PASS, SS_MASTER_NODE, SS_MASTER_IP,
63 742f39ac Michael Hanselmann
                 SS_MASTER_NETDEV, SS_CLUSTER_NAME, SS_FILE_STORAGE_DIR,
64 742f39ac Michael Hanselmann
                 SS_CONFIG_VERSION)
65 a8083063 Iustin Pop
  _MAX_SIZE = 4096
66 a8083063 Iustin Pop
67 a8083063 Iustin Pop
  def __init__(self, cfg_location=None):
68 a8083063 Iustin Pop
    if cfg_location is None:
69 a8083063 Iustin Pop
      self._cfg_dir = constants.DATA_DIR
70 a8083063 Iustin Pop
    else:
71 a8083063 Iustin Pop
      self._cfg_dir = cfg_location
72 a8083063 Iustin Pop
73 a8083063 Iustin Pop
  def KeyToFilename(self, key):
74 a8083063 Iustin Pop
    """Convert a given key into filename.
75 a8083063 Iustin Pop

76 a8083063 Iustin Pop
    """
77 a8083063 Iustin Pop
    if key not in self._VALID_KEYS:
78 3ecf6786 Iustin Pop
      raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'"
79 3ecf6786 Iustin Pop
                                   % str(key))
80 a8083063 Iustin Pop
81 a8083063 Iustin Pop
    filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key
82 a8083063 Iustin Pop
    return filename
83 a8083063 Iustin Pop
84 a8083063 Iustin Pop
  def _ReadFile(self, key):
85 a8083063 Iustin Pop
    """Generic routine to read keys.
86 a8083063 Iustin Pop

87 a8083063 Iustin Pop
    This will read the file which holds the value requested. Errors
88 a8083063 Iustin Pop
    will be changed into ConfigurationErrors.
89 a8083063 Iustin Pop

90 a8083063 Iustin Pop
    """
91 a8083063 Iustin Pop
    filename = self.KeyToFilename(key)
92 a8083063 Iustin Pop
    try:
93 a8083063 Iustin Pop
      fh = file(filename, 'r')
94 a8083063 Iustin Pop
      try:
95 a8083063 Iustin Pop
        data = fh.readline(self._MAX_SIZE)
96 a8083063 Iustin Pop
        data = data.rstrip('\n')
97 a8083063 Iustin Pop
      finally:
98 a8083063 Iustin Pop
        fh.close()
99 a8083063 Iustin Pop
    except EnvironmentError, err:
100 3ecf6786 Iustin Pop
      raise errors.ConfigurationError("Can't read from the ssconf file:"
101 3ecf6786 Iustin Pop
                                      " '%s'" % str(err))
102 a8083063 Iustin Pop
    return data
103 a8083063 Iustin Pop
104 a8083063 Iustin Pop
  def GetNodeDaemonPort(self):
105 a8083063 Iustin Pop
    """Get the node daemon port for this cluster.
106 a8083063 Iustin Pop

107 a8083063 Iustin Pop
    Note that this routine does not read a ganeti-specific file, but
108 a8083063 Iustin Pop
    instead uses socket.getservbyname to allow pre-customization of
109 a8083063 Iustin Pop
    this parameter outside of ganeti.
110 a8083063 Iustin Pop

111 a8083063 Iustin Pop
    """
112 a8083063 Iustin Pop
    try:
113 a8083063 Iustin Pop
      port = socket.getservbyname("ganeti-noded", "tcp")
114 a8083063 Iustin Pop
    except socket.error:
115 a8083063 Iustin Pop
      port = constants.DEFAULT_NODED_PORT
116 a8083063 Iustin Pop
117 a8083063 Iustin Pop
    return port
118 a8083063 Iustin Pop
119 a8083063 Iustin Pop
  def GetHypervisorType(self):
120 a8083063 Iustin Pop
    """Get the hypervisor type for this cluster.
121 a8083063 Iustin Pop

122 a8083063 Iustin Pop
    """
123 a8083063 Iustin Pop
    return self._ReadFile(self.SS_HYPERVISOR)
124 a8083063 Iustin Pop
125 a8083063 Iustin Pop
  def GetNodeDaemonPassword(self):
126 a8083063 Iustin Pop
    """Get the node password for this cluster.
127 a8083063 Iustin Pop

128 a8083063 Iustin Pop
    """
129 a8083063 Iustin Pop
    return self._ReadFile(self.SS_NODED_PASS)
130 a8083063 Iustin Pop
131 880478f8 Iustin Pop
  def GetMasterNode(self):
132 880478f8 Iustin Pop
    """Get the hostname of the master node for this cluster.
133 880478f8 Iustin Pop

134 880478f8 Iustin Pop
    """
135 880478f8 Iustin Pop
    return self._ReadFile(self.SS_MASTER_NODE)
136 880478f8 Iustin Pop
137 880478f8 Iustin Pop
  def GetMasterIP(self):
138 880478f8 Iustin Pop
    """Get the IP of the master node for this cluster.
139 880478f8 Iustin Pop

140 880478f8 Iustin Pop
    """
141 880478f8 Iustin Pop
    return self._ReadFile(self.SS_MASTER_IP)
142 880478f8 Iustin Pop
143 880478f8 Iustin Pop
  def GetMasterNetdev(self):
144 880478f8 Iustin Pop
    """Get the netdev to which we'll add the master ip.
145 880478f8 Iustin Pop

146 880478f8 Iustin Pop
    """
147 880478f8 Iustin Pop
    return self._ReadFile(self.SS_MASTER_NETDEV)
148 880478f8 Iustin Pop
149 5fcdc80d Iustin Pop
  def GetClusterName(self):
150 5fcdc80d Iustin Pop
    """Get the cluster name.
151 5fcdc80d Iustin Pop

152 5fcdc80d Iustin Pop
    """
153 5fcdc80d Iustin Pop
    return self._ReadFile(self.SS_CLUSTER_NAME)
154 5fcdc80d Iustin Pop
155 17dfc522 Manuel Franceschini
  def GetFileStorageDir(self):
156 17dfc522 Manuel Franceschini
    """Get the file storage dir.
157 17dfc522 Manuel Franceschini

158 17dfc522 Manuel Franceschini
    """
159 17dfc522 Manuel Franceschini
    return self._ReadFile(self.SS_FILE_STORAGE_DIR)
160 17dfc522 Manuel Franceschini
161 742f39ac Michael Hanselmann
  def GetConfigVersion(self):
162 742f39ac Michael Hanselmann
    """Get the configuration version.
163 742f39ac Michael Hanselmann

164 742f39ac Michael Hanselmann
    """
165 742f39ac Michael Hanselmann
    value = self._ReadFile(self.SS_CONFIG_VERSION)
166 742f39ac Michael Hanselmann
    try:
167 742f39ac Michael Hanselmann
      return int(value)
168 742f39ac Michael Hanselmann
    except (ValueError, TypeError), err:
169 742f39ac Michael Hanselmann
      raise errors.ConfigurationError("Failed to convert config version %s to"
170 742f39ac Michael Hanselmann
                                      " int: '%s'" % (value, str(err)))
171 742f39ac Michael Hanselmann
172 05f86716 Guido Trotter
  def GetFileList(self):
173 05f86716 Guido Trotter
    """Return the list of all config files.
174 05f86716 Guido Trotter

175 05f86716 Guido Trotter
    This is used for computing node replication data.
176 05f86716 Guido Trotter

177 05f86716 Guido Trotter
    """
178 05f86716 Guido Trotter
    return [self.KeyToFilename(key) for key in self._VALID_KEYS]
179 05f86716 Guido Trotter
180 05f86716 Guido Trotter
181 05f86716 Guido Trotter
class WritableSimpleStore(SimpleStore):
182 05f86716 Guido Trotter
  """This is a read/write interface to SimpleStore, which is used rarely, when
183 05f86716 Guido Trotter
  values need to be changed. Since WriteFile handles updates in an atomic way
184 05f86716 Guido Trotter
  it should be fine to use two WritableSimpleStore at the same time, but in
185 05f86716 Guido Trotter
  the future we might want to put additional protection for this class.
186 05f86716 Guido Trotter

187 05f86716 Guido Trotter
  A WritableSimpleStore cannot be used to update system-dependent values.
188 05f86716 Guido Trotter

189 05f86716 Guido Trotter
  """
190 05f86716 Guido Trotter
191 a8083063 Iustin Pop
  def SetKey(self, key, value):
192 a8083063 Iustin Pop
    """Set the value of a key.
193 a8083063 Iustin Pop

194 8498462b Guido Trotter
    This should be used only when adding a node to a cluster, or in other
195 8498462b Guido Trotter
    infrequent operations such as cluster-rename or master-failover.
196 a8083063 Iustin Pop

197 a8083063 Iustin Pop
    """
198 a8083063 Iustin Pop
    file_name = self.KeyToFilename(key)
199 41a57aab Michael Hanselmann
    utils.WriteFile(file_name, data="%s\n" % str(value),
200 41a57aab Michael Hanselmann
                    uid=0, gid=0, mode=0400)