Statistics
| Branch: | Tag: | Revision:

root / lib / runtime.py @ f3aebf6f

History | View | Annotate | Download (8 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 a20e4768 Michael Hanselmann
import platform
30 f12e1736 René Nussbaumer
31 f12e1736 René Nussbaumer
from ganeti import constants
32 f12e1736 René Nussbaumer
from ganeti import errors
33 a51b19de Helga Velroyen
from ganeti import luxi
34 ff1012ef Petr Pudlak
from ganeti.rpc.errors import NoMasterError
35 a51b19de Helga Velroyen
from ganeti import pathutils
36 a51b19de Helga Velroyen
from ganeti import ssconf
37 44fbd23b René Nussbaumer
from ganeti import utils
38 f12e1736 René Nussbaumer
39 f12e1736 René Nussbaumer
40 f12e1736 René Nussbaumer
_priv = None
41 f12e1736 René Nussbaumer
_priv_lock = threading.Lock()
42 f12e1736 René Nussbaumer
43 a20e4768 Michael Hanselmann
#: Architecture information
44 a20e4768 Michael Hanselmann
_arch = None
45 a20e4768 Michael Hanselmann
46 f12e1736 René Nussbaumer
47 f12e1736 René Nussbaumer
def GetUid(user, _getpwnam):
48 f12e1736 René Nussbaumer
  """Retrieve the uid from the database.
49 f12e1736 René Nussbaumer

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

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

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

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

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

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

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

151 44fbd23b René Nussbaumer
    @param uid: The uid to lookup
152 44fbd23b René Nussbaumer
    @returns The user name associated with that uid
153 44fbd23b René Nussbaumer

154 44fbd23b René Nussbaumer
    """
155 44fbd23b René Nussbaumer
    try:
156 44fbd23b René Nussbaumer
      return self._uid2user[uid]
157 44fbd23b René Nussbaumer
    except KeyError:
158 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti uid '%d'" % uid)
159 44fbd23b René Nussbaumer
160 44fbd23b René Nussbaumer
  def LookupGid(self, gid):
161 44fbd23b René Nussbaumer
    """Looks which Ganeti group belongs to this gid.
162 44fbd23b René Nussbaumer

163 44fbd23b René Nussbaumer
    @param gid: The gid to lookup
164 44fbd23b René Nussbaumer
    @returns The group name associated with that gid
165 44fbd23b René Nussbaumer

166 44fbd23b René Nussbaumer
    """
167 44fbd23b René Nussbaumer
    try:
168 44fbd23b René Nussbaumer
      return self._gid2group[gid]
169 44fbd23b René Nussbaumer
    except KeyError:
170 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti gid '%d'" % gid)
171 44fbd23b René Nussbaumer
172 44fbd23b René Nussbaumer
  def LookupUser(self, name):
173 44fbd23b René Nussbaumer
    """Looks which uid belongs to this name.
174 44fbd23b René Nussbaumer

175 44fbd23b René Nussbaumer
    @param name: The name to lookup
176 44fbd23b René Nussbaumer
    @returns The uid associated with that user name
177 44fbd23b René Nussbaumer

178 44fbd23b René Nussbaumer
    """
179 44fbd23b René Nussbaumer
    try:
180 44fbd23b René Nussbaumer
      return self._user2uid[name]
181 44fbd23b René Nussbaumer
    except KeyError:
182 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti user '%s'" % name)
183 44fbd23b René Nussbaumer
184 44fbd23b René Nussbaumer
  def LookupGroup(self, name):
185 44fbd23b René Nussbaumer
    """Looks which gid belongs to this name.
186 44fbd23b René Nussbaumer

187 44fbd23b René Nussbaumer
    @param name: The name to lookup
188 44fbd23b René Nussbaumer
    @returns The gid associated with that group name
189 44fbd23b René Nussbaumer

190 44fbd23b René Nussbaumer
    """
191 44fbd23b René Nussbaumer
    try:
192 44fbd23b René Nussbaumer
      return self._group2gid[name]
193 44fbd23b René Nussbaumer
    except KeyError:
194 44fbd23b René Nussbaumer
      raise errors.ConfigurationError("Unknown Ganeti group '%s'" % name)
195 44fbd23b René Nussbaumer
196 f12e1736 René Nussbaumer
197 f12e1736 René Nussbaumer
def GetEnts(resolver=GetentResolver):
198 f12e1736 René Nussbaumer
  """Singleton wrapper around resolver instance.
199 f12e1736 René Nussbaumer

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

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

222 a20e4768 Michael Hanselmann
  We can assume this information never changes during the lifetime of a
223 a20e4768 Michael Hanselmann
  process, therefore the information can easily be cached.
224 a20e4768 Michael Hanselmann

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

230 a20e4768 Michael Hanselmann
  """
231 a20e4768 Michael Hanselmann
  global _arch # pylint: disable=W0603
232 a20e4768 Michael Hanselmann
233 a20e4768 Michael Hanselmann
  if _arch is not None:
234 a20e4768 Michael Hanselmann
    raise errors.ProgrammerError("Architecture information can only be"
235 a20e4768 Michael Hanselmann
                                 " initialized once")
236 a20e4768 Michael Hanselmann
237 a20e4768 Michael Hanselmann
  _arch = (platform.architecture()[0], platform.machine())
238 a20e4768 Michael Hanselmann
239 a20e4768 Michael Hanselmann
240 a20e4768 Michael Hanselmann
def GetArchInfo():
241 a20e4768 Michael Hanselmann
  """Returns previsouly initialized architecture information.
242 a20e4768 Michael Hanselmann

243 a20e4768 Michael Hanselmann
  """
244 a20e4768 Michael Hanselmann
  if _arch is None:
245 a20e4768 Michael Hanselmann
    raise errors.ProgrammerError("Architecture information hasn't been"
246 a20e4768 Michael Hanselmann
                                 " initialized")
247 a20e4768 Michael Hanselmann
248 a20e4768 Michael Hanselmann
  return _arch
249 a51b19de Helga Velroyen
250 a51b19de Helga Velroyen
251 7f28a87a Klaus Aehlig
def GetClient():
252 a51b19de Helga Velroyen
  """Connects to the a luxi socket and returns a client.
253 a51b19de Helga Velroyen

254 a51b19de Helga Velroyen
  """
255 a51b19de Helga Velroyen
  try:
256 7f28a87a Klaus Aehlig
    client = luxi.Client(address=pathutils.QUERY_SOCKET)
257 ff1012ef Petr Pudlak
  except NoMasterError:
258 a51b19de Helga Velroyen
    ss = ssconf.SimpleStore()
259 a51b19de Helga Velroyen
260 a51b19de Helga Velroyen
    # Try to read ssconf file
261 a51b19de Helga Velroyen
    try:
262 a51b19de Helga Velroyen
      ss.GetMasterNode()
263 a51b19de Helga Velroyen
    except errors.ConfigurationError:
264 a51b19de Helga Velroyen
      raise errors.OpPrereqError("Cluster not initialized or this machine is"
265 a51b19de Helga Velroyen
                                 " not part of a cluster",
266 a51b19de Helga Velroyen
                                 errors.ECODE_INVAL)
267 a51b19de Helga Velroyen
268 a51b19de Helga Velroyen
    master, myself = ssconf.GetMasterAndMyself(ss=ss)
269 a51b19de Helga Velroyen
    if master != myself:
270 a51b19de Helga Velroyen
      raise errors.OpPrereqError("This is not the master node, please connect"
271 a51b19de Helga Velroyen
                                 " to node '%s' and rerun the command" %
272 a51b19de Helga Velroyen
                                 master, errors.ECODE_INVAL)
273 a51b19de Helga Velroyen
    raise
274 a51b19de Helga Velroyen
  return client