root / lib / tools / ensure_dirs.py @ c904c032
History | View | Annotate | Download (9 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.WATCHER_PAUSEFILE, FILE, 0644,
|
155 |
getent.masterd_uid, getent.masterd_gid, False),
|
156 |
] |
157 |
|
158 |
ss = ssconf.SimpleStore() |
159 |
for ss_path in ss.GetFileList(): |
160 |
paths.append((ss_path, FILE, constants.SS_FILE_PERMS, |
161 |
getent.noded_uid, getent.noded_gid, False))
|
162 |
|
163 |
paths.extend([ |
164 |
(pathutils.QUEUE_DIR, DIR, 0750, getent.masterd_uid, getent.daemons_gid),
|
165 |
(pathutils.QUEUE_DIR, QUEUE_DIR, constants.JOB_QUEUE_FILES_PERMS, |
166 |
getent.masterd_uid, getent.daemons_gid), |
167 |
(pathutils.JOB_QUEUE_DRAIN_FILE, FILE, 0644,
|
168 |
getent.masterd_uid, getent.daemons_gid, False),
|
169 |
(pathutils.JOB_QUEUE_LOCK_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS, |
170 |
getent.masterd_uid, getent.daemons_gid, False),
|
171 |
(pathutils.JOB_QUEUE_SERIAL_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS, |
172 |
getent.masterd_uid, getent.daemons_gid, False),
|
173 |
(pathutils.JOB_QUEUE_VERSION_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS, |
174 |
getent.masterd_uid, getent.daemons_gid, False),
|
175 |
(pathutils.JOB_QUEUE_ARCHIVE_DIR, DIR, 0750,
|
176 |
getent.masterd_uid, getent.daemons_gid), |
177 |
(rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
|
178 |
(pathutils.RAPI_USERS_FILE, FILE, 0640,
|
179 |
getent.rapi_uid, getent.masterd_gid, False),
|
180 |
(pathutils.RUN_DIR, DIR, 0775, getent.masterd_uid, getent.daemons_gid),
|
181 |
(pathutils.SOCKET_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
|
182 |
(pathutils.MASTER_SOCKET, FILE, 0660,
|
183 |
getent.masterd_uid, getent.daemons_gid, False),
|
184 |
(pathutils.QUERY_SOCKET, FILE, 0660,
|
185 |
getent.luxid_uid, getent.daemons_gid, False),
|
186 |
(pathutils.BDEV_CACHE_DIR, DIR, 0755,
|
187 |
getent.noded_uid, getent.masterd_gid), |
188 |
(pathutils.UIDPOOL_LOCKDIR, DIR, 0750,
|
189 |
getent.noded_uid, getent.masterd_gid), |
190 |
(pathutils.DISK_LINKS_DIR, DIR, 0755,
|
191 |
getent.noded_uid, getent.masterd_gid), |
192 |
(pathutils.CRYPTO_KEYS_DIR, DIR, 0700,
|
193 |
getent.noded_uid, getent.masterd_gid), |
194 |
(pathutils.IMPORT_EXPORT_DIR, DIR, 0755,
|
195 |
getent.noded_uid, getent.masterd_gid), |
196 |
(pathutils.LOG_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
|
197 |
(masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid, False), |
198 |
(confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False), |
199 |
(luxid_log, FILE, 0600, getent.luxid_uid, getent.masterd_gid, False), |
200 |
(noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False), |
201 |
(rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False), |
202 |
(mond_log, FILE, 0600, getent.mond_uid, getent.masterd_gid, False), |
203 |
(pathutils.LOG_OS_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
|
204 |
(pathutils.LOG_XEN_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
|
205 |
(cleaner_log_dir, DIR, 0750, getent.noded_uid, getent.noded_gid),
|
206 |
(master_cleaner_log_dir, DIR, 0750, getent.masterd_uid, getent.masterd_gid),
|
207 |
(pathutils.INSTANCE_REASON_DIR, DIR, 0755, getent.noded_uid,
|
208 |
getent.noded_gid), |
209 |
]) |
210 |
|
211 |
return paths
|
212 |
|
213 |
|
214 |
def ParseOptions(): |
215 |
"""Parses the options passed to the program.
|
216 |
|
217 |
@return: Options and arguments
|
218 |
|
219 |
"""
|
220 |
program = os.path.basename(sys.argv[0])
|
221 |
|
222 |
parser = optparse.OptionParser(usage="%prog [--full-run]",
|
223 |
prog=program) |
224 |
parser.add_option(cli.DEBUG_OPT) |
225 |
parser.add_option(cli.VERBOSE_OPT) |
226 |
parser.add_option("--full-run", "-f", dest="full_run", action="store_true", |
227 |
default=False, help=("Make a full run and set permissions" |
228 |
" on archived jobs (time consuming)"))
|
229 |
|
230 |
return parser.parse_args()
|
231 |
|
232 |
|
233 |
def Main(): |
234 |
"""Main routine.
|
235 |
|
236 |
"""
|
237 |
(opts, args) = ParseOptions() |
238 |
|
239 |
utils.SetupToolLogging(opts.debug, opts.verbose) |
240 |
|
241 |
if args:
|
242 |
logging.error("No arguments are expected")
|
243 |
return constants.EXIT_FAILURE
|
244 |
|
245 |
if opts.full_run:
|
246 |
logging.info("Running in full mode")
|
247 |
|
248 |
getent = runtime.GetEnts() |
249 |
|
250 |
try:
|
251 |
for path in GetPaths(): |
252 |
ProcessPath(path) |
253 |
|
254 |
if opts.full_run:
|
255 |
RecursiveEnsure(pathutils.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid, |
256 |
getent.daemons_gid, 0750, constants.JOB_QUEUE_FILES_PERMS)
|
257 |
except errors.GenericError, err:
|
258 |
logging.error("An error occurred while setting permissions: %s", err)
|
259 |
return constants.EXIT_FAILURE
|
260 |
|
261 |
return constants.EXIT_SUCCESS
|