# Path: src/imgbased/command.py
# def nsenter(arg, new_root=None, shell=False, environ=None):
#     DEVNULL = open(os.devnull, "w")
#     if new_root:
#         if shell:
#             arg = "nsenter --root={0} --wd={0} {1}".format(new_root, arg)
#         else:
#             arg = [
#                 "nsenter",
#                 "--root={}".format(new_root),
#                 "--wd={}".format(new_root),
#             ] + arg
#     environ = environ or os.environ
#     log.debug("Executing: %s", arg)
#     proc = subprocess.Popen(arg, stdout=subprocess.PIPE, env=environ,
#                             stderr=DEVNULL, shell=shell).communicate()
#     ret = proc[0]
#     log.debug("Result: %s", repr(ret))
#     return ret
# 
# Path: src/imgbased/utils.py
# class File(object):
#     filename = None
# 
#     @property
#     def contents(self):
#         return self.read()
# 
#     @property
#     def stat(self):
#         return os.stat(self.filename)
# 
#     def __init__(self, fn):
#         self.filename = fn
# 
#     def __str__(self):
#         return "<%s %s>" % (self.__class__.__name__, self.filename)
# 
#     def read(self):
#         with open(self.filename) as src:
#             return src.read()
# 
#     def exists(self):
#         return os.path.exists(self.filename)
# 
#     def replace(self, pat, repl):
#         self.write(self.contents.replace(pat, repl))
# 
#     def sub(self, pat, repl):
#         self.write(re.sub(pat, repl, self.contents))
# 
#     def write(self, data, mode="w", mkdir=False):
#         if mkdir:
#             os.makedirs(os.path.dirname(self.filename))
#         with open(self.filename, mode) as dst:
#             dst.write(data)
# 
#     def writen(self, data, mode="w"):
#         self.write(data + "\n", mode)
# 
#     def remove(self):
#         os.unlink(self.filename)
# 
#     def lines(self, keepends=False):
#         for line in self.contents.splitlines(keepends):
#             yield line
# 
#     def findall(self, pat):
#         r = []
#         for line in self.lines():
#             r += re.findall(pat, line)
#         return r
# 
#     def chmod(self, mode):
#         return os.chmod(self.filename, mode)
# 
#     def basename(self):
#         return os.path.basename(self.filename)
# 
#     def truncate(self, size=0):
#         """Truncate the file to size
#         """
#         with open(self.filename, "w") as fd:
#             fd.truncate(size)
# 
# @contextmanager
# def bindmounted(source, target, rbind=False, readonly=False):
#     options = "rbind" if rbind else "bind,private"
#     options = options + ",ro" if readonly else options
#     with mounted(source, target=target, options=options) as mnt:
#         yield mnt
#     log.debug("Done!")


import logging
import os
import time
from six.moves.configparser import ConfigParser
from systemd import journal
from .command import nsenter
from .constants import IMGBASED_STATE_DIR
from .utils import File, bindmounted
        else:
            self.configure()

    def register(self, datastream, profile):
        log.info("Registering profile %s from %s", profile, datastream)
        if profile not in self.profiles(datastream):
            log.error("Profile %s not found", profile)
            return
        self._config.datastream = os.path.realpath(datastream)
        self._config.profile = profile

    def unregister(self, profile):
        if profile == self._config.profile:
            log.info("Unregistering profile %s", profile)
            self._config.profile = ""
        else:
            log.warn("Profile [%s] is not registered, skipping", profile)

    def scan(self, remediate=False, path="/"):
        log.debug("Running OSCAP scan on %s, (remediate=%s)", path, remediate)
        if not self._config.registered:
            log.warn("Security profile not registered, skipping")
            return
        report = SCAP_REPORT_FMT % time.strftime("%Y%m%d%H%M%S")
        args = ["chroot", path, "oscap", "xccdf", "eval",
                "--profile", self.profile, "--report", report]
        if remediate:
            args.append("--remediate")
        args.append(self._config.datastream)
        with bindmounted("/proc", path + "/proc"):

# Path: src/imgbased/command.py
# def nsenter(arg, new_root=None, shell=False, environ=None):
#     DEVNULL = open(os.devnull, "w")
#     if new_root:
#         if shell:
#             arg = "nsenter --root={0} --wd={0} {1}".format(new_root, arg)
#         else:
#             arg = [
#                 "nsenter",
#                 "--root={}".format(new_root),
#                 "--wd={}".format(new_root),
#             ] + arg
#     environ = environ or os.environ
#     log.debug("Executing: %s", arg)
#     proc = subprocess.Popen(arg, stdout=subprocess.PIPE, env=environ,
#                             stderr=DEVNULL, shell=shell).communicate()
#     ret = proc[0]
#     log.debug("Result: %s", repr(ret))
#     return ret
# 
# Path: src/imgbased/utils.py
# class File(object):
#     filename = None
# 
#     @property
#     def contents(self):
#         return self.read()
# 
#     @property
#     def stat(self):
#         return os.stat(self.filename)
# 
#     def __init__(self, fn):
#         self.filename = fn
# 
#     def __str__(self):
#         return "<%s %s>" % (self.__class__.__name__, self.filename)
# 
#     def read(self):
#         with open(self.filename) as src:
#             return src.read()
# 
#     def exists(self):
#         return os.path.exists(self.filename)
# 
#     def replace(self, pat, repl):
#         self.write(self.contents.replace(pat, repl))
# 
#     def sub(self, pat, repl):
#         self.write(re.sub(pat, repl, self.contents))
# 
#     def write(self, data, mode="w", mkdir=False):
#         if mkdir:
#             os.makedirs(os.path.dirname(self.filename))
#         with open(self.filename, mode) as dst:
#             dst.write(data)
# 
#     def writen(self, data, mode="w"):
#         self.write(data + "\n", mode)
# 
#     def remove(self):
#         os.unlink(self.filename)
# 
#     def lines(self, keepends=False):
#         for line in self.contents.splitlines(keepends):
#             yield line
# 
#     def findall(self, pat):
#         r = []
#         for line in self.lines():
#             r += re.findall(pat, line)
#         return r
# 
#     def chmod(self, mode):
#         return os.chmod(self.filename, mode)
# 
#     def basename(self):
#         return os.path.basename(self.filename)
# 
#     def truncate(self, size=0):
#         """Truncate the file to size
#         """
#         with open(self.filename, "w") as fd:
#             fd.truncate(size)
# 
# @contextmanager
# def bindmounted(source, target, rbind=False, readonly=False):
#     options = "rbind" if rbind else "bind,private"
#     options = options + ",ro" if readonly else options
#     with mounted(source, target=target, options=options) as mnt:
#         yield mnt
#     log.debug("Done!")


# Path: src/imgbased/openscap.py
import logging
import os
import time
from six.moves.configparser import ConfigParser
from systemd import journal
from .command import nsenter
from .constants import IMGBASED_STATE_DIR
from .utils import File, bindmounted

        else:
            self.configure()

    def register(self, datastream, profile):
        log.info("Registering profile %s from %s", profile, datastream)
        if profile not in self.profiles(datastream):
            log.error("Profile %s not found", profile)
            return
        self._config.datastream = os.path.realpath(datastream)
        self._config.profile = profile

    def unregister(self, profile):
        if profile == self._config.profile:
            log.info("Unregistering profile %s", profile)
            self._config.profile = ""
        else:
            log.warn("Profile [%s] is not registered, skipping", profile)

    def scan(self, remediate=False, path="/"):
        log.debug("Running OSCAP scan on %s, (remediate=%s)", path, remediate)
        if not self._config.registered:
            log.warn("Security profile not registered, skipping")
            return
        report = SCAP_REPORT_FMT % time.strftime("%Y%m%d%H%M%S")
        args = ["chroot", path, "oscap", "xccdf", "eval",
                "--profile", self.profile, "--report", report]
        if remediate:
            args.append("--remediate")
        args.append(self._config.datastream)
        with bindmounted("/proc", path + "/proc"):

            with bindmounted("/var", path + "/var", rbind=True):