root / lib / tools / ensure_dirs.py @ a30b473c
History | View | Annotate | Download (8 kB)
1 | 0d2bf835 | René Nussbaumer | # Copyright (C) 2011 Google Inc.
|
---|---|---|---|
2 | 0d2bf835 | René Nussbaumer | #
|
3 | 0d2bf835 | René Nussbaumer | # This program is free software; you can redistribute it and/or modify
|
4 | 0d2bf835 | René Nussbaumer | # it under the terms of the GNU General Public License as published by
|
5 | 0d2bf835 | René Nussbaumer | # the Free Software Foundation; either version 2 of the License, or
|
6 | 0d2bf835 | René Nussbaumer | # (at your option) any later version.
|
7 | 0d2bf835 | René Nussbaumer | #
|
8 | 0d2bf835 | René Nussbaumer | # This program is distributed in the hope that it will be useful, but
|
9 | 0d2bf835 | René Nussbaumer | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
10 | 0d2bf835 | René Nussbaumer | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
11 | 0d2bf835 | René Nussbaumer | # General Public License for more details.
|
12 | 0d2bf835 | René Nussbaumer | #
|
13 | 0d2bf835 | René Nussbaumer | # You should have received a copy of the GNU General Public License
|
14 | 0d2bf835 | René Nussbaumer | # along with this program; if not, write to the Free Software
|
15 | 0d2bf835 | René Nussbaumer | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
16 | 0d2bf835 | René Nussbaumer | # 02110-1301, USA.
|
17 | 0d2bf835 | René Nussbaumer | |
18 | 0d2bf835 | René Nussbaumer | """Script to ensure permissions on files/dirs are accurate.
|
19 | 0d2bf835 | René Nussbaumer |
|
20 | 0d2bf835 | René Nussbaumer | """
|
21 | 0d2bf835 | René Nussbaumer | |
22 | 0d2bf835 | René Nussbaumer | import errno |
23 | 0d2bf835 | René Nussbaumer | import os |
24 | 0d2bf835 | René Nussbaumer | import os.path |
25 | 0d2bf835 | René Nussbaumer | import optparse |
26 | 0d2bf835 | René Nussbaumer | import sys |
27 | 0d2bf835 | René Nussbaumer | import stat |
28 | 0d2bf835 | René Nussbaumer | |
29 | 0d2bf835 | René Nussbaumer | from ganeti import constants |
30 | 0d2bf835 | René Nussbaumer | from ganeti import errors |
31 | 0d2bf835 | René Nussbaumer | from ganeti import runtime |
32 | 0d2bf835 | René Nussbaumer | from ganeti import ssconf |
33 | 0d2bf835 | René Nussbaumer | |
34 | 0d2bf835 | René Nussbaumer | |
35 | 0d2bf835 | René Nussbaumer | (DIR, FILE) = range(2) |
36 | 0d2bf835 | René Nussbaumer | ALL_TYPES = frozenset([DIR, FILE])
|
37 | 0d2bf835 | René Nussbaumer | |
38 | 0d2bf835 | René Nussbaumer | |
39 | 0d2bf835 | René Nussbaumer | class EnsureError(errors.GenericError): |
40 | 0d2bf835 | René Nussbaumer | """Top-level error class related to this script.
|
41 | 0d2bf835 | René Nussbaumer |
|
42 | 0d2bf835 | René Nussbaumer | """
|
43 | 0d2bf835 | René Nussbaumer | |
44 | 0d2bf835 | René Nussbaumer | |
45 | 0d2bf835 | René Nussbaumer | def EnsurePermission(path, mode, uid=-1, gid=-1, must_exist=True, |
46 | 0d2bf835 | René Nussbaumer | _chmod_fn=os.chmod, _chown_fn=os.chown): |
47 | 0d2bf835 | René Nussbaumer | """Ensures that given path has given mode.
|
48 | 0d2bf835 | René Nussbaumer |
|
49 | 0d2bf835 | René Nussbaumer | @param path: The path to the file
|
50 | 0d2bf835 | René Nussbaumer | @param mode: The mode of the file
|
51 | 0d2bf835 | René Nussbaumer | @param uid: The uid of the owner of this file
|
52 | 0d2bf835 | René Nussbaumer | @param gid: The gid of the owner of this file
|
53 | 0d2bf835 | René Nussbaumer | @param must_exist: Specifies if non-existance of path will be an error
|
54 | 0d2bf835 | René Nussbaumer | @param _chmod_fn: chmod function to use (unittest only)
|
55 | 0d2bf835 | René Nussbaumer | @param _chown_fn: chown function to use (unittest only)
|
56 | 0d2bf835 | René Nussbaumer |
|
57 | 0d2bf835 | René Nussbaumer | """
|
58 | 0d2bf835 | René Nussbaumer | try:
|
59 | 0d2bf835 | René Nussbaumer | _chmod_fn(path, mode) |
60 | 0d2bf835 | René Nussbaumer | |
61 | 0d2bf835 | René Nussbaumer | if max(uid, gid) > -1: |
62 | 0d2bf835 | René Nussbaumer | _chown_fn(path, uid, gid) |
63 | 0d2bf835 | René Nussbaumer | except EnvironmentError, err: |
64 | 0d2bf835 | René Nussbaumer | if err.errno == errno.ENOENT:
|
65 | 0d2bf835 | René Nussbaumer | if must_exist:
|
66 | 0d2bf835 | René Nussbaumer | raise EnsureError("Path %s does not exists, but should" % path) |
67 | 0d2bf835 | René Nussbaumer | else:
|
68 | 0d2bf835 | René Nussbaumer | raise EnsureError("Error while changing permission on %s: %s" % |
69 | 0d2bf835 | René Nussbaumer | (path, err)) |
70 | 0d2bf835 | René Nussbaumer | |
71 | 0d2bf835 | René Nussbaumer | |
72 | 0d2bf835 | René Nussbaumer | def EnsureDir(path, mode, uid, gid, _stat_fn=os.lstat, _mkdir_fn=os.mkdir, |
73 | 0d2bf835 | René Nussbaumer | _ensure_fn=EnsurePermission): |
74 | 0d2bf835 | René Nussbaumer | """Ensures that given path is a dir and has given mode, uid and gid set.
|
75 | 0d2bf835 | René Nussbaumer |
|
76 | 0d2bf835 | René Nussbaumer | @param path: The path to the file
|
77 | 0d2bf835 | René Nussbaumer | @param mode: The mode of the file
|
78 | 0d2bf835 | René Nussbaumer | @param uid: The uid of the owner of this file
|
79 | 0d2bf835 | René Nussbaumer | @param gid: The gid of the owner of this file
|
80 | 0d2bf835 | René Nussbaumer | @param _stat_fn: Stat function to use (unittest only)
|
81 | 0d2bf835 | René Nussbaumer | @param _mkdir_fn: mkdir function to use (unittest only)
|
82 | 0d2bf835 | René Nussbaumer | @param _ensure_fn: ensure function to use (unittest only)
|
83 | 0d2bf835 | René Nussbaumer |
|
84 | 0d2bf835 | René Nussbaumer | """
|
85 | 0d2bf835 | René Nussbaumer | try:
|
86 | 0d2bf835 | René Nussbaumer | # We don't want to follow symlinks
|
87 | 0d2bf835 | René Nussbaumer | st_mode = _stat_fn(path)[stat.ST_MODE] |
88 | 0d2bf835 | René Nussbaumer | |
89 | 0d2bf835 | René Nussbaumer | if not stat.S_ISDIR(st_mode): |
90 | 0d2bf835 | René Nussbaumer | raise EnsureError("Path %s is expected to be a directory, but it's not" % |
91 | 0d2bf835 | René Nussbaumer | path) |
92 | 0d2bf835 | René Nussbaumer | except EnvironmentError, err: |
93 | 0d2bf835 | René Nussbaumer | if err.errno == errno.ENOENT:
|
94 | 0d2bf835 | René Nussbaumer | _mkdir_fn(path) |
95 | 0d2bf835 | René Nussbaumer | else:
|
96 | 0d2bf835 | René Nussbaumer | raise EnsureError("Error while do a stat() on %s: %s" % (path, err)) |
97 | 0d2bf835 | René Nussbaumer | |
98 | 0d2bf835 | René Nussbaumer | _ensure_fn(path, mode, uid=uid, gid=gid) |
99 | 0d2bf835 | René Nussbaumer | |
100 | 0d2bf835 | René Nussbaumer | |
101 | 0d2bf835 | René Nussbaumer | def RecursiveEnsure(path, uid, gid, dir_perm, file_perm): |
102 | 0d2bf835 | René Nussbaumer | """Ensures permissions recursively down a directory.
|
103 | 0d2bf835 | René Nussbaumer |
|
104 | 0d2bf835 | René Nussbaumer | This functions walks the path and sets permissions accordingly.
|
105 | 0d2bf835 | René Nussbaumer |
|
106 | 0d2bf835 | René Nussbaumer | @param path: The absolute path to walk
|
107 | 0d2bf835 | René Nussbaumer | @param uid: The uid used as owner
|
108 | 0d2bf835 | René Nussbaumer | @param gid: The gid used as group
|
109 | 0d2bf835 | René Nussbaumer | @param dir_perm: The permission bits set for directories
|
110 | 0d2bf835 | René Nussbaumer | @param file_perm: The permission bits set for files
|
111 | 0d2bf835 | René Nussbaumer |
|
112 | 0d2bf835 | René Nussbaumer | """
|
113 | 0d2bf835 | René Nussbaumer | assert os.path.isabs(path), "Path %s is not absolute" % path |
114 | 0d2bf835 | René Nussbaumer | assert os.path.isdir(path), "Path %s is not a dir" % path |
115 | 0d2bf835 | René Nussbaumer | |
116 | 0d2bf835 | René Nussbaumer | for root, dirs, files in os.walk(path): |
117 | 0d2bf835 | René Nussbaumer | for subdir in dirs: |
118 | 0d2bf835 | René Nussbaumer | EnsurePermission(os.path.join(root, subdir), dir_perm, uid=uid, gid=gid) |
119 | 0d2bf835 | René Nussbaumer | |
120 | 0d2bf835 | René Nussbaumer | for filename in files: |
121 | 0d2bf835 | René Nussbaumer | EnsurePermission(os.path.join(root, filename), file_perm, uid=uid, |
122 | 0d2bf835 | René Nussbaumer | gid=gid) |
123 | 0d2bf835 | René Nussbaumer | |
124 | 0d2bf835 | René Nussbaumer | |
125 | 0d2bf835 | René Nussbaumer | def ProcessPath(path): |
126 | 0d2bf835 | René Nussbaumer | """Processes a path component.
|
127 | 0d2bf835 | René Nussbaumer |
|
128 | 0d2bf835 | René Nussbaumer | @param path: A tuple of the path component to process
|
129 | 0d2bf835 | René Nussbaumer |
|
130 | 0d2bf835 | René Nussbaumer | """
|
131 | 0d2bf835 | René Nussbaumer | (pathname, pathtype, mode, uid, gid) = path[0:5] |
132 | 0d2bf835 | René Nussbaumer | |
133 | 0d2bf835 | René Nussbaumer | assert pathtype in ALL_TYPES |
134 | 0d2bf835 | René Nussbaumer | |
135 | 0d2bf835 | René Nussbaumer | if pathtype == DIR:
|
136 | 0d2bf835 | René Nussbaumer | # No additional parameters
|
137 | 0d2bf835 | René Nussbaumer | assert len(path[5:]) == 0 |
138 | 0d2bf835 | René Nussbaumer | EnsureDir(pathname, mode, uid, gid) |
139 | 0d2bf835 | René Nussbaumer | elif pathtype == FILE:
|
140 | 0d2bf835 | René Nussbaumer | (must_exist, ) = path[5:]
|
141 | 0d2bf835 | René Nussbaumer | EnsurePermission(pathname, mode, uid=uid, gid=gid, must_exist=must_exist) |
142 | 0d2bf835 | René Nussbaumer | |
143 | 0d2bf835 | René Nussbaumer | |
144 | 0d2bf835 | René Nussbaumer | def GetPaths(): |
145 | 0d2bf835 | René Nussbaumer | """Returns a tuple of path objects to process.
|
146 | 0d2bf835 | René Nussbaumer |
|
147 | 0d2bf835 | René Nussbaumer | """
|
148 | 0d2bf835 | René Nussbaumer | getent = runtime.GetEnts() |
149 | 0d2bf835 | René Nussbaumer | masterd_log = constants.DAEMONS_LOGFILES[constants.MASTERD] |
150 | 0d2bf835 | René Nussbaumer | noded_log = constants.DAEMONS_LOGFILES[constants.NODED] |
151 | 0d2bf835 | René Nussbaumer | confd_log = constants.DAEMONS_LOGFILES[constants.CONFD] |
152 | 0d2bf835 | René Nussbaumer | rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI] |
153 | 0d2bf835 | René Nussbaumer | |
154 | 0d2bf835 | René Nussbaumer | rapi_dir = os.path.join(constants.DATA_DIR, "rapi")
|
155 | 0d2bf835 | René Nussbaumer | |
156 | 0d2bf835 | René Nussbaumer | paths = [ |
157 | 0d2bf835 | René Nussbaumer | (constants.DATA_DIR, DIR, 0755, getent.masterd_uid,
|
158 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
159 | 0d2bf835 | René Nussbaumer | (constants.CLUSTER_DOMAIN_SECRET_FILE, FILE, 0640,
|
160 | 0d2bf835 | René Nussbaumer | getent.masterd_uid, getent.masterd_gid, False),
|
161 | 0d2bf835 | René Nussbaumer | (constants.CLUSTER_CONF_FILE, FILE, 0640, getent.masterd_uid,
|
162 | 0d2bf835 | René Nussbaumer | getent.confd_gid, False),
|
163 | 0d2bf835 | René Nussbaumer | (constants.CONFD_HMAC_KEY, FILE, 0440, getent.confd_uid,
|
164 | 0d2bf835 | René Nussbaumer | getent.masterd_gid, False),
|
165 | 0d2bf835 | René Nussbaumer | (constants.SSH_KNOWN_HOSTS_FILE, FILE, 0644, getent.masterd_uid,
|
166 | 0d2bf835 | René Nussbaumer | getent.masterd_gid, False),
|
167 | 0d2bf835 | René Nussbaumer | (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid,
|
168 | 0d2bf835 | René Nussbaumer | getent.masterd_gid, False),
|
169 | 0d2bf835 | René Nussbaumer | (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid,
|
170 | 0d2bf835 | René Nussbaumer | getent.masterd_gid, False),
|
171 | 0d2bf835 | René Nussbaumer | ] |
172 | 0d2bf835 | René Nussbaumer | |
173 | 0d2bf835 | René Nussbaumer | ss = ssconf.SimpleStore() |
174 | 0d2bf835 | René Nussbaumer | for ss_path in ss.GetFileList(): |
175 | 0d2bf835 | René Nussbaumer | paths.append((ss_path, FILE, 0400, getent.noded_uid, 0, False)) |
176 | 0d2bf835 | René Nussbaumer | |
177 | 0d2bf835 | René Nussbaumer | paths.extend([ |
178 | 0d2bf835 | René Nussbaumer | (constants.QUEUE_DIR, DIR, 0700, getent.masterd_uid,
|
179 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
180 | 0d2bf835 | René Nussbaumer | (constants.JOB_QUEUE_SERIAL_FILE, FILE, 0600,
|
181 | 0d2bf835 | René Nussbaumer | getent.masterd_uid, getent.masterd_gid, False),
|
182 | 0d2bf835 | René Nussbaumer | (constants.JOB_QUEUE_ARCHIVE_DIR, DIR, 0700,
|
183 | 0d2bf835 | René Nussbaumer | getent.masterd_uid, getent.masterd_gid), |
184 | 0d2bf835 | René Nussbaumer | (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
|
185 | 0d2bf835 | René Nussbaumer | (constants.RAPI_USERS_FILE, FILE, 0640, getent.rapi_uid,
|
186 | 0d2bf835 | René Nussbaumer | getent.masterd_gid, False),
|
187 | 0d2bf835 | René Nussbaumer | (constants.RUN_GANETI_DIR, DIR, 0775, getent.masterd_uid,
|
188 | 0d2bf835 | René Nussbaumer | getent.daemons_gid), |
189 | 0d2bf835 | René Nussbaumer | (constants.SOCKET_DIR, DIR, 0750, getent.masterd_uid,
|
190 | 0d2bf835 | René Nussbaumer | getent.daemons_gid), |
191 | 0d2bf835 | René Nussbaumer | (constants.MASTER_SOCKET, FILE, 0770, getent.masterd_uid,
|
192 | 0d2bf835 | René Nussbaumer | getent.daemons_gid, False),
|
193 | 0d2bf835 | René Nussbaumer | (constants.BDEV_CACHE_DIR, DIR, 0755, getent.noded_uid,
|
194 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
195 | 0d2bf835 | René Nussbaumer | (constants.UIDPOOL_LOCKDIR, DIR, 0750, getent.noded_uid,
|
196 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
197 | 0d2bf835 | René Nussbaumer | (constants.DISK_LINKS_DIR, DIR, 0755, getent.noded_uid,
|
198 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
199 | 0d2bf835 | René Nussbaumer | (constants.CRYPTO_KEYS_DIR, DIR, 0700, getent.noded_uid,
|
200 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
201 | 0d2bf835 | René Nussbaumer | (constants.IMPORT_EXPORT_DIR, DIR, 0755, getent.noded_uid,
|
202 | 0d2bf835 | René Nussbaumer | getent.masterd_gid), |
203 | 0d2bf835 | René Nussbaumer | (constants.LOG_DIR, DIR, 0770, getent.masterd_uid,
|
204 | 0d2bf835 | René Nussbaumer | getent.daemons_gid), |
205 | 0d2bf835 | René Nussbaumer | (masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid,
|
206 | 0d2bf835 | René Nussbaumer | False),
|
207 | 0d2bf835 | René Nussbaumer | (confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False), |
208 | 0d2bf835 | René Nussbaumer | (noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False), |
209 | 0d2bf835 | René Nussbaumer | (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False), |
210 | 0d2bf835 | René Nussbaumer | (constants.LOG_OS_DIR, DIR, 0750, getent.masterd_uid,
|
211 | 0d2bf835 | René Nussbaumer | getent.daemons_gid), |
212 | 0d2bf835 | René Nussbaumer | ]) |
213 | 0d2bf835 | René Nussbaumer | |
214 | 0d2bf835 | René Nussbaumer | return tuple(paths) |
215 | 0d2bf835 | René Nussbaumer | |
216 | 0d2bf835 | René Nussbaumer | |
217 | 0d2bf835 | René Nussbaumer | def ParseOptions(): |
218 | 0d2bf835 | René Nussbaumer | """Parses the options passed to the program.
|
219 | 0d2bf835 | René Nussbaumer |
|
220 | 0d2bf835 | René Nussbaumer | @return: Options and arguments
|
221 | 0d2bf835 | René Nussbaumer |
|
222 | 0d2bf835 | René Nussbaumer | """
|
223 | 0d2bf835 | René Nussbaumer | program = os.path.basename(sys.argv[0])
|
224 | 0d2bf835 | René Nussbaumer | |
225 | 0d2bf835 | René Nussbaumer | parser = optparse.OptionParser(usage="%%prog [--full-run]",
|
226 | 0d2bf835 | René Nussbaumer | prog=program) |
227 | 0d2bf835 | René Nussbaumer | parser.add_option("--full-run", "-f", dest="full_run", action="store_true", |
228 | 0d2bf835 | René Nussbaumer | default=False, help=("Make a full run and collect" |
229 | 0d2bf835 | René Nussbaumer | " additional files (time consuming)"))
|
230 | 0d2bf835 | René Nussbaumer | |
231 | 0d2bf835 | René Nussbaumer | return parser.parse_args()
|
232 | 0d2bf835 | René Nussbaumer | |
233 | 0d2bf835 | René Nussbaumer | |
234 | 0d2bf835 | René Nussbaumer | def Main(): |
235 | 0d2bf835 | René Nussbaumer | """Main routine.
|
236 | 0d2bf835 | René Nussbaumer |
|
237 | 0d2bf835 | René Nussbaumer | """
|
238 | 0d2bf835 | René Nussbaumer | getent = runtime.GetEnts() |
239 | 0d2bf835 | René Nussbaumer | (opts, _) = ParseOptions() |
240 | 0d2bf835 | René Nussbaumer | |
241 | 0d2bf835 | René Nussbaumer | try:
|
242 | 0d2bf835 | René Nussbaumer | for path in GetPaths(): |
243 | 0d2bf835 | René Nussbaumer | ProcessPath(path) |
244 | 0d2bf835 | René Nussbaumer | |
245 | 0d2bf835 | René Nussbaumer | if opts.full_run:
|
246 | 0d2bf835 | René Nussbaumer | RecursiveEnsure(constants.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid, |
247 | 0d2bf835 | René Nussbaumer | getent.masterd_gid, 0700, 0600) |
248 | 0d2bf835 | René Nussbaumer | except EnsureError, err:
|
249 | 0d2bf835 | René Nussbaumer | print >> sys.stderr, "An error occurred while ensure permissions:", err |
250 | 0d2bf835 | René Nussbaumer | return constants.EXIT_FAILURE
|
251 | 0d2bf835 | René Nussbaumer | |
252 | 0d2bf835 | René Nussbaumer | return constants.EXIT_SUCCESS |