Statistics
| Branch: | Tag: | Revision:

root / lib / tools / ensure_dirs.py @ e37f47d3

History | View | Annotate | Download (8.3 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
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 = constants.DAEMONS_LOGFILES[constants.MASTERD]
122
  noded_log = constants.DAEMONS_LOGFILES[constants.NODED]
123
  confd_log = constants.DAEMONS_LOGFILES[constants.CONFD]
124
  rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI]
125

    
126
  rapi_dir = os.path.join(pathutils.DATA_DIR, "rapi")
127
  cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "cleaner")
128
  master_cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "master-cleaner")
129

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

    
155
  ss = ssconf.SimpleStore()
156
  for ss_path in ss.GetFileList():
157
    paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
158
                  getent.noded_uid, getent.noded_gid, False))
159

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

    
201
  return paths
202

    
203

    
204
def ParseOptions():
205
  """Parses the options passed to the program.
206

207
  @return: Options and arguments
208

209
  """
210
  program = os.path.basename(sys.argv[0])
211

    
212
  parser = optparse.OptionParser(usage="%prog [--full-run]",
213
                                 prog=program)
214
  parser.add_option(cli.DEBUG_OPT)
215
  parser.add_option(cli.VERBOSE_OPT)
216
  parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
217
                    default=False, help=("Make a full run and set permissions"
218
                                         " on archived jobs (time consuming)"))
219

    
220
  return parser.parse_args()
221

    
222

    
223
def Main():
224
  """Main routine.
225

226
  """
227
  (opts, args) = ParseOptions()
228

    
229
  utils.SetupToolLogging(opts.debug, opts.verbose)
230

    
231
  if args:
232
    logging.error("No arguments are expected")
233
    return constants.EXIT_FAILURE
234

    
235
  if opts.full_run:
236
    logging.info("Running in full mode")
237

    
238
  getent = runtime.GetEnts()
239

    
240
  try:
241
    for path in GetPaths():
242
      ProcessPath(path)
243

    
244
    if opts.full_run:
245
      RecursiveEnsure(pathutils.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
246
                      getent.masterd_gid, 0700, 0600)
247
  except errors.GenericError, err:
248
    logging.error("An error occurred while setting permissions: %s", err)
249
    return constants.EXIT_FAILURE
250

    
251
  return constants.EXIT_SUCCESS