from .cfg_app import PpCfgAppError, PpConfigApplication
-__version__ = '0.1.1'
+__version__ = '0.2.1'
LOG = logging.getLogger(__name__)
default_home_root = os.sep + 'home'
# /etc/pixelpark/exclude_homes
- default_exlude_file = os.sep + os.path.join('etc', 'pixelpark', 'exclude_homes')
+ default_exclude_file = os.sep + os.path.join('etc', 'pixelpark', 'exclude_homes')
default_mail_recipients = [
'frank.brehm@pixelpark.com'
default_reply_to = 'frank.brehm@pixelpark.com'
+ comment_re = re.compile(r'\s*#.*')
+ whitespace_re = re.compile(r'(?:[,;]+|\s*[,;]*\s+)')
+
# -------------------------------------------------------------------------
def __init__(self, appname=None, version=__version__):
self.home_root_abs = self.default_home_root
self.home_root_rel = os.path.relpath(self.home_root_abs, os.sep)
+ self.exclude_file = self.default_exclude_file
+
self.mail_recipients = copy.copy(self.default_mail_recipients)
self.mail_cc = copy.copy(self.default_mail_cc)
self.reply_to = self.default_reply_to
This scripts detects unnecessary home directories - without an
appropriate home directory in the passwd database and not excluded
in {!r}.
- ''').strip().format(self.default_exlude_file)
+ ''').strip().format(self.default_exclude_file)
super(PpTestHomeApp, self).__init__(
appname=appname, version=version, description=description,
self.initialized = True
+ # -------------------------------------------------------------------------
+ def perform_config(self):
+
+ super(PpTestHomeApp, self).perform_config()
+
+ for section_name in self.cfg.keys():
+
+ if self.verbose > 2:
+ LOG.debug("Checking config section {!r} ...".format(section_name))
+
+ if section_name.lower() not in ('test-home', 'test_home', 'testhome') :
+ continue
+
+ section = self.cfg[section_name]
+ if self.verbose > 2:
+ LOG.debug("Evaluating config section {n!r}:\n{s}".format(
+ n=section_name, s=pp(section)))
+
+ if 'chroot_homedir' in section:
+ v = section['chroot_homedir']
+ if not os.path.isabs(v):
+ msg = (
+ "The chrooted path of the home directories must be an "
+ "absolute pathname (found [{s}]/chroot_homedir "
+ "=> {v!r} in configuration.").format(s=section_name, v=v)
+ raise PpMkHomeError(msg)
+ self.chroot_homedir = v
+
+ if 'home_root' in section:
+ v = section['home_root']
+ if not os.path.isabs(v):
+ msg = (
+ "The root path of the home directories must be an "
+ "absolute pathname (found [{s}]/home_root "
+ "=> {v!r} in configuration.").format(s=section_name, v=v)
+ raise PpMkHomeError(msg)
+ self.home_root_abs = v
+
+ if 'exclude_file' in section:
+ v = section['exclude_file']
+ if not os.path.isabs(v):
+ msg = (
+ "The path of file of excluded directories must be an "
+ "absolute pathname (found [{s}]/exclude_file "
+ "=> {v!r} in configuration.").format(s=section_name, v=v)
+ raise PpMkHomeError(msg)
+ self.exclude_file = v
+
+ self.home_root_rel = os.path.relpath(self.home_root_abs, os.sep)
+ self.home_root_real = os.path.join(self.chroot_homedir, self.home_root_rel)
+
# -------------------------------------------------------------------------
def _run(self):
- LOG.info("Jetzt geht's los ...")
+ self.read_exclude_dirs()
+
+ # -------------------------------------------------------------------------
+ def read_exclude_dirs(self):
+
+ LOG.info("Reading exclude file {!r} ...".format(self.exclude_file))
+ upper_dir = os.pardir + os.sep
+
+ if not os.path.exists(self.exclude_file):
+ msg = "Exclude file {!r} does not exists.".format(self.exclude_file)
+ LOG.error(msg)
+ return
+
+ if not os.path.isfile(self.exclude_file):
+ msg = "Exclude file {!r} is not a regular file.".format(self.exclude_file)
+ LOG.error(msg)
+ return
+
+ if not os.access(self.exclude_file, os.R_OK):
+ msg = "No read access to exclude file {!r}.".format(self.exclude_file)
+ LOG.error(msg)
+ return
+
+ open_args = {}
+ if six.PY3:
+ open_args['encoding'] = 'utf-8'
+ open_args['errors'] = 'surrogateescape'
+
+ with open(self.exclude_file, 'r', **open_args) as fh:
+ lnr = 0
+ for line in fh.readlines():
+ lnr += 1
+ line = line.strip()
+ if not line:
+ continue
+ line = self.comment_re.sub('', line)
+ if not line:
+ continue
+ if self.verbose > 3:
+ LOG.debug("Evaluating line {l!r} (file {f!r}, line {lnr}).".format(
+ l=line, f=self.exclude_file, lnr=lnr))
+ tokens = self.whitespace_re.split(line)
+ for token in tokens:
+ if not os.path.isabs(token):
+ LOG.warn((
+ "Entry {e!r} in file {f!r}, line {l}, "
+ "is not an absolute path.").format(
+ e=token, f=self.exclude_file, l=lnr))
+ continue
+ home_relative = os.path.relpath(token, self.home_root_abs)
+ if home_relative.startswith(upper_dir):
+ LOG.warn((
+ "Entry {e!r} in file {f!r}, line {l}, "
+ "is outside home root {h!r}.").format(
+ e=token, f=self.exclude_file, l=lnr, h=self.home_root_abs))
+ continue
+ if not token in self.exclude_dirs:
+ self.exclude_dirs.append(token)
+
+ self.exclude_dirs.sort(key=str.lower)
+
+ if self.verbose > 2:
+ LOG.debug("Found directories to exclude:\n{}".format(pp(self.exclude_dirs)))
# =============================================================================