1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
40 _arch = None
41
42
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
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
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
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
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
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
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
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
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
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
182 global _priv
183
184 if not _priv:
185 _priv_lock.acquire()
186 try:
187 if not _priv:
188
189 _priv = resolver()
190 finally:
191 _priv_lock.release()
192
193 return _priv
194
195
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
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
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