Statistics
| Branch: | Tag: | Revision:

root / lib / tools / ensure_dirs.py @ 592eb0df

History | View | Annotate | Download (8 kB)

1 cb66225d Michael Hanselmann
#
2 cb66225d Michael Hanselmann
#
3 cb66225d Michael Hanselmann
4 0d2bf835 René Nussbaumer
# Copyright (C) 2011 Google Inc.
5 0d2bf835 René Nussbaumer
#
6 0d2bf835 René Nussbaumer
# This program is free software; you can redistribute it and/or modify
7 0d2bf835 René Nussbaumer
# it under the terms of the GNU General Public License as published by
8 0d2bf835 René Nussbaumer
# the Free Software Foundation; either version 2 of the License, or
9 0d2bf835 René Nussbaumer
# (at your option) any later version.
10 0d2bf835 René Nussbaumer
#
11 0d2bf835 René Nussbaumer
# This program is distributed in the hope that it will be useful, but
12 0d2bf835 René Nussbaumer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 0d2bf835 René Nussbaumer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 0d2bf835 René Nussbaumer
# General Public License for more details.
15 0d2bf835 René Nussbaumer
#
16 0d2bf835 René Nussbaumer
# You should have received a copy of the GNU General Public License
17 0d2bf835 René Nussbaumer
# along with this program; if not, write to the Free Software
18 0d2bf835 René Nussbaumer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 0d2bf835 René Nussbaumer
# 02110-1301, USA.
20 0d2bf835 René Nussbaumer
21 0d2bf835 René Nussbaumer
"""Script to ensure permissions on files/dirs are accurate.
22 0d2bf835 René Nussbaumer

23 0d2bf835 René Nussbaumer
"""
24 0d2bf835 René Nussbaumer
25 0d2bf835 René Nussbaumer
import os
26 0d2bf835 René Nussbaumer
import os.path
27 0d2bf835 René Nussbaumer
import optparse
28 0d2bf835 René Nussbaumer
import sys
29 961226f6 Michael Hanselmann
import logging
30 0d2bf835 René Nussbaumer
31 0d2bf835 René Nussbaumer
from ganeti import constants
32 0d2bf835 René Nussbaumer
from ganeti import errors
33 0d2bf835 René Nussbaumer
from ganeti import runtime
34 0d2bf835 René Nussbaumer
from ganeti import ssconf
35 cb66225d Michael Hanselmann
from ganeti import utils
36 961226f6 Michael Hanselmann
from ganeti import cli
37 0d2bf835 René Nussbaumer
38 0d2bf835 René Nussbaumer
39 cb66225d Michael Hanselmann
(DIR,
40 cb66225d Michael Hanselmann
 FILE,
41 cb66225d Michael Hanselmann
 QUEUE_DIR) = range(1, 4)
42 cb66225d Michael Hanselmann
43 cb66225d Michael Hanselmann
ALL_TYPES = frozenset([
44 cb66225d Michael Hanselmann
  DIR,
45 cb66225d Michael Hanselmann
  FILE,
46 cb66225d Michael Hanselmann
  QUEUE_DIR,
47 cb66225d Michael Hanselmann
  ])
48 0d2bf835 René Nussbaumer
49 0d2bf835 René Nussbaumer
50 0d2bf835 René Nussbaumer
def RecursiveEnsure(path, uid, gid, dir_perm, file_perm):
51 0d2bf835 René Nussbaumer
  """Ensures permissions recursively down a directory.
52 0d2bf835 René Nussbaumer

53 0d2bf835 René Nussbaumer
  This functions walks the path and sets permissions accordingly.
54 0d2bf835 René Nussbaumer

55 0d2bf835 René Nussbaumer
  @param path: The absolute path to walk
56 0d2bf835 René Nussbaumer
  @param uid: The uid used as owner
57 0d2bf835 René Nussbaumer
  @param gid: The gid used as group
58 0d2bf835 René Nussbaumer
  @param dir_perm: The permission bits set for directories
59 0d2bf835 René Nussbaumer
  @param file_perm: The permission bits set for files
60 0d2bf835 René Nussbaumer

61 0d2bf835 René Nussbaumer
  """
62 0d2bf835 René Nussbaumer
  assert os.path.isabs(path), "Path %s is not absolute" % path
63 0d2bf835 René Nussbaumer
  assert os.path.isdir(path), "Path %s is not a dir" % path
64 0d2bf835 René Nussbaumer
65 961226f6 Michael Hanselmann
  logging.debug("Recursively processing %s", path)
66 961226f6 Michael Hanselmann
67 0d2bf835 René Nussbaumer
  for root, dirs, files in os.walk(path):
68 0d2bf835 René Nussbaumer
    for subdir in dirs:
69 b81b3c96 René Nussbaumer
      utils.EnforcePermission(os.path.join(root, subdir), dir_perm, uid=uid,
70 b81b3c96 René Nussbaumer
                              gid=gid)
71 0d2bf835 René Nussbaumer
72 0d2bf835 René Nussbaumer
    for filename in files:
73 b81b3c96 René Nussbaumer
      utils.EnforcePermission(os.path.join(root, filename), file_perm, uid=uid,
74 b81b3c96 René Nussbaumer
                              gid=gid)
75 0d2bf835 René Nussbaumer
76 0d2bf835 René Nussbaumer
77 cb66225d Michael Hanselmann
def EnsureQueueDir(path, mode, uid, gid):
78 cb66225d Michael Hanselmann
  """Sets the correct permissions on all job files in the queue.
79 cb66225d Michael Hanselmann

80 cb66225d Michael Hanselmann
  @param path: Directory path
81 cb66225d Michael Hanselmann
  @param mode: Wanted file mode
82 cb66225d Michael Hanselmann
  @param uid: Wanted user ID
83 cb66225d Michael Hanselmann
  @param gid: Wanted group ID
84 cb66225d Michael Hanselmann

85 cb66225d Michael Hanselmann
  """
86 cb66225d Michael Hanselmann
  for filename in utils.ListVisibleFiles(path):
87 cb66225d Michael Hanselmann
    if constants.JOB_FILE_RE.match(filename):
88 b81b3c96 René Nussbaumer
      utils.EnforcePermission(utils.PathJoin(path, filename), mode, uid=uid,
89 b81b3c96 René Nussbaumer
                              gid=gid)
90 cb66225d Michael Hanselmann
91 cb66225d Michael Hanselmann
92 0d2bf835 René Nussbaumer
def ProcessPath(path):
93 0d2bf835 René Nussbaumer
  """Processes a path component.
94 0d2bf835 René Nussbaumer

95 0d2bf835 René Nussbaumer
  @param path: A tuple of the path component to process
96 0d2bf835 René Nussbaumer

97 0d2bf835 René Nussbaumer
  """
98 0d2bf835 René Nussbaumer
  (pathname, pathtype, mode, uid, gid) = path[0:5]
99 0d2bf835 René Nussbaumer
100 0d2bf835 René Nussbaumer
  assert pathtype in ALL_TYPES
101 0d2bf835 René Nussbaumer
102 cb66225d Michael Hanselmann
  if pathtype in (DIR, QUEUE_DIR):
103 0d2bf835 René Nussbaumer
    # No additional parameters
104 0d2bf835 René Nussbaumer
    assert len(path[5:]) == 0
105 cb66225d Michael Hanselmann
    if pathtype == DIR:
106 b81b3c96 René Nussbaumer
      utils.MakeDirWithPerm(pathname, mode, uid, gid)
107 cb66225d Michael Hanselmann
    elif pathtype == QUEUE_DIR:
108 cb66225d Michael Hanselmann
      EnsureQueueDir(pathname, mode, uid, gid)
109 0d2bf835 René Nussbaumer
  elif pathtype == FILE:
110 0d2bf835 René Nussbaumer
    (must_exist, ) = path[5:]
111 b81b3c96 René Nussbaumer
    utils.EnforcePermission(pathname, mode, uid=uid, gid=gid,
112 b81b3c96 René Nussbaumer
                            must_exist=must_exist)
113 0d2bf835 René Nussbaumer
114 0d2bf835 René Nussbaumer
115 0d2bf835 René Nussbaumer
def GetPaths():
116 0d2bf835 René Nussbaumer
  """Returns a tuple of path objects to process.
117 0d2bf835 René Nussbaumer

118 0d2bf835 René Nussbaumer
  """
119 0d2bf835 René Nussbaumer
  getent = runtime.GetEnts()
120 0d2bf835 René Nussbaumer
  masterd_log = constants.DAEMONS_LOGFILES[constants.MASTERD]
121 0d2bf835 René Nussbaumer
  noded_log = constants.DAEMONS_LOGFILES[constants.NODED]
122 0d2bf835 René Nussbaumer
  confd_log = constants.DAEMONS_LOGFILES[constants.CONFD]
123 0d2bf835 René Nussbaumer
  rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI]
124 0d2bf835 René Nussbaumer
125 0d2bf835 René Nussbaumer
  rapi_dir = os.path.join(constants.DATA_DIR, "rapi")
126 0d2bf835 René Nussbaumer
127 0d2bf835 René Nussbaumer
  paths = [
128 0d2bf835 René Nussbaumer
    (constants.DATA_DIR, DIR, 0755, getent.masterd_uid,
129 0d2bf835 René Nussbaumer
     getent.masterd_gid),
130 0d2bf835 René Nussbaumer
    (constants.CLUSTER_DOMAIN_SECRET_FILE, FILE, 0640,
131 0d2bf835 René Nussbaumer
     getent.masterd_uid, getent.masterd_gid, False),
132 0d2bf835 René Nussbaumer
    (constants.CLUSTER_CONF_FILE, FILE, 0640, getent.masterd_uid,
133 0d2bf835 René Nussbaumer
     getent.confd_gid, False),
134 0d2bf835 René Nussbaumer
    (constants.CONFD_HMAC_KEY, FILE, 0440, getent.confd_uid,
135 0d2bf835 René Nussbaumer
     getent.masterd_gid, False),
136 0d2bf835 René Nussbaumer
    (constants.SSH_KNOWN_HOSTS_FILE, FILE, 0644, getent.masterd_uid,
137 0d2bf835 René Nussbaumer
     getent.masterd_gid, False),
138 0d2bf835 René Nussbaumer
    (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid,
139 0d2bf835 René Nussbaumer
     getent.masterd_gid, False),
140 bfe86c76 Andrea Spadaccini
    (constants.SPICE_CERT_FILE, FILE, 0440, getent.noded_uid,
141 bfe86c76 Andrea Spadaccini
     getent.masterd_gid, False),
142 bfe86c76 Andrea Spadaccini
    (constants.SPICE_CACERT_FILE, FILE, 0440, getent.noded_uid,
143 bfe86c76 Andrea Spadaccini
     getent.masterd_gid, False),
144 0d2bf835 René Nussbaumer
    (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid,
145 0d2bf835 René Nussbaumer
     getent.masterd_gid, False),
146 0d2bf835 René Nussbaumer
    ]
147 0d2bf835 René Nussbaumer
148 0d2bf835 René Nussbaumer
  ss = ssconf.SimpleStore()
149 0d2bf835 René Nussbaumer
  for ss_path in ss.GetFileList():
150 cd57bab6 Michael Hanselmann
    paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
151 cd57bab6 Michael Hanselmann
                  getent.noded_uid, 0, False))
152 0d2bf835 René Nussbaumer
153 0d2bf835 René Nussbaumer
  paths.extend([
154 0d2bf835 René Nussbaumer
    (constants.QUEUE_DIR, DIR, 0700, getent.masterd_uid,
155 0d2bf835 René Nussbaumer
     getent.masterd_gid),
156 cb66225d Michael Hanselmann
    (constants.QUEUE_DIR, QUEUE_DIR, 0600, getent.masterd_uid,
157 cb66225d Michael Hanselmann
     getent.masterd_gid),
158 247ee81f Michael Hanselmann
    (constants.JOB_QUEUE_LOCK_FILE, FILE, 0600,
159 247ee81f Michael Hanselmann
     getent.masterd_uid, getent.masterd_gid, False),
160 0d2bf835 René Nussbaumer
    (constants.JOB_QUEUE_SERIAL_FILE, FILE, 0600,
161 0d2bf835 René Nussbaumer
     getent.masterd_uid, getent.masterd_gid, False),
162 69f78cf7 René Nussbaumer
    (constants.JOB_QUEUE_VERSION_FILE, FILE, 0600,
163 69f78cf7 René Nussbaumer
     getent.masterd_uid, getent.masterd_gid, False),
164 0d2bf835 René Nussbaumer
    (constants.JOB_QUEUE_ARCHIVE_DIR, DIR, 0700,
165 0d2bf835 René Nussbaumer
     getent.masterd_uid, getent.masterd_gid),
166 0d2bf835 René Nussbaumer
    (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
167 0d2bf835 René Nussbaumer
    (constants.RAPI_USERS_FILE, FILE, 0640, getent.rapi_uid,
168 0d2bf835 René Nussbaumer
     getent.masterd_gid, False),
169 0d2bf835 René Nussbaumer
    (constants.RUN_GANETI_DIR, DIR, 0775, getent.masterd_uid,
170 0d2bf835 René Nussbaumer
     getent.daemons_gid),
171 0d2bf835 René Nussbaumer
    (constants.SOCKET_DIR, DIR, 0750, getent.masterd_uid,
172 0d2bf835 René Nussbaumer
     getent.daemons_gid),
173 0d2bf835 René Nussbaumer
    (constants.MASTER_SOCKET, FILE, 0770, getent.masterd_uid,
174 0d2bf835 René Nussbaumer
     getent.daemons_gid, False),
175 0d2bf835 René Nussbaumer
    (constants.BDEV_CACHE_DIR, DIR, 0755, getent.noded_uid,
176 0d2bf835 René Nussbaumer
     getent.masterd_gid),
177 0d2bf835 René Nussbaumer
    (constants.UIDPOOL_LOCKDIR, DIR, 0750, getent.noded_uid,
178 0d2bf835 René Nussbaumer
     getent.masterd_gid),
179 0d2bf835 René Nussbaumer
    (constants.DISK_LINKS_DIR, DIR, 0755, getent.noded_uid,
180 0d2bf835 René Nussbaumer
     getent.masterd_gid),
181 0d2bf835 René Nussbaumer
    (constants.CRYPTO_KEYS_DIR, DIR, 0700, getent.noded_uid,
182 0d2bf835 René Nussbaumer
     getent.masterd_gid),
183 0d2bf835 René Nussbaumer
    (constants.IMPORT_EXPORT_DIR, DIR, 0755, getent.noded_uid,
184 0d2bf835 René Nussbaumer
     getent.masterd_gid),
185 0d2bf835 René Nussbaumer
    (constants.LOG_DIR, DIR, 0770, getent.masterd_uid,
186 0d2bf835 René Nussbaumer
     getent.daemons_gid),
187 0d2bf835 René Nussbaumer
    (masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid,
188 0d2bf835 René Nussbaumer
     False),
189 0d2bf835 René Nussbaumer
    (confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False),
190 0d2bf835 René Nussbaumer
    (noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False),
191 0d2bf835 René Nussbaumer
    (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False),
192 0d2bf835 René Nussbaumer
    (constants.LOG_OS_DIR, DIR, 0750, getent.masterd_uid,
193 0d2bf835 René Nussbaumer
     getent.daemons_gid),
194 0d2bf835 René Nussbaumer
    ])
195 0d2bf835 René Nussbaumer
196 0d2bf835 René Nussbaumer
  return tuple(paths)
197 0d2bf835 René Nussbaumer
198 0d2bf835 René Nussbaumer
199 961226f6 Michael Hanselmann
def SetupLogging(opts):
200 961226f6 Michael Hanselmann
  """Configures the logging module.
201 961226f6 Michael Hanselmann

202 961226f6 Michael Hanselmann
  """
203 961226f6 Michael Hanselmann
  formatter = logging.Formatter("%(asctime)s: %(message)s")
204 961226f6 Michael Hanselmann
205 961226f6 Michael Hanselmann
  stderr_handler = logging.StreamHandler()
206 961226f6 Michael Hanselmann
  stderr_handler.setFormatter(formatter)
207 961226f6 Michael Hanselmann
  if opts.debug:
208 961226f6 Michael Hanselmann
    stderr_handler.setLevel(logging.NOTSET)
209 961226f6 Michael Hanselmann
  elif opts.verbose:
210 961226f6 Michael Hanselmann
    stderr_handler.setLevel(logging.INFO)
211 961226f6 Michael Hanselmann
  else:
212 961226f6 Michael Hanselmann
    stderr_handler.setLevel(logging.WARNING)
213 961226f6 Michael Hanselmann
214 961226f6 Michael Hanselmann
  root_logger = logging.getLogger("")
215 961226f6 Michael Hanselmann
  root_logger.setLevel(logging.NOTSET)
216 961226f6 Michael Hanselmann
  root_logger.addHandler(stderr_handler)
217 961226f6 Michael Hanselmann
218 961226f6 Michael Hanselmann
219 0d2bf835 René Nussbaumer
def ParseOptions():
220 0d2bf835 René Nussbaumer
  """Parses the options passed to the program.
221 0d2bf835 René Nussbaumer

222 0d2bf835 René Nussbaumer
  @return: Options and arguments
223 0d2bf835 René Nussbaumer

224 0d2bf835 René Nussbaumer
  """
225 0d2bf835 René Nussbaumer
  program = os.path.basename(sys.argv[0])
226 0d2bf835 René Nussbaumer
227 0d2bf835 René Nussbaumer
  parser = optparse.OptionParser(usage="%%prog [--full-run]",
228 0d2bf835 René Nussbaumer
                                 prog=program)
229 961226f6 Michael Hanselmann
  parser.add_option(cli.DEBUG_OPT)
230 961226f6 Michael Hanselmann
  parser.add_option(cli.VERBOSE_OPT)
231 0d2bf835 René Nussbaumer
  parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
232 297657a2 Michael Hanselmann
                    default=False, help=("Make a full run and set permissions"
233 297657a2 Michael Hanselmann
                                         " on archived jobs (time consuming)"))
234 0d2bf835 René Nussbaumer
235 0d2bf835 René Nussbaumer
  return parser.parse_args()
236 0d2bf835 René Nussbaumer
237 0d2bf835 René Nussbaumer
238 0d2bf835 René Nussbaumer
def Main():
239 0d2bf835 René Nussbaumer
  """Main routine.
240 0d2bf835 René Nussbaumer

241 0d2bf835 René Nussbaumer
  """
242 0d2bf835 René Nussbaumer
  (opts, _) = ParseOptions()
243 0d2bf835 René Nussbaumer
244 961226f6 Michael Hanselmann
  SetupLogging(opts)
245 961226f6 Michael Hanselmann
246 961226f6 Michael Hanselmann
  if opts.full_run:
247 961226f6 Michael Hanselmann
    logging.info("Running in full mode")
248 961226f6 Michael Hanselmann
249 961226f6 Michael Hanselmann
  getent = runtime.GetEnts()
250 961226f6 Michael Hanselmann
251 0d2bf835 René Nussbaumer
  try:
252 0d2bf835 René Nussbaumer
    for path in GetPaths():
253 0d2bf835 René Nussbaumer
      ProcessPath(path)
254 0d2bf835 René Nussbaumer
255 0d2bf835 René Nussbaumer
    if opts.full_run:
256 0d2bf835 René Nussbaumer
      RecursiveEnsure(constants.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
257 0d2bf835 René Nussbaumer
                      getent.masterd_gid, 0700, 0600)
258 b81b3c96 René Nussbaumer
  except errors.GenericError, err:
259 961226f6 Michael Hanselmann
    logging.error("An error occurred while setting permissions: %s", err)
260 0d2bf835 René Nussbaumer
    return constants.EXIT_FAILURE
261 0d2bf835 René Nussbaumer
262 0d2bf835 René Nussbaumer
  return constants.EXIT_SUCCESS