Package ganeti :: Module runtime
[hide private]
[frames] | no frames]

Source Code for Module ganeti.runtime

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2010 Google Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, but 
 12  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 14  # General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 19  # 02110-1301, USA. 
 20   
 21  """Module implementing configuration details at runtime. 
 22   
 23  """ 
 24   
 25   
 26  import grp 
 27  import pwd 
 28  import threading 
 29  import platform 
 30   
 31  from ganeti import constants 
 32  from ganeti import errors 
 33  from ganeti import utils 
 34   
 35   
 36  _priv = None 
 37  _priv_lock = threading.Lock() 
 38   
 39  #: Architecture information 
 40  _arch = None 
 41   
 42   
43 -def GetUid(user, _getpwnam):
44 """Retrieve the uid from the database. 45 46 @type user: string 47 @param user: The username to retrieve 48 @return: The resolved uid 49 50 """ 51 try: 52 return _getpwnam(user).pw_uid 53 except KeyError, err: 54 raise errors.ConfigurationError("User '%s' not found (%s)" % (user, err))
55 56
57 -def GetGid(group, _getgrnam):
58 """Retrieve the gid from the database. 59 60 @type group: string 61 @param group: The group name to retrieve 62 @return: The resolved gid 63 64 """ 65 try: 66 return _getgrnam(group).gr_gid 67 except KeyError, err: 68 raise errors.ConfigurationError("Group '%s' not found (%s)" % (group, err))
69 70
71 -class GetentResolver:
72 """Resolves Ganeti uids and gids by name. 73 74 @ivar masterd_uid: The resolved uid of the masterd user 75 @ivar masterd_gid: The resolved gid of the masterd group 76 @ivar confd_uid: The resolved uid of the confd user 77 @ivar confd_gid: The resolved gid of the confd group 78 @ivar rapi_uid: The resolved uid of the rapi user 79 @ivar rapi_gid: The resolved gid of the rapi group 80 @ivar noded_uid: The resolved uid of the noded user 81 @ivar daemons_gid: The resolved gid of the daemons group 82 @ivar admin_gid: The resolved gid of the admin group 83 84 """
85 - def __init__(self, _getpwnam=pwd.getpwnam, _getgrnam=grp.getgrnam):
86 """Initialize the resolver. 87 88 """ 89 # Daemon pairs 90 self.masterd_uid = GetUid(constants.MASTERD_USER, _getpwnam) 91 self.masterd_gid = GetGid(constants.MASTERD_GROUP, _getgrnam) 92 93 self.confd_uid = GetUid(constants.CONFD_USER, _getpwnam) 94 self.confd_gid = GetGid(constants.CONFD_GROUP, _getgrnam) 95 96 self.rapi_uid = GetUid(constants.RAPI_USER, _getpwnam) 97 self.rapi_gid = GetGid(constants.RAPI_GROUP, _getgrnam) 98 99 self.noded_uid = GetUid(constants.NODED_USER, _getpwnam) 100 self.noded_gid = GetGid(constants.NODED_GROUP, _getgrnam) 101 102 # Misc Ganeti groups 103 self.daemons_gid = GetGid(constants.DAEMONS_GROUP, _getgrnam) 104 self.admin_gid = GetGid(constants.ADMIN_GROUP, _getgrnam) 105 106 self._uid2user = { 107 self.masterd_uid: constants.MASTERD_USER, 108 self.confd_uid: constants.CONFD_USER, 109 self.rapi_uid: constants.RAPI_USER, 110 self.noded_uid: constants.NODED_USER, 111 } 112 113 self._gid2group = { 114 self.masterd_gid: constants.MASTERD_GROUP, 115 self.confd_gid: constants.CONFD_GROUP, 116 self.rapi_gid: constants.RAPI_GROUP, 117 self.noded_gid: constants.NODED_GROUP, 118 self.daemons_gid: constants.DAEMONS_GROUP, 119 self.admin_gid: constants.ADMIN_GROUP, 120 } 121 122 self._user2uid = utils.InvertDict(self._uid2user) 123 self._group2gid = utils.InvertDict(self._gid2group)
124
125 - def LookupUid(self, uid):
126 """Looks which Ganeti user belongs to this uid. 127 128 @param uid: The uid to lookup 129 @returns The user name associated with that uid 130 131 """ 132 try: 133 return self._uid2user[uid] 134 except KeyError: 135 raise errors.ConfigurationError("Unknown Ganeti uid '%d'" % uid)
136
137 - def LookupGid(self, gid):
138 """Looks which Ganeti group belongs to this gid. 139 140 @param gid: The gid to lookup 141 @returns The group name associated with that gid 142 143 """ 144 try: 145 return self._gid2group[gid] 146 except KeyError: 147 raise errors.ConfigurationError("Unknown Ganeti gid '%d'" % gid)
148
149 - def LookupUser(self, name):
150 """Looks which uid belongs to this name. 151 152 @param name: The name to lookup 153 @returns The uid associated with that user name 154 155 """ 156 try: 157 return self._user2uid[name] 158 except KeyError: 159 raise errors.ConfigurationError("Unknown Ganeti user '%s'" % name)
160
161 - def LookupGroup(self, name):
162 """Looks which gid belongs to this name. 163 164 @param name: The name to lookup 165 @returns The gid associated with that group name 166 167 """ 168 try: 169 return self._group2gid[name] 170 except KeyError: 171 raise errors.ConfigurationError("Unknown Ganeti group '%s'" % name)
172 173
174 -def GetEnts(resolver=GetentResolver):
175 """Singleton wrapper around resolver instance. 176 177 As this method is accessed by multiple threads at the same time 178 we need to take thread-safety carefully. 179 180 """ 181 # We need to use the global keyword here 182 global _priv # pylint: disable=W0603 183 184 if not _priv: 185 _priv_lock.acquire() 186 try: 187 if not _priv: 188 # W0621: Redefine '_priv' from outer scope (used for singleton) 189 _priv = resolver() # pylint: disable=W0621 190 finally: 191 _priv_lock.release() 192 193 return _priv
194 195
196 -def InitArchInfo():
197 """Initialize architecture information. 198 199 We can assume this information never changes during the lifetime of a 200 process, therefore the information can easily be cached. 201 202 @note: This function uses C{platform.architecture} to retrieve the Python 203 binary architecture and does so by forking to run C{file} (see Python 204 documentation for more information). Therefore it must not be used in a 205 multi-threaded environment. 206 207 """ 208 global _arch # pylint: disable=W0603 209 210 if _arch is not None: 211 raise errors.ProgrammerError("Architecture information can only be" 212 " initialized once") 213 214 _arch = (platform.architecture()[0], platform.machine())
215 216
217 -def GetArchInfo():
218 """Returns previsouly initialized architecture information. 219 220 """ 221 if _arch is None: 222 raise errors.ProgrammerError("Architecture information hasn't been" 223 " initialized") 224 225 return _arch
226