Statistics
| Branch: | Tag: | Revision:

root / lib / runtime.py @ 44fbd23b

History | View | Annotate | Download (5.3 kB)

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
from ganeti import utils
32

    
33

    
34
_priv = None
35
_priv_lock = threading.Lock()
36

    
37

    
38
def GetUid(user, _getpwnam):
39
  """Retrieve the uid from the database.
40

41
  @type user: string
42
  @param user: The username to retrieve
43
  @return: The resolved uid
44

45
  """
46
  try:
47
    return _getpwnam(user).pw_uid
48
  except KeyError, err:
49
    raise errors.ConfigurationError("User '%s' not found (%s)" % (user, err))
50

    
51

    
52
def GetGid(group, _getgrnam):
53
  """Retrieve the gid from the database.
54

55
  @type group: string
56
  @param group: The group name to retrieve
57
  @return: The resolved gid
58

59
  """
60
  try:
61
    return _getgrnam(group).gr_gid
62
  except KeyError, err:
63
    raise errors.ConfigurationError("Group '%s' not found (%s)" % (group, err))
64

    
65

    
66
class GetentResolver:
67
  """Resolves Ganeti uids and gids by name.
68

69
  @ivar masterd_uid: The resolved uid of the masterd user
70
  @ivar masterd_gid: The resolved gid of the masterd group
71
  @ivar confd_uid: The resolved uid of the confd user
72
  @ivar confd_gid: The resolved gid of the confd group
73
  @ivar rapi_uid: The resolved uid of the rapi user
74
  @ivar rapi_gid: The resolved gid of the rapi group
75
  @ivar noded_uid: The resolved uid of the noded user
76

77
  @ivar daemons_gid: The resolved gid of the daemons group
78
  @ivar admin_gid: The resolved gid of the admin group
79
  """
80
  def __init__(self, _getpwnam=pwd.getpwnam, _getgrnam=grp.getgrnam):
81
    """Initialize the resolver.
82

83
    """
84
    # Daemon pairs
85
    self.masterd_uid = GetUid(constants.MASTERD_USER, _getpwnam)
86
    self.masterd_gid = GetGid(constants.MASTERD_GROUP, _getgrnam)
87

    
88
    self.confd_uid = GetUid(constants.CONFD_USER, _getpwnam)
89
    self.confd_gid = GetGid(constants.CONFD_GROUP, _getgrnam)
90

    
91
    self.rapi_uid = GetUid(constants.RAPI_USER, _getpwnam)
92
    self.rapi_gid = GetGid(constants.RAPI_GROUP, _getgrnam)
93

    
94
    self.noded_uid = GetUid(constants.NODED_USER, _getpwnam)
95
    self.noded_gid = GetGid(constants.NODED_GROUP, _getgrnam)
96

    
97
    # Misc Ganeti groups
98
    self.daemons_gid = GetGid(constants.DAEMONS_GROUP, _getgrnam)
99
    self.admin_gid = GetGid(constants.ADMIN_GROUP, _getgrnam)
100

    
101
    self._uid2user = {
102
      self.masterd_uid: constants.MASTERD_USER,
103
      self.confd_uid: constants.CONFD_USER,
104
      self.rapi_uid: constants.RAPI_USER,
105
      self.noded_uid: constants.NODED_USER,
106
      }
107

    
108
    self._gid2group = {
109
      self.masterd_gid: constants.MASTERD_GROUP,
110
      self.confd_gid: constants.CONFD_GROUP,
111
      self.rapi_gid: constants.RAPI_GROUP,
112
      self.noded_gid: constants.NODED_GROUP,
113
      self.daemons_gid: constants.DAEMONS_GROUP,
114
      self.admin_gid: constants.ADMIN_GROUP,
115
      }
116

    
117
    self._user2uid = utils.InvertDict(self._uid2user)
118
    self._group2gid = utils.InvertDict(self._gid2group)
119

    
120
  def LookupUid(self, uid):
121
    """Looks which Ganeti user belongs to this uid.
122

123
    @param uid: The uid to lookup
124
    @returns The user name associated with that uid
125

126
    """
127
    try:
128
      return self._uid2user[uid]
129
    except KeyError:
130
      raise errors.ConfigurationError("Unknown Ganeti uid '%d'" % uid)
131

    
132
  def LookupGid(self, gid):
133
    """Looks which Ganeti group belongs to this gid.
134

135
    @param gid: The gid to lookup
136
    @returns The group name associated with that gid
137

138
    """
139
    try:
140
      return self._gid2group[gid]
141
    except KeyError:
142
      raise errors.ConfigurationError("Unknown Ganeti gid '%d'" % gid)
143

    
144
  def LookupUser(self, name):
145
    """Looks which uid belongs to this name.
146

147
    @param name: The name to lookup
148
    @returns The uid associated with that user name
149

150
    """
151
    try:
152
      return self._user2uid[name]
153
    except KeyError:
154
      raise errors.ConfigurationError("Unknown Ganeti user '%s'" % name)
155

    
156
  def LookupGroup(self, name):
157
    """Looks which gid belongs to this name.
158

159
    @param name: The name to lookup
160
    @returns The gid associated with that group name
161

162
    """
163
    try:
164
      return self._group2gid[name]
165
    except KeyError:
166
      raise errors.ConfigurationError("Unknown Ganeti group '%s'" % name)
167

    
168

    
169
def GetEnts(resolver=GetentResolver):
170
  """Singleton wrapper around resolver instance.
171

172
  As this method is accessed by multiple threads at the same time
173
  we need to take thread-safty carefully
174

175
  """
176
  # We need to use the global keyword here
177
  global _priv # pylint: disable-msg=W0603
178

    
179
  if not _priv:
180
    _priv_lock.acquire()
181
    try:
182
      if not _priv:
183
        # W0621: Redefine '_priv' from outer scope (used for singleton)
184
        _priv = resolver() # pylint: disable-msg=W0621
185
    finally:
186
      _priv_lock.release()
187

    
188
  return _priv
189