Statistics
| Branch: | Tag: | Revision:

root / lib / tools / ensure_dirs.py @ 3329f4de

History | View | Annotate | Download (8 kB)

1
#
2
#
3

    
4
# Copyright (C) 2011 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 to ensure permissions on files/dirs are accurate.
22

23
"""
24

    
25
import os
26
import os.path
27
import optparse
28
import sys
29
import logging
30

    
31
from ganeti import constants
32
from ganeti import errors
33
from ganeti import runtime
34
from ganeti import ssconf
35
from ganeti import utils
36
from ganeti import cli
37
from ganeti import pathutils
38

    
39

    
40
(DIR,
41
 FILE,
42
 QUEUE_DIR) = range(1, 4)
43

    
44
ALL_TYPES = frozenset([
45
  DIR,
46
  FILE,
47
  QUEUE_DIR,
48
  ])
49

    
50

    
51
def RecursiveEnsure(path, uid, gid, dir_perm, file_perm):
52
  """Ensures permissions recursively down a directory.
53

54
  This functions walks the path and sets permissions accordingly.
55

56
  @param path: The absolute path to walk
57
  @param uid: The uid used as owner
58
  @param gid: The gid used as group
59
  @param dir_perm: The permission bits set for directories
60
  @param file_perm: The permission bits set for files
61

62
  """
63
  assert os.path.isabs(path), "Path %s is not absolute" % path
64
  assert os.path.isdir(path), "Path %s is not a dir" % path
65

    
66
  logging.debug("Recursively processing %s", path)
67

    
68
  for root, dirs, files in os.walk(path):
69
    for subdir in dirs:
70
      utils.EnforcePermission(os.path.join(root, subdir), dir_perm, uid=uid,
71
                              gid=gid)
72

    
73
    for filename in files:
74
      utils.EnforcePermission(os.path.join(root, filename), file_perm, uid=uid,
75
                              gid=gid)
76

    
77

    
78
def EnsureQueueDir(path, mode, uid, gid):
79
  """Sets the correct permissions on all job files in the queue.
80

81
  @param path: Directory path
82
  @param mode: Wanted file mode
83
  @param uid: Wanted user ID
84
  @param gid: Wanted group ID
85

86
  """
87
  for filename in utils.ListVisibleFiles(path):
88
    if constants.JOB_FILE_RE.match(filename):
89
      utils.EnforcePermission(utils.PathJoin(path, filename), mode, uid=uid,
90
                              gid=gid)
91

    
92

    
93
def ProcessPath(path):
94
  """Processes a path component.
95

96
  @param path: A tuple of the path component to process
97

98
  """
99
  (pathname, pathtype, mode, uid, gid) = path[0:5]
100

    
101
  assert pathtype in ALL_TYPES
102

    
103
  if pathtype in (DIR, QUEUE_DIR):
104
    # No additional parameters
105
    assert len(path[5:]) == 0
106
    if pathtype == DIR:
107
      utils.MakeDirWithPerm(pathname, mode, uid, gid)
108
    elif pathtype == QUEUE_DIR:
109
      EnsureQueueDir(pathname, mode, uid, gid)
110
  elif pathtype == FILE:
111
    (must_exist, ) = path[5:]
112
    utils.EnforcePermission(pathname, mode, uid=uid, gid=gid,
113
                            must_exist=must_exist)
114

    
115

    
116
def GetPaths():
117
  """Returns a tuple of path objects to process.
118

119
  """
120
  getent = runtime.GetEnts()
121
  masterd_log = pathutils.GetLogFilename(constants.MASTERD)
122
  noded_log = pathutils.GetLogFilename(constants.NODED)
123
  confd_log = pathutils.GetLogFilename(constants.CONFD)
124
  rapi_log = pathutils.GetLogFilename(constants.RAPI)
125

    
126
  rapi_dir = os.path.join(constants.DATA_DIR, "rapi")
127

    
128
  paths = [
129
    (constants.DATA_DIR, DIR, 0755, getent.masterd_uid,
130
     getent.masterd_gid),
131
    (constants.CLUSTER_DOMAIN_SECRET_FILE, FILE, 0640,
132
     getent.masterd_uid, getent.masterd_gid, False),
133
    (constants.CLUSTER_CONF_FILE, FILE, 0640, getent.masterd_uid,
134
     getent.confd_gid, False),
135
    (constants.CONFD_HMAC_KEY, FILE, 0440, getent.confd_uid,
136
     getent.masterd_gid, False),
137
    (constants.SSH_KNOWN_HOSTS_FILE, FILE, 0644, getent.masterd_uid,
138
     getent.masterd_gid, False),
139
    (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid,
140
     getent.masterd_gid, False),
141
    (constants.SPICE_CERT_FILE, FILE, 0440, getent.noded_uid,
142
     getent.masterd_gid, False),
143
    (constants.SPICE_CACERT_FILE, FILE, 0440, getent.noded_uid,
144
     getent.masterd_gid, False),
145
    (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid,
146
     getent.masterd_gid, False),
147
    ]
148

    
149
  ss = ssconf.SimpleStore()
150
  for ss_path in ss.GetFileList():
151
    paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
152
                  getent.noded_uid, 0, False))
153

    
154
  paths.extend([
155
    (constants.QUEUE_DIR, DIR, 0700, getent.masterd_uid,
156
     getent.masterd_gid),
157
    (constants.QUEUE_DIR, QUEUE_DIR, 0600, getent.masterd_uid,
158
     getent.masterd_gid),
159
    (constants.JOB_QUEUE_LOCK_FILE, FILE, 0600,
160
     getent.masterd_uid, getent.masterd_gid, False),
161
    (constants.JOB_QUEUE_SERIAL_FILE, FILE, 0600,
162
     getent.masterd_uid, getent.masterd_gid, False),
163
    (constants.JOB_QUEUE_VERSION_FILE, FILE, 0600,
164
     getent.masterd_uid, getent.masterd_gid, False),
165
    (constants.JOB_QUEUE_ARCHIVE_DIR, DIR, 0700,
166
     getent.masterd_uid, getent.masterd_gid),
167
    (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
168
    (constants.RAPI_USERS_FILE, FILE, 0640, getent.rapi_uid,
169
     getent.masterd_gid, False),
170
    (constants.RUN_DIR, DIR, 0775, getent.masterd_uid,
171
     getent.daemons_gid),
172
    (constants.SOCKET_DIR, DIR, 0750, getent.masterd_uid,
173
     getent.daemons_gid),
174
    (constants.MASTER_SOCKET, FILE, 0770, getent.masterd_uid,
175
     getent.daemons_gid, False),
176
    (constants.BDEV_CACHE_DIR, DIR, 0755, getent.noded_uid,
177
     getent.masterd_gid),
178
    (constants.UIDPOOL_LOCKDIR, DIR, 0750, getent.noded_uid,
179
     getent.masterd_gid),
180
    (constants.DISK_LINKS_DIR, DIR, 0755, getent.noded_uid,
181
     getent.masterd_gid),
182
    (constants.CRYPTO_KEYS_DIR, DIR, 0700, getent.noded_uid,
183
     getent.masterd_gid),
184
    (constants.IMPORT_EXPORT_DIR, DIR, 0755, getent.noded_uid,
185
     getent.masterd_gid),
186
    (constants.LOG_DIR, DIR, 0770, getent.masterd_uid,
187
     getent.daemons_gid),
188
    (masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid,
189
     False),
190
    (confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False),
191
    (noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False),
192
    (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False),
193
    (constants.LOG_OS_DIR, DIR, 0750, getent.masterd_uid,
194
     getent.daemons_gid),
195
    ])
196

    
197
  return tuple(paths)
198

    
199

    
200
def SetupLogging(opts):
201
  """Configures the logging module.
202

203
  """
204
  formatter = logging.Formatter("%(asctime)s: %(message)s")
205

    
206
  stderr_handler = logging.StreamHandler()
207
  stderr_handler.setFormatter(formatter)
208
  if opts.debug:
209
    stderr_handler.setLevel(logging.NOTSET)
210
  elif opts.verbose:
211
    stderr_handler.setLevel(logging.INFO)
212
  else:
213
    stderr_handler.setLevel(logging.WARNING)
214

    
215
  root_logger = logging.getLogger("")
216
  root_logger.setLevel(logging.NOTSET)
217
  root_logger.addHandler(stderr_handler)
218

    
219

    
220
def ParseOptions():
221
  """Parses the options passed to the program.
222

223
  @return: Options and arguments
224

225
  """
226
  program = os.path.basename(sys.argv[0])
227

    
228
  parser = optparse.OptionParser(usage="%%prog [--full-run]",
229
                                 prog=program)
230
  parser.add_option(cli.DEBUG_OPT)
231
  parser.add_option(cli.VERBOSE_OPT)
232
  parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
233
                    default=False, help=("Make a full run and set permissions"
234
                                         " on archived jobs (time consuming)"))
235

    
236
  return parser.parse_args()
237

    
238

    
239
def Main():
240
  """Main routine.
241

242
  """
243
  (opts, _) = ParseOptions()
244

    
245
  SetupLogging(opts)
246

    
247
  if opts.full_run:
248
    logging.info("Running in full mode")
249

    
250
  getent = runtime.GetEnts()
251

    
252
  try:
253
    for path in GetPaths():
254
      ProcessPath(path)
255

    
256
    if opts.full_run:
257
      RecursiveEnsure(constants.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
258
                      getent.masterd_gid, 0700, 0600)
259
  except errors.GenericError, err:
260
    logging.error("An error occurred while setting permissions: %s", err)
261
    return constants.EXIT_FAILURE
262

    
263
  return constants.EXIT_SUCCESS