1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 """Script to ensure permissions on files/dirs are accurate.
31
32 """
33
34 import os
35 import os.path
36 import optparse
37 import sys
38 import logging
39
40 from ganeti import constants
41 from ganeti import errors
42 from ganeti import runtime
43 from ganeti import ssconf
44 from ganeti import utils
45 from ganeti import cli
46 from ganeti import pathutils
47 from ganeti import compat
48
49
50 (DIR,
51 FILE,
52 QUEUE_DIR) = range(1, 4)
53
54 ALL_TYPES = compat.UniqueFrozenset([
55 DIR,
56 FILE,
57 QUEUE_DIR,
58 ])
59
60
62 """Ensures permissions recursively down a directory.
63
64 This functions walks the path and sets permissions accordingly.
65
66 @param path: The absolute path to walk
67 @param uid: The uid used as owner
68 @param gid: The gid used as group
69 @param dir_perm: The permission bits set for directories
70 @param file_perm: The permission bits set for files
71
72 """
73 assert os.path.isabs(path), "Path %s is not absolute" % path
74 assert os.path.isdir(path), "Path %s is not a dir" % path
75
76 logging.debug("Recursively processing %s", path)
77
78 for root, dirs, files in os.walk(path):
79 for subdir in dirs:
80 utils.EnforcePermission(os.path.join(root, subdir), dir_perm, uid=uid,
81 gid=gid)
82
83 for filename in files:
84 utils.EnforcePermission(os.path.join(root, filename), file_perm, uid=uid,
85 gid=gid)
86
87
89 """Sets the correct permissions on all job files in the queue.
90
91 @param path: Directory path
92 @param mode: Wanted file mode
93 @param uid: Wanted user ID
94 @param gid: Wanted group ID
95
96 """
97 for filename in utils.ListVisibleFiles(path):
98 if constants.JOB_FILE_RE.match(filename):
99 utils.EnforcePermission(utils.PathJoin(path, filename), mode, uid=uid,
100 gid=gid)
101
102
104 """Processes a path component.
105
106 @param path: A tuple of the path component to process
107
108 """
109 (pathname, pathtype, mode, uid, gid) = path[0:5]
110
111 assert pathtype in ALL_TYPES
112
113 if pathtype in (DIR, QUEUE_DIR):
114
115 assert len(path) == 5
116 if pathtype == DIR:
117 utils.MakeDirWithPerm(pathname, mode, uid, gid)
118 elif pathtype == QUEUE_DIR:
119 EnsureQueueDir(pathname, mode, uid, gid)
120 elif pathtype == FILE:
121 (must_exist, ) = path[5:]
122 utils.EnforcePermission(pathname, mode, uid=uid, gid=gid,
123 must_exist=must_exist)
124
125
127 """Returns a tuple of path objects to process.
128
129 """
130 getent = runtime.GetEnts()
131 masterd_log = constants.DAEMONS_LOGFILES[constants.MASTERD]
132 noded_log = constants.DAEMONS_LOGFILES[constants.NODED]
133 confd_log = constants.DAEMONS_LOGFILES[constants.CONFD]
134 luxid_log = constants.DAEMONS_LOGFILES[constants.LUXID]
135 rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI]
136 mond_log = constants.DAEMONS_LOGFILES[constants.MOND]
137
138 rapi_dir = os.path.join(pathutils.DATA_DIR, "rapi")
139 cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "cleaner")
140 master_cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "master-cleaner")
141
142
143
144
145 paths = [
146 (pathutils.DATA_DIR, DIR, 0755, getent.masterd_uid, getent.masterd_gid),
147 (pathutils.CLUSTER_DOMAIN_SECRET_FILE, FILE, 0640,
148 getent.masterd_uid, getent.masterd_gid, False),
149 (pathutils.CLUSTER_CONF_FILE, FILE, 0640,
150 getent.masterd_uid, getent.confd_gid, False),
151 (pathutils.CONFD_HMAC_KEY, FILE, 0440,
152 getent.confd_uid, getent.masterd_gid, False),
153 (pathutils.SSH_KNOWN_HOSTS_FILE, FILE, 0644,
154 getent.masterd_uid, getent.masterd_gid, False),
155 (pathutils.RAPI_CERT_FILE, FILE, 0440,
156 getent.rapi_uid, getent.masterd_gid, False),
157 (pathutils.SPICE_CERT_FILE, FILE, 0440,
158 getent.noded_uid, getent.masterd_gid, False),
159 (pathutils.SPICE_CACERT_FILE, FILE, 0440,
160 getent.noded_uid, getent.masterd_gid, False),
161 (pathutils.NODED_CERT_FILE, FILE, pathutils.NODED_CERT_MODE,
162 getent.masterd_uid, getent.masterd_gid, False),
163 (pathutils.NODED_CLIENT_CERT_FILE, FILE, pathutils.NODED_CERT_MODE,
164 getent.masterd_uid, getent.masterd_gid, False),
165 (pathutils.WATCHER_PAUSEFILE, FILE, 0644,
166 getent.masterd_uid, getent.masterd_gid, False),
167 ]
168
169 ss = ssconf.SimpleStore()
170 for ss_path in ss.GetFileList():
171 paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
172 getent.noded_uid, getent.noded_gid, False))
173
174 paths.extend([
175 (pathutils.QUEUE_DIR, DIR, 0750, getent.masterd_uid, getent.daemons_gid),
176 (pathutils.QUEUE_DIR, QUEUE_DIR, constants.JOB_QUEUE_FILES_PERMS,
177 getent.masterd_uid, getent.daemons_gid),
178 (pathutils.JOB_QUEUE_DRAIN_FILE, FILE, 0644,
179 getent.masterd_uid, getent.daemons_gid, False),
180 (pathutils.JOB_QUEUE_LOCK_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
181 getent.masterd_uid, getent.daemons_gid, False),
182 (pathutils.JOB_QUEUE_SERIAL_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
183 getent.masterd_uid, getent.daemons_gid, False),
184 (pathutils.JOB_QUEUE_VERSION_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
185 getent.masterd_uid, getent.daemons_gid, False),
186 (pathutils.JOB_QUEUE_ARCHIVE_DIR, DIR, 0750,
187 getent.masterd_uid, getent.daemons_gid),
188 (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
189 (pathutils.RAPI_USERS_FILE, FILE, 0640,
190 getent.rapi_uid, getent.masterd_gid, False),
191 (pathutils.RUN_DIR, DIR, 0775, getent.masterd_uid, getent.daemons_gid),
192 (pathutils.SOCKET_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
193 (pathutils.MASTER_SOCKET, FILE, 0660,
194 getent.masterd_uid, getent.daemons_gid, False),
195 (pathutils.QUERY_SOCKET, FILE, 0660,
196 getent.luxid_uid, getent.daemons_gid, False),
197 (pathutils.BDEV_CACHE_DIR, DIR, 0755,
198 getent.noded_uid, getent.masterd_gid),
199 (pathutils.UIDPOOL_LOCKDIR, DIR, 0750,
200 getent.noded_uid, getent.masterd_gid),
201 (pathutils.DISK_LINKS_DIR, DIR, 0755,
202 getent.noded_uid, getent.masterd_gid),
203 (pathutils.CRYPTO_KEYS_DIR, DIR, 0700,
204 getent.noded_uid, getent.masterd_gid),
205 (pathutils.IMPORT_EXPORT_DIR, DIR, 0755,
206 getent.noded_uid, getent.masterd_gid),
207 (pathutils.LOG_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
208 (masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid, False),
209 (confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False),
210 (luxid_log, FILE, 0600, getent.luxid_uid, getent.masterd_gid, False),
211 (noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False),
212 (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False),
213 (mond_log, FILE, 0600, getent.mond_uid, getent.masterd_gid, False),
214 (pathutils.LOG_OS_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
215 (pathutils.LOG_XEN_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
216 (cleaner_log_dir, DIR, 0750, getent.noded_uid, getent.noded_gid),
217 (master_cleaner_log_dir, DIR, 0750, getent.masterd_uid, getent.masterd_gid),
218 (pathutils.INSTANCE_REASON_DIR, DIR, 0755, getent.noded_uid,
219 getent.noded_gid),
220 (pathutils.LIVELOCK_DIR, DIR, 0750, getent.masterd_uid, getent.daemons_gid),
221 (pathutils.LUXID_MESSAGE_DIR, DIR, 0750, getent.masterd_uid,
222 getent.daemons_gid),
223 ])
224
225 return paths
226
227
229 """Parses the options passed to the program.
230
231 @return: Options and arguments
232
233 """
234 program = os.path.basename(sys.argv[0])
235
236 parser = optparse.OptionParser(usage="%prog [--full-run]",
237 prog=program)
238 parser.add_option(cli.DEBUG_OPT)
239 parser.add_option(cli.VERBOSE_OPT)
240 parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
241 default=False, help=("Make a full run and set permissions"
242 " on archived jobs (time consuming)"))
243
244 return parser.parse_args()
245
246
248 """Main routine.
249
250 """
251 (opts, args) = ParseOptions()
252
253 utils.SetupToolLogging(
254 opts.debug, opts.verbose,
255 toolname=os.path.splitext(os.path.basename(__file__))[0])
256
257 if args:
258 logging.error("No arguments are expected")
259 return constants.EXIT_FAILURE
260
261 if opts.full_run:
262 logging.info("Running in full mode")
263
264 getent = runtime.GetEnts()
265
266 try:
267 for path in GetPaths():
268 ProcessPath(path)
269
270 if opts.full_run:
271 RecursiveEnsure(pathutils.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
272 getent.daemons_gid, 0750, constants.JOB_QUEUE_FILES_PERMS)
273 except errors.GenericError, err:
274 logging.error("An error occurred while setting permissions: %s", err)
275 return constants.EXIT_FAILURE
276
277 return constants.EXIT_SUCCESS
278