Statistics
| Branch: | Tag: | Revision:

root / lib / runtime.py @ f00170e2

History | View | Annotate | Download (5.3 kB)

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

    
30
from ganeti import constants
31
from ganeti import errors
32
from ganeti import utils
33

    
34

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

    
38

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

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

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

    
52

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

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

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

    
66

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

70
  @ivar masterd_uid: The resolved uid of the masterd user
71
  @ivar masterd_gid: The resolved gid of the masterd group
72
  @ivar confd_uid: The resolved uid of the confd user
73
  @ivar confd_gid: The resolved gid of the confd group
74
  @ivar rapi_uid: The resolved uid of the rapi user
75
  @ivar rapi_gid: The resolved gid of the rapi group
76
  @ivar noded_uid: The resolved uid of the noded user
77
  @ivar daemons_gid: The resolved gid of the daemons group
78
  @ivar admin_gid: The resolved gid of the admin group
79

80
  """
81
  def __init__(self, _getpwnam=pwd.getpwnam, _getgrnam=grp.getgrnam):
82
    """Initialize the resolver.
83

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
169

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

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

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

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

    
189
  return _priv