Statistics
| Branch: | Tag: | Revision:

root / lib / runtime.py @ 31d3b918

History | View | Annotate | Download (8.4 kB)

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

23 f12e1736 René Nussbaumer
"""
24 f12e1736 René Nussbaumer
25 f12e1736 René Nussbaumer
26 f12e1736 René Nussbaumer
import grp
27 f12e1736 René Nussbaumer
import pwd
28 f12e1736 René Nussbaumer
import threading
29 a51b19de Helga Velroyen
import os
30 a20e4768 Michael Hanselmann
import platform
31 f12e1736 René Nussbaumer
32 f12e1736 René Nussbaumer
from ganeti import constants
33 f12e1736 René Nussbaumer
from ganeti import errors
34 a51b19de Helga Velroyen
from ganeti import luxi
35 ff1012ef Petr Pudlak
from ganeti.rpc.errors import NoMasterError
36 a51b19de Helga Velroyen
from ganeti import pathutils
37 a51b19de Helga Velroyen
from ganeti import ssconf
38 44fbd23b René Nussbaumer
from ganeti import utils
39 f12e1736 René Nussbaumer
40 f12e1736 René Nussbaumer
41 f12e1736 René Nussbaumer
_priv = None
42 f12e1736 René Nussbaumer
_priv_lock = threading.Lock()
43 f12e1736 René Nussbaumer
44 a20e4768 Michael Hanselmann
#: Architecture information
45 a20e4768 Michael Hanselmann
_arch = None
46 a20e4768 Michael Hanselmann
47 f12e1736 René Nussbaumer
48 f12e1736 René Nussbaumer
def GetUid(user, _getpwnam):
49 f12e1736 René Nussbaumer
  """Retrieve the uid from the database.
50 f12e1736 René Nussbaumer

51 f12e1736 René Nussbaumer
  @type user: string
52 f12e1736 René Nussbaumer
  @param user: The username to retrieve
53 f12e1736 René Nussbaumer
  @return: The resolved uid
54 f12e1736 René Nussbaumer

55 f12e1736 René Nussbaumer
  """
56 f12e1736 René Nussbaumer
  try:
57 f12e1736 René Nussbaumer
    return _getpwnam(user).pw_uid
58 f12e1736 René Nussbaumer
  except KeyError, err:
59 f12e1736 René Nussbaumer
    raise errors.ConfigurationError("User '%s' not found (%s)" % (user, err))
60 f12e1736 René Nussbaumer
61 f12e1736 René Nussbaumer
62 f12e1736 René Nussbaumer
def GetGid(group, _getgrnam):
63 f12e1736 René Nussbaumer
  """Retrieve the gid from the database.
64 f12e1736 René Nussbaumer

65 f12e1736 René Nussbaumer
  @type group: string
66 f12e1736 René Nussbaumer
  @param group: The group name to retrieve
67 f12e1736 René Nussbaumer
  @return: The resolved gid
68 f12e1736 René Nussbaumer

69 f12e1736 René Nussbaumer
  """
70 f12e1736 René Nussbaumer
  try:
71 f12e1736 René Nussbaumer
    return _getgrnam(group).gr_gid
72 f12e1736 René Nussbaumer
  except KeyError, err:
73 f12e1736 René Nussbaumer
    raise errors.ConfigurationError("Group '%s' not found (%s)" % (group, err))
74 f12e1736 René Nussbaumer
75 f12e1736 René Nussbaumer
76 f12e1736 René Nussbaumer
class GetentResolver:
77 f12e1736 René Nussbaumer
  """Resolves Ganeti uids and gids by name.
78 f12e1736 René Nussbaumer

79 f12e1736 René Nussbaumer
  @ivar masterd_uid: The resolved uid of the masterd user
80 f12e1736 René Nussbaumer
  @ivar masterd_gid: The resolved gid of the masterd group
81 f12e1736 René Nussbaumer
  @ivar confd_uid: The resolved uid of the confd user
82 f12e1736 René Nussbaumer
  @ivar confd_gid: The resolved gid of the confd group
83 3695a4e0 Thomas Thrainer
  @ivar luxid_uid: The resolved uid of the luxid user
84 3695a4e0 Thomas Thrainer
  @ivar luxid_gid: The resolved gid of the luxid group
85 f12e1736 René Nussbaumer
  @ivar rapi_uid: The resolved uid of the rapi user
86 f12e1736 René Nussbaumer
  @ivar rapi_gid: The resolved gid of the rapi group
87 f12e1736 René Nussbaumer
  @ivar noded_uid: The resolved uid of the noded user
88 f12e1736 René Nussbaumer
  @ivar daemons_gid: The resolved gid of the daemons group
89 f12e1736 René Nussbaumer
  @ivar admin_gid: The resolved gid of the admin group
90 f00170e2 Michael Hanselmann

91 f12e1736 René Nussbaumer
  """
92 f12e1736 René Nussbaumer
  def __init__(self, _getpwnam=pwd.getpwnam, _getgrnam=grp.getgrnam):
93 f12e1736 René Nussbaumer
    """Initialize the resolver.
94 f12e1736 René Nussbaumer

95 f12e1736 René Nussbaumer
    """
96 f12e1736 René Nussbaumer
    # Daemon pairs
97 f12e1736 René Nussbaumer
    self.masterd_uid = GetUid(constants.MASTERD_USER, _getpwnam)
98 f12e1736 René Nussbaumer
    self.masterd_gid = GetGid(constants.MASTERD_GROUP, _getgrnam)
99 f12e1736 René Nussbaumer
100 f12e1736 René Nussbaumer
    self.confd_uid = GetUid(constants.CONFD_USER, _getpwnam)
101 f12e1736 René Nussbaumer
    self.confd_gid = GetGid(constants.CONFD_GROUP, _getgrnam)
102 f12e1736 René Nussbaumer
103 3695a4e0 Thomas Thrainer
    self.luxid_uid = GetUid(constants.LUXID_USER, _getpwnam)
104 3695a4e0 Thomas Thrainer
    self.luxid_gid = GetGid(constants.LUXID_GROUP, _getgrnam)
105 670e954a Thomas Thrainer
106 f12e1736 René Nussbaumer
    self.rapi_uid = GetUid(constants.RAPI_USER, _getpwnam)
107 f12e1736 René Nussbaumer
    self.rapi_gid = GetGid(constants.RAPI_GROUP, _getgrnam)
108 f12e1736 René Nussbaumer
109 f12e1736 René Nussbaumer
    self.noded_uid = GetUid(constants.NODED_USER, _getpwnam)
110 44fbd23b René Nussbaumer
    self.noded_gid = GetGid(constants.NODED_GROUP, _getgrnam)
111 f12e1736 René Nussbaumer
112 d08a8359 Thomas Thrainer
    self.mond_uid = GetUid(constants.MOND_USER, _getpwnam)
113 d08a8359 Thomas Thrainer
    self.mond_gid = GetGid(constants.MOND_GROUP, _getgrnam)
114 d08a8359 Thomas Thrainer
115 f12e1736 René Nussbaumer
    # Misc Ganeti groups
116 f12e1736 René Nussbaumer
    self.daemons_gid = GetGid(constants.DAEMONS_GROUP, _getgrnam)
117 f12e1736 René Nussbaumer
    self.admin_gid = GetGid(constants.ADMIN_GROUP, _getgrnam)
118 f12e1736 René Nussbaumer
119 44fbd23b René Nussbaumer
    self._uid2user = {
120 44fbd23b René Nussbaumer
      self.masterd_uid: constants.MASTERD_USER,
121 44fbd23b René Nussbaumer
      self.confd_uid: constants.CONFD_USER,
122 3695a4e0 Thomas Thrainer
      self.luxid_uid: constants.LUXID_USER,
123 44fbd23b René Nussbaumer
      self.rapi_uid: constants.RAPI_USER,
124 44fbd23b René Nussbaumer
      self.noded_uid: constants.NODED_USER,
125 d08a8359 Thomas Thrainer
      self.mond_uid: constants.MOND_USER,
126 44fbd23b René Nussbaumer
      }
127 44fbd23b René Nussbaumer
128 44fbd23b René Nussbaumer
    self._gid2group = {
129 44fbd23b René Nussbaumer
      self.masterd_gid: constants.MASTERD_GROUP,
130 44fbd23b René Nussbaumer
      self.confd_gid: constants.CONFD_GROUP,
131 3695a4e0 Thomas Thrainer
      self.luxid_gid: constants.LUXID_GROUP,
132 44fbd23b René Nussbaumer
      self.rapi_gid: constants.RAPI_GROUP,
133 44fbd23b René Nussbaumer
      self.noded_gid: constants.NODED_GROUP,
134 d08a8359 Thomas Thrainer
      self.mond_gid: constants.MOND_GROUP,
135 44fbd23b René Nussbaumer
      self.daemons_gid: constants.DAEMONS_GROUP,
136 44fbd23b René Nussbaumer
      self.admin_gid: constants.ADMIN_GROUP,
137 44fbd23b René Nussbaumer
      }
138 44fbd23b René Nussbaumer
139 44fbd23b René Nussbaumer
    self._user2uid = utils.InvertDict(self._uid2user)
140 44fbd23b René Nussbaumer
    self._group2gid = utils.InvertDict(self._gid2group)
141 44fbd23b René Nussbaumer
142 44fbd23b René Nussbaumer
  def LookupUid(self, uid):
143 44fbd23b René Nussbaumer
    """Looks which Ganeti user belongs to this uid.
144 44fbd23b René Nussbaumer

145 44fbd23b René Nussbaumer
    @param uid: The uid to lookup
146 44fbd23b René Nussbaumer
    @returns The user name associated with that uid
147 44fbd23b René Nussbaumer

148 44fbd23b René Nussbaumer
    """
149 44fbd23b René Nussbaumer
    try:
150 44fbd23b René Nussbaumer
      return self._uid2user[uid]
151 44fbd23b René Nussbaumer
    except KeyError:
152 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti uid '%d'" % uid)
153 44fbd23b René Nussbaumer
154 44fbd23b René Nussbaumer
  def LookupGid(self, gid):
155 44fbd23b René Nussbaumer
    """Looks which Ganeti group belongs to this gid.
156 44fbd23b René Nussbaumer

157 44fbd23b René Nussbaumer
    @param gid: The gid to lookup
158 44fbd23b René Nussbaumer
    @returns The group name associated with that gid
159 44fbd23b René Nussbaumer

160 44fbd23b René Nussbaumer
    """
161 44fbd23b René Nussbaumer
    try:
162 44fbd23b René Nussbaumer
      return self._gid2group[gid]
163 44fbd23b René Nussbaumer
    except KeyError:
164 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti gid '%d'" % gid)
165 44fbd23b René Nussbaumer
166 44fbd23b René Nussbaumer
  def LookupUser(self, name):
167 44fbd23b René Nussbaumer
    """Looks which uid belongs to this name.
168 44fbd23b René Nussbaumer

169 44fbd23b René Nussbaumer
    @param name: The name to lookup
170 44fbd23b René Nussbaumer
    @returns The uid associated with that user name
171 44fbd23b René Nussbaumer

172 44fbd23b René Nussbaumer
    """
173 44fbd23b René Nussbaumer
    try:
174 44fbd23b René Nussbaumer
      return self._user2uid[name]
175 44fbd23b René Nussbaumer
    except KeyError:
176 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti user '%s'" % name)
177 44fbd23b René Nussbaumer
178 44fbd23b René Nussbaumer
  def LookupGroup(self, name):
179 44fbd23b René Nussbaumer
    """Looks which gid belongs to this name.
180 44fbd23b René Nussbaumer

181 44fbd23b René Nussbaumer
    @param name: The name to lookup
182 44fbd23b René Nussbaumer
    @returns The gid associated with that group name
183 44fbd23b René Nussbaumer

184 44fbd23b René Nussbaumer
    """
185 44fbd23b René Nussbaumer
    try:
186 44fbd23b René Nussbaumer
      return self._group2gid[name]
187 44fbd23b René Nussbaumer
    except KeyError:
188 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti group '%s'" % name)
189 44fbd23b René Nussbaumer
190 f12e1736 René Nussbaumer
191 f12e1736 René Nussbaumer
def GetEnts(resolver=GetentResolver):
192 f12e1736 René Nussbaumer
  """Singleton wrapper around resolver instance.
193 f12e1736 René Nussbaumer

194 f12e1736 René Nussbaumer
  As this method is accessed by multiple threads at the same time
195 1fdfa87a Iustin Pop
  we need to take thread-safety carefully.
196 f12e1736 René Nussbaumer

197 f12e1736 René Nussbaumer
  """
198 f12e1736 René Nussbaumer
  # We need to use the global keyword here
199 b459a848 Andrea Spadaccini
  global _priv # pylint: disable=W0603
200 f12e1736 René Nussbaumer
201 f12e1736 René Nussbaumer
  if not _priv:
202 f12e1736 René Nussbaumer
    _priv_lock.acquire()
203 f12e1736 René Nussbaumer
    try:
204 f12e1736 René Nussbaumer
      if not _priv:
205 f12e1736 René Nussbaumer
        # W0621: Redefine '_priv' from outer scope (used for singleton)
206 b459a848 Andrea Spadaccini
        _priv = resolver() # pylint: disable=W0621
207 f12e1736 René Nussbaumer
    finally:
208 f12e1736 René Nussbaumer
      _priv_lock.release()
209 f12e1736 René Nussbaumer
210 f12e1736 René Nussbaumer
  return _priv
211 a20e4768 Michael Hanselmann
212 a20e4768 Michael Hanselmann
213 a20e4768 Michael Hanselmann
def InitArchInfo():
214 a20e4768 Michael Hanselmann
  """Initialize architecture information.
215 a20e4768 Michael Hanselmann

216 a20e4768 Michael Hanselmann
  We can assume this information never changes during the lifetime of a
217 a20e4768 Michael Hanselmann
  process, therefore the information can easily be cached.
218 a20e4768 Michael Hanselmann

219 a20e4768 Michael Hanselmann
  @note: This function uses C{platform.architecture} to retrieve the Python
220 a20e4768 Michael Hanselmann
    binary architecture and does so by forking to run C{file} (see Python
221 a20e4768 Michael Hanselmann
    documentation for more information). Therefore it must not be used in a
222 a20e4768 Michael Hanselmann
    multi-threaded environment.
223 a20e4768 Michael Hanselmann

224 a20e4768 Michael Hanselmann
  """
225 a20e4768 Michael Hanselmann
  global _arch # pylint: disable=W0603
226 a20e4768 Michael Hanselmann
227 a20e4768 Michael Hanselmann
  if _arch is not None:
228 a20e4768 Michael Hanselmann
    raise errors.ProgrammerError("Architecture information can only be"
229 a20e4768 Michael Hanselmann
                                 " initialized once")
230 a20e4768 Michael Hanselmann
231 a20e4768 Michael Hanselmann
  _arch = (platform.architecture()[0], platform.machine())
232 a20e4768 Michael Hanselmann
233 a20e4768 Michael Hanselmann
234 a20e4768 Michael Hanselmann
def GetArchInfo():
235 a20e4768 Michael Hanselmann
  """Returns previsouly initialized architecture information.
236 a20e4768 Michael Hanselmann

237 a20e4768 Michael Hanselmann
  """
238 a20e4768 Michael Hanselmann
  if _arch is None:
239 a20e4768 Michael Hanselmann
    raise errors.ProgrammerError("Architecture information hasn't been"
240 a20e4768 Michael Hanselmann
                                 " initialized")
241 a20e4768 Michael Hanselmann
242 a20e4768 Michael Hanselmann
  return _arch
243 a51b19de Helga Velroyen
244 a51b19de Helga Velroyen
245 d75d7772 Klaus Aehlig
def GetClient(query=True):
246 a51b19de Helga Velroyen
  """Connects to the a luxi socket and returns a client.
247 a51b19de Helga Velroyen

248 a51b19de Helga Velroyen
  @type query: boolean
249 a51b19de Helga Velroyen
  @param query: this signifies that the client will only be
250 a51b19de Helga Velroyen
      used for queries; if the build-time parameter
251 a51b19de Helga Velroyen
      enable-split-queries is enabled, then the client will be
252 a51b19de Helga Velroyen
      connected to the query socket instead of the masterd socket
253 a51b19de Helga Velroyen

254 a51b19de Helga Velroyen
  """
255 a51b19de Helga Velroyen
  override_socket = os.getenv(constants.LUXI_OVERRIDE, "")
256 a51b19de Helga Velroyen
  if override_socket:
257 a51b19de Helga Velroyen
    if override_socket == constants.LUXI_OVERRIDE_MASTER:
258 a51b19de Helga Velroyen
      address = pathutils.MASTER_SOCKET
259 a51b19de Helga Velroyen
    elif override_socket == constants.LUXI_OVERRIDE_QUERY:
260 a51b19de Helga Velroyen
      address = pathutils.QUERY_SOCKET
261 a51b19de Helga Velroyen
    else:
262 a51b19de Helga Velroyen
      address = override_socket
263 a51b19de Helga Velroyen
  elif query:
264 a51b19de Helga Velroyen
    address = pathutils.QUERY_SOCKET
265 a51b19de Helga Velroyen
  else:
266 a51b19de Helga Velroyen
    address = None
267 a51b19de Helga Velroyen
  # TODO: Cache object?
268 a51b19de Helga Velroyen
  try:
269 a51b19de Helga Velroyen
    client = luxi.Client(address=address)
270 ff1012ef Petr Pudlak
  except NoMasterError:
271 a51b19de Helga Velroyen
    ss = ssconf.SimpleStore()
272 a51b19de Helga Velroyen
273 a51b19de Helga Velroyen
    # Try to read ssconf file
274 a51b19de Helga Velroyen
    try:
275 a51b19de Helga Velroyen
      ss.GetMasterNode()
276 a51b19de Helga Velroyen
    except errors.ConfigurationError:
277 a51b19de Helga Velroyen
      raise errors.OpPrereqError("Cluster not initialized or this machine is"
278 a51b19de Helga Velroyen
                                 " not part of a cluster",
279 a51b19de Helga Velroyen
                                 errors.ECODE_INVAL)
280 a51b19de Helga Velroyen
281 a51b19de Helga Velroyen
    master, myself = ssconf.GetMasterAndMyself(ss=ss)
282 a51b19de Helga Velroyen
    if master != myself:
283 a51b19de Helga Velroyen
      raise errors.OpPrereqError("This is not the master node, please connect"
284 a51b19de Helga Velroyen
                                 " to node '%s' and rerun the command" %
285 a51b19de Helga Velroyen
                                 master, errors.ECODE_INVAL)
286 a51b19de Helga Velroyen
    raise
287 a51b19de Helga Velroyen
  return client