Revision f12e1736
b/Makefile.am | ||
---|---|---|
124 | 124 |
lib/objects.py \ |
125 | 125 |
lib/opcodes.py \ |
126 | 126 |
lib/rpc.py \ |
127 |
lib/runtime.py \ |
|
127 | 128 |
lib/serializer.py \ |
128 | 129 |
lib/ssconf.py \ |
129 | 130 |
lib/ssh.py \ |
... | ... | |
393 | 394 |
test/ganeti.rapi.resources_unittest.py \ |
394 | 395 |
test/ganeti.rapi.rlib2_unittest.py \ |
395 | 396 |
test/ganeti.rpc_unittest.py \ |
397 |
test/ganeti.runtime_unittest.py \ |
|
396 | 398 |
test/ganeti.serializer_unittest.py \ |
397 | 399 |
test/ganeti.ssh_unittest.py \ |
398 | 400 |
test/ganeti.uidpool_unittest.py \ |
... | ... | |
565 | 567 |
echo "DRBD_BARRIERS = $(DRBD_BARRIERS)"; \ |
566 | 568 |
echo "SYSLOG_USAGE = '$(SYSLOG_USAGE)'"; \ |
567 | 569 |
echo "DAEMONS_GROUP = '$(DAEMONS_GROUP)'"; \ |
570 |
echo "ADMIN_GROUP = '$(ADMIN_GROUP)'"; \ |
|
568 | 571 |
echo "MASTERD_USER = '$(MASTERD_USER)'"; \ |
572 |
echo "MASTERD_GROUP = '$(MASTERD_GROUP)'"; \ |
|
569 | 573 |
echo "RAPI_USER = '$(RAPI_USER)'"; \ |
574 |
echo "RAPI_GROUP = '$(RAPI_GROUP)'"; \ |
|
575 |
echo "CONFD_USER = '$(CONFD_USER)'"; \ |
|
576 |
echo "CONFD_GROUP = '$(CONFD_GROUP)'"; \ |
|
577 |
echo "NODED_USER = '$(NODED_USER)'"; \ |
|
570 | 578 |
echo "VCS_VERSION = '$$VCSVER'"; \ |
571 | 579 |
} > $@ |
572 | 580 |
|
b/lib/constants.py | ||
---|---|---|
86 | 86 |
|
87 | 87 |
# user separation |
88 | 88 |
DAEMONS_GROUP = _autoconf.DAEMONS_GROUP |
89 |
ADMIN_GROUP = _autoconf.ADMIN_GROUP |
|
89 | 90 |
MASTERD_USER = _autoconf.MASTERD_USER |
91 |
MASTERD_GROUP = _autoconf.MASTERD_GROUP |
|
90 | 92 |
RAPI_USER = _autoconf.RAPI_USER |
93 |
RAPI_GROUP = _autoconf.RAPI_GROUP |
|
94 |
CONFD_USER = _autoconf.CONFD_USER |
|
95 |
CONFD_GROUP = _autoconf.CONFD_GROUP |
|
96 |
NODED_USER = _autoconf.NODED_USER |
|
91 | 97 |
|
92 | 98 |
# file paths |
93 | 99 |
DATA_DIR = _autoconf.LOCALSTATEDIR + "/lib/ganeti" |
b/lib/runtime.py | ||
---|---|---|
1 |
# |
|
2 |
|
|
3 |
# Copyright (C) 2010 Google Inc. |
|
4 |
# |
|
5 |
# This program is free software; you can redistribute it and/or modify |
|
6 |
# it under the terms of the GNU General Public License as published by |
|
7 |
# the Free Software Foundation; either version 2 of the License, or |
|
8 |
# (at your option) any later version. |
|
9 |
# |
|
10 |
# This program is distributed in the hope that it will be useful, but |
|
11 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 |
# General Public License for more details. |
|
14 |
# |
|
15 |
# You should have received a copy of the GNU General Public License |
|
16 |
# along with this program; if not, write to the Free Software |
|
17 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
18 |
# 02110-1301, USA. |
|
19 |
|
|
20 |
"""Module implementing configuration details at runtime. |
|
21 |
|
|
22 |
""" |
|
23 |
|
|
24 |
|
|
25 |
import grp |
|
26 |
import pwd |
|
27 |
import threading |
|
28 |
|
|
29 |
from ganeti import constants |
|
30 |
from ganeti import errors |
|
31 |
|
|
32 |
|
|
33 |
_priv = None |
|
34 |
_priv_lock = threading.Lock() |
|
35 |
|
|
36 |
|
|
37 |
def GetUid(user, _getpwnam): |
|
38 |
"""Retrieve the uid from the database. |
|
39 |
|
|
40 |
@type user: string |
|
41 |
@param user: The username to retrieve |
|
42 |
@return: The resolved uid |
|
43 |
|
|
44 |
""" |
|
45 |
try: |
|
46 |
return _getpwnam(user).pw_uid |
|
47 |
except KeyError, err: |
|
48 |
raise errors.ConfigurationError("User '%s' not found (%s)" % (user, err)) |
|
49 |
|
|
50 |
|
|
51 |
def GetGid(group, _getgrnam): |
|
52 |
"""Retrieve the gid from the database. |
|
53 |
|
|
54 |
@type group: string |
|
55 |
@param group: The group name to retrieve |
|
56 |
@return: The resolved gid |
|
57 |
|
|
58 |
""" |
|
59 |
try: |
|
60 |
return _getgrnam(group).gr_gid |
|
61 |
except KeyError, err: |
|
62 |
raise errors.ConfigurationError("Group '%s' not found (%s)" % (group, err)) |
|
63 |
|
|
64 |
|
|
65 |
class GetentResolver: |
|
66 |
"""Resolves Ganeti uids and gids by name. |
|
67 |
|
|
68 |
@ivar masterd_uid: The resolved uid of the masterd user |
|
69 |
@ivar masterd_gid: The resolved gid of the masterd group |
|
70 |
@ivar confd_uid: The resolved uid of the confd user |
|
71 |
@ivar confd_gid: The resolved gid of the confd group |
|
72 |
@ivar rapi_uid: The resolved uid of the rapi user |
|
73 |
@ivar rapi_gid: The resolved gid of the rapi group |
|
74 |
@ivar noded_uid: The resolved uid of the noded user |
|
75 |
|
|
76 |
@ivar daemons_gid: The resolved gid of the daemons group |
|
77 |
@ivar admin_gid: The resolved gid of the admin group |
|
78 |
""" |
|
79 |
def __init__(self, _getpwnam=pwd.getpwnam, _getgrnam=grp.getgrnam): |
|
80 |
"""Initialize the resolver. |
|
81 |
|
|
82 |
""" |
|
83 |
# Daemon pairs |
|
84 |
self.masterd_uid = GetUid(constants.MASTERD_USER, _getpwnam) |
|
85 |
self.masterd_gid = GetGid(constants.MASTERD_GROUP, _getgrnam) |
|
86 |
|
|
87 |
self.confd_uid = GetUid(constants.CONFD_USER, _getpwnam) |
|
88 |
self.confd_gid = GetGid(constants.CONFD_GROUP, _getgrnam) |
|
89 |
|
|
90 |
self.rapi_uid = GetUid(constants.RAPI_USER, _getpwnam) |
|
91 |
self.rapi_gid = GetGid(constants.RAPI_GROUP, _getgrnam) |
|
92 |
|
|
93 |
self.noded_uid = GetUid(constants.NODED_USER, _getpwnam) |
|
94 |
|
|
95 |
# Misc Ganeti groups |
|
96 |
self.daemons_gid = GetGid(constants.DAEMONS_GROUP, _getgrnam) |
|
97 |
self.admin_gid = GetGid(constants.ADMIN_GROUP, _getgrnam) |
|
98 |
|
|
99 |
|
|
100 |
def GetEnts(resolver=GetentResolver): |
|
101 |
"""Singleton wrapper around resolver instance. |
|
102 |
|
|
103 |
As this method is accessed by multiple threads at the same time |
|
104 |
we need to take thread-safty carefully |
|
105 |
|
|
106 |
""" |
|
107 |
# We need to use the global keyword here |
|
108 |
global _priv # pylint: disable-msg=W0603 |
|
109 |
|
|
110 |
if not _priv: |
|
111 |
_priv_lock.acquire() |
|
112 |
try: |
|
113 |
if not _priv: |
|
114 |
# W0621: Redefine '_priv' from outer scope (used for singleton) |
|
115 |
_priv = resolver() # pylint: disable-msg=W0621 |
|
116 |
finally: |
|
117 |
_priv_lock.release() |
|
118 |
|
|
119 |
return _priv |
|
120 |
|
b/test/ganeti.runtime_unittest.py | ||
---|---|---|
1 |
#!/usr/bin/python |
|
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 |
"""Script for testing ganeti.runtime""" |
|
22 |
|
|
23 |
from ganeti import constants |
|
24 |
from ganeti import errors |
|
25 |
from ganeti import runtime |
|
26 |
|
|
27 |
import testutils |
|
28 |
|
|
29 |
|
|
30 |
class _EntStub: |
|
31 |
def __init__(self, uid=None, gid=None): |
|
32 |
self.pw_uid = uid |
|
33 |
self.gr_gid = gid |
|
34 |
|
|
35 |
|
|
36 |
def _StubGetpwnam(user): |
|
37 |
users = { |
|
38 |
constants.MASTERD_USER: _EntStub(uid=0), |
|
39 |
constants.CONFD_USER: _EntStub(uid=1), |
|
40 |
constants.RAPI_USER: _EntStub(uid=2), |
|
41 |
constants.NODED_USER: _EntStub(uid=3), |
|
42 |
} |
|
43 |
return users[user] |
|
44 |
|
|
45 |
|
|
46 |
def _StubGetgrnam(group): |
|
47 |
groups = { |
|
48 |
constants.MASTERD_GROUP: _EntStub(gid=0), |
|
49 |
constants.CONFD_GROUP: _EntStub(gid=1), |
|
50 |
constants.RAPI_GROUP: _EntStub(gid=2), |
|
51 |
constants.DAEMONS_GROUP: _EntStub(gid=3), |
|
52 |
constants.ADMIN_GROUP: _EntStub(gid=4), |
|
53 |
} |
|
54 |
return groups[group] |
|
55 |
|
|
56 |
|
|
57 |
def _RaisingStubGetpwnam(user): |
|
58 |
raise KeyError("user not found") |
|
59 |
|
|
60 |
|
|
61 |
def _RaisingStubGetgrnam(group): |
|
62 |
raise KeyError("group not found") |
|
63 |
|
|
64 |
|
|
65 |
class ResolverStubRaising(object): |
|
66 |
def __init__(self): |
|
67 |
raise errors.ConfigurationError("No entries") |
|
68 |
|
|
69 |
|
|
70 |
class TestErrors(testutils.GanetiTestCase): |
|
71 |
def testEverythingSuccessful(self): |
|
72 |
resolver = runtime.GetentResolver(_getpwnam=_StubGetpwnam, |
|
73 |
_getgrnam=_StubGetgrnam) |
|
74 |
|
|
75 |
self.assertEqual(resolver.masterd_uid, |
|
76 |
_StubGetpwnam(constants.MASTERD_USER).pw_uid) |
|
77 |
self.assertEqual(resolver.masterd_gid, |
|
78 |
_StubGetgrnam(constants.MASTERD_GROUP).gr_gid) |
|
79 |
self.assertEqual(resolver.confd_uid, |
|
80 |
_StubGetpwnam(constants.CONFD_USER).pw_uid) |
|
81 |
self.assertEqual(resolver.confd_gid, |
|
82 |
_StubGetgrnam(constants.CONFD_GROUP).gr_gid) |
|
83 |
self.assertEqual(resolver.rapi_uid, |
|
84 |
_StubGetpwnam(constants.RAPI_USER).pw_uid) |
|
85 |
self.assertEqual(resolver.rapi_gid, |
|
86 |
_StubGetgrnam(constants.RAPI_GROUP).gr_gid) |
|
87 |
self.assertEqual(resolver.noded_uid, |
|
88 |
_StubGetpwnam(constants.NODED_USER).pw_uid) |
|
89 |
|
|
90 |
self.assertEqual(resolver.daemons_gid, |
|
91 |
_StubGetgrnam(constants.DAEMONS_GROUP).gr_gid) |
|
92 |
self.assertEqual(resolver.admin_gid, |
|
93 |
_StubGetgrnam(constants.ADMIN_GROUP).gr_gid) |
|
94 |
|
|
95 |
def testUserNotFound(self): |
|
96 |
self.assertRaises(errors.ConfigurationError, runtime.GetentResolver, |
|
97 |
_getpwnam=_RaisingStubGetpwnam, _getgrnam=_StubGetgrnam) |
|
98 |
|
|
99 |
def testGroupNotFound(self): |
|
100 |
self.assertRaises(errors.ConfigurationError, runtime.GetentResolver, |
|
101 |
_getpwnam=_StubGetpwnam, _getgrnam=_RaisingStubGetgrnam) |
|
102 |
|
|
103 |
def testUserNotFoundGetEnts(self): |
|
104 |
self.assertRaises(errors.ConfigurationError, runtime.GetEnts, |
|
105 |
resolver=ResolverStubRaising) |
|
106 |
|
|
107 |
|
|
108 |
if __name__ == "__main__": |
|
109 |
testutils.GanetiTestProgram() |
Also available in: Unified diff