root / lib / tools / ensure_dirs.py @ 383477e9
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
|