1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 """Module implementing configuration details at runtime.
31
32 """
33
34
35 import grp
36 import pwd
37 import threading
38 import os
39 import platform
40
41 from ganeti import constants
42 from ganeti import errors
43 from ganeti import luxi
44 from ganeti.rpc.errors import NoMasterError
45 from ganeti import pathutils
46 from ganeti import ssconf
47 from ganeti import utils
48
49
50 _priv = None
51 _priv_lock = threading.Lock()
52
53
54 _arch = None
55
56
58 """Retrieve the uid from the database.
59
60 @type user: string
61 @param user: The username to retrieve
62 @return: The resolved uid
63
64 """
65 try:
66 return _getpwnam(user).pw_uid
67 except KeyError, err:
68 raise errors.ConfigurationError("User '%s' not found (%s)" % (user, err))
69
70
72 """Retrieve the gid from the database.
73
74 @type group: string
75 @param group: The group name to retrieve
76 @return: The resolved gid
77
78 """
79 try:
80 return _getgrnam(group).gr_gid
81 except KeyError, err:
82 raise errors.ConfigurationError("Group '%s' not found (%s)" % (group, err))
83
84
86 """Resolves Ganeti uids and gids by name.
87
88 @ivar masterd_uid: The resolved uid of the masterd user
89 @ivar masterd_gid: The resolved gid of the masterd group
90 @ivar confd_uid: The resolved uid of the confd user
91 @ivar confd_gid: The resolved gid of the confd group
92 @ivar luxid_uid: The resolved uid of the luxid user
93 @ivar luxid_gid: The resolved gid of the luxid group
94 @ivar rapi_uid: The resolved uid of the rapi user
95 @ivar rapi_gid: The resolved gid of the rapi group
96 @ivar noded_uid: The resolved uid of the noded user
97 @ivar daemons_gid: The resolved gid of the daemons group
98 @ivar admin_gid: The resolved gid of the admin group
99
100 """
101 - def __init__(self, _getpwnam=pwd.getpwnam, _getgrnam=grp.getgrnam):
102 """Initialize the resolver.
103
104 """
105
106 self.masterd_uid = GetUid(constants.MASTERD_USER, _getpwnam)
107 self.masterd_gid = GetGid(constants.MASTERD_GROUP, _getgrnam)
108
109 self.confd_uid = GetUid(constants.CONFD_USER, _getpwnam)
110 self.confd_gid = GetGid(constants.CONFD_GROUP, _getgrnam)
111
112 self.luxid_uid = GetUid(constants.LUXID_USER, _getpwnam)
113 self.luxid_gid = GetGid(constants.LUXID_GROUP, _getgrnam)
114
115 self.rapi_uid = GetUid(constants.RAPI_USER, _getpwnam)
116 self.rapi_gid = GetGid(constants.RAPI_GROUP, _getgrnam)
117
118 self.noded_uid = GetUid(constants.NODED_USER, _getpwnam)
119 self.noded_gid = GetGid(constants.NODED_GROUP, _getgrnam)
120
121 self.mond_uid = GetUid(constants.MOND_USER, _getpwnam)
122 self.mond_gid = GetGid(constants.MOND_GROUP, _getgrnam)
123
124
125 self.daemons_gid = GetGid(constants.DAEMONS_GROUP, _getgrnam)
126 self.admin_gid = GetGid(constants.ADMIN_GROUP, _getgrnam)
127
128 self._uid2user = {
129 self.masterd_uid: constants.MASTERD_USER,
130 self.confd_uid: constants.CONFD_USER,
131 self.luxid_uid: constants.LUXID_USER,
132 self.rapi_uid: constants.RAPI_USER,
133 self.noded_uid: constants.NODED_USER,
134 self.mond_uid: constants.MOND_USER,
135 }
136
137 self._gid2group = {
138 self.masterd_gid: constants.MASTERD_GROUP,
139 self.confd_gid: constants.CONFD_GROUP,
140 self.luxid_gid: constants.LUXID_GROUP,
141 self.rapi_gid: constants.RAPI_GROUP,
142 self.noded_gid: constants.NODED_GROUP,
143 self.mond_gid: constants.MOND_GROUP,
144 self.daemons_gid: constants.DAEMONS_GROUP,
145 self.admin_gid: constants.ADMIN_GROUP,
146 }
147
148 self._user2uid = utils.InvertDict(self._uid2user)
149 self._group2gid = utils.InvertDict(self._gid2group)
150
152 """Looks which Ganeti user belongs to this uid.
153
154 @param uid: The uid to lookup
155 @returns The user name associated with that uid
156
157 """
158 try:
159 return self._uid2user[uid]
160 except KeyError:
161 raise errors.ConfigurationError("Unknown Ganeti uid '%d'" % uid)
162
164 """Looks which Ganeti group belongs to this gid.
165
166 @param gid: The gid to lookup
167 @returns The group name associated with that gid
168
169 """
170 try:
171 return self._gid2group[gid]
172 except KeyError:
173 raise errors.ConfigurationError("Unknown Ganeti gid '%d'" % gid)
174
176 """Looks which uid belongs to this name.
177
178 @param name: The name to lookup
179 @returns The uid associated with that user name
180
181 """
182 try:
183 return self._user2uid[name]
184 except KeyError:
185 raise errors.ConfigurationError("Unknown Ganeti user '%s'" % name)
186
188 """Looks which gid belongs to this name.
189
190 @param name: The name to lookup
191 @returns The gid associated with that group name
192
193 """
194 try:
195 return self._group2gid[name]
196 except KeyError:
197 raise errors.ConfigurationError("Unknown Ganeti group '%s'" % name)
198
199
201 """Singleton wrapper around resolver instance.
202
203 As this method is accessed by multiple threads at the same time
204 we need to take thread-safety carefully.
205
206 """
207
208 global _priv
209
210 if not _priv:
211 _priv_lock.acquire()
212 try:
213 if not _priv:
214
215 _priv = resolver()
216 finally:
217 _priv_lock.release()
218
219 return _priv
220
221
223 """Initialize architecture information.
224
225 We can assume this information never changes during the lifetime of a
226 process, therefore the information can easily be cached.
227
228 @note: This function uses C{platform.architecture} to retrieve the Python
229 binary architecture and does so by forking to run C{file} (see Python
230 documentation for more information). Therefore it must not be used in a
231 multi-threaded environment.
232
233 """
234 global _arch
235
236 if _arch is not None:
237 raise errors.ProgrammerError("Architecture information can only be"
238 " initialized once")
239
240 _arch = (platform.architecture()[0], platform.machine())
241
242
244 """Returns previsouly initialized architecture information.
245
246 """
247 if _arch is None:
248 raise errors.ProgrammerError("Architecture information hasn't been"
249 " initialized")
250
251 return _arch
252
253
297