Statistics
| Branch: | Tag: | Revision:

root / lib / tools / ensure_dirs.py @ 5d83892f

History | View | Annotate | Download (9.2 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
from ganeti import compat
39

    
40

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

    
45
ALL_TYPES = compat.UniqueFrozenset([
46
  DIR,
47
  FILE,
48
  QUEUE_DIR,
49
  ])
50

    
51

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

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

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

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

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

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

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

    
78

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

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

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

    
93

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

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

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

    
102
  assert pathtype in ALL_TYPES
103

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

    
116

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

120
  """
121
  getent = runtime.GetEnts()
122
  masterd_log = constants.DAEMONS_LOGFILES[constants.MASTERD]
123
  noded_log = constants.DAEMONS_LOGFILES[constants.NODED]
124
  confd_log = constants.DAEMONS_LOGFILES[constants.CONFD]
125
  luxid_log = constants.DAEMONS_LOGFILES[constants.LUXID]
126
  rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI]
127
  mond_log = constants.DAEMONS_LOGFILES[constants.MOND]
128

    
129
  rapi_dir = os.path.join(pathutils.DATA_DIR, "rapi")
130
  cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "cleaner")
131
  master_cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "master-cleaner")
132

    
133
  # A note on the ordering: The parent directory (type C{DIR}) must always be
134
  # listed before files (type C{FILE}) in that directory. Once the directory is
135
  # set, only files directly in that directory can be listed.
136
  paths = [
137
    (pathutils.DATA_DIR, DIR, 0755, getent.masterd_uid, getent.masterd_gid),
138
    (pathutils.CLUSTER_DOMAIN_SECRET_FILE, FILE, 0640,
139
     getent.masterd_uid, getent.masterd_gid, False),
140
    (pathutils.CLUSTER_CONF_FILE, FILE, 0640,
141
     getent.masterd_uid, getent.confd_gid, False),
142
    (pathutils.CONFD_HMAC_KEY, FILE, 0440,
143
     getent.confd_uid, getent.masterd_gid, False),
144
    (pathutils.SSH_KNOWN_HOSTS_FILE, FILE, 0644,
145
     getent.masterd_uid, getent.masterd_gid, False),
146
    (pathutils.RAPI_CERT_FILE, FILE, 0440,
147
     getent.rapi_uid, getent.masterd_gid, False),
148
    (pathutils.SPICE_CERT_FILE, FILE, 0440,
149
     getent.noded_uid, getent.masterd_gid, False),
150
    (pathutils.SPICE_CACERT_FILE, FILE, 0440,
151
     getent.noded_uid, getent.masterd_gid, False),
152
    (pathutils.NODED_CERT_FILE, FILE, pathutils.NODED_CERT_MODE,
153
     getent.masterd_uid, getent.masterd_gid, False),
154
    (pathutils.NODED_CLIENT_CERT_FILE, FILE, pathutils.NODED_CERT_MODE,
155
     getent.masterd_uid, getent.masterd_gid, False),
156
    (pathutils.WATCHER_PAUSEFILE, FILE, 0644,
157
     getent.masterd_uid, getent.masterd_gid, False),
158
    ]
159

    
160
  ss = ssconf.SimpleStore()
161
  for ss_path in ss.GetFileList():
162
    paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
163
                  getent.noded_uid, getent.noded_gid, False))
164

    
165
  paths.extend([
166
    (pathutils.QUEUE_DIR, DIR, 0750, getent.masterd_uid, getent.daemons_gid),
167
    (pathutils.QUEUE_DIR, QUEUE_DIR, constants.JOB_QUEUE_FILES_PERMS,
168
     getent.masterd_uid, getent.daemons_gid),
169
    (pathutils.JOB_QUEUE_DRAIN_FILE, FILE, 0644,
170
     getent.masterd_uid, getent.daemons_gid, False),
171
    (pathutils.JOB_QUEUE_LOCK_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
172
     getent.masterd_uid, getent.daemons_gid, False),
173
    (pathutils.JOB_QUEUE_SERIAL_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
174
     getent.masterd_uid, getent.daemons_gid, False),
175
    (pathutils.JOB_QUEUE_VERSION_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
176
     getent.masterd_uid, getent.daemons_gid, False),
177
    (pathutils.JOB_QUEUE_ARCHIVE_DIR, DIR, 0750,
178
     getent.masterd_uid, getent.daemons_gid),
179
    (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
180
    (pathutils.RAPI_USERS_FILE, FILE, 0640,
181
     getent.rapi_uid, getent.masterd_gid, False),
182
    (pathutils.RUN_DIR, DIR, 0775, getent.masterd_uid, getent.daemons_gid),
183
    (pathutils.SOCKET_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
184
    (pathutils.MASTER_SOCKET, FILE, 0660,
185
     getent.masterd_uid, getent.daemons_gid, False),
186
    (pathutils.QUERY_SOCKET, FILE, 0660,
187
     getent.luxid_uid, getent.daemons_gid, False),
188
    (pathutils.BDEV_CACHE_DIR, DIR, 0755,
189
     getent.noded_uid, getent.masterd_gid),
190
    (pathutils.UIDPOOL_LOCKDIR, DIR, 0750,
191
     getent.noded_uid, getent.masterd_gid),
192
    (pathutils.DISK_LINKS_DIR, DIR, 0755,
193
     getent.noded_uid, getent.masterd_gid),
194
    (pathutils.CRYPTO_KEYS_DIR, DIR, 0700,
195
     getent.noded_uid, getent.masterd_gid),
196
    (pathutils.IMPORT_EXPORT_DIR, DIR, 0755,
197
     getent.noded_uid, getent.masterd_gid),
198
    (pathutils.LOG_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
199
    (masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid, False),
200
    (confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False),
201
    (luxid_log, FILE, 0600, getent.luxid_uid, getent.masterd_gid, False),
202
    (noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False),
203
    (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False),
204
    (mond_log, FILE, 0600, getent.mond_uid, getent.masterd_gid, False),
205
    (pathutils.LOG_OS_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
206
    (pathutils.LOG_XEN_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
207
    (cleaner_log_dir, DIR, 0750, getent.noded_uid, getent.noded_gid),
208
    (master_cleaner_log_dir, DIR, 0750, getent.masterd_uid, getent.masterd_gid),
209
    (pathutils.INSTANCE_REASON_DIR, DIR, 0755, getent.noded_uid,
210
     getent.noded_gid),
211
    (pathutils.LIVELOCK_DIR, DIR, 0750, getent.masterd_uid, getent.daemons_gid),
212
    ])
213

    
214
  return paths
215

    
216

    
217
def ParseOptions():
218
  """Parses the options passed to the program.
219

220
  @return: Options and arguments
221

222
  """
223
  program = os.path.basename(sys.argv[0])
224

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

    
233
  return parser.parse_args()
234

    
235

    
236
def Main():
237
  """Main routine.
238

239
  """
240
  (opts, args) = ParseOptions()
241

    
242
  utils.SetupToolLogging(opts.debug, opts.verbose)
243

    
244
  if args:
245
    logging.error("No arguments are expected")
246
    return constants.EXIT_FAILURE
247

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

    
251
  getent = runtime.GetEnts()
252

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

    
257
    if opts.full_run:
258
      RecursiveEnsure(pathutils.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
259
                      getent.daemons_gid, 0750, constants.JOB_QUEUE_FILES_PERMS)
260
  except errors.GenericError, err:
261
    logging.error("An error occurred while setting permissions: %s", err)
262
    return constants.EXIT_FAILURE
263

    
264
  return constants.EXIT_SUCCESS