Beispiel #1
0
def prepare_tmpfs(version_info: VersionInfo, site: SiteContext) -> None:
    if tmpfs_mounted(site.name):
        sys.stdout.write("Temporary filesystem already mounted\n")
        return  # Fine: Mounted

    if site.conf["TMPFS"] != "on":
        sys.stdout.write("Preparing tmp directory %s..." % site.tmp_dir)
        sys.stdout.flush()

        if os.path.exists(site.tmp_dir):
            return

        try:
            os.mkdir(site.tmp_dir)
        except OSError as e:
            if e.errno != errno.EEXIST:  # File exists
                raise
        return

    sys.stdout.write("Creating temporary filesystem %s..." % site.tmp_dir)
    sys.stdout.flush()
    if not os.path.exists(site.tmp_dir):
        os.mkdir(site.tmp_dir)

    mount_options = shlex.split(version_info.MOUNT_OPTIONS)
    p = subprocess.Popen(  # pylint:disable=consider-using-with
        ["mount"] + mount_options + [site.tmp_dir],
        shell=False,
        stdin=open(os.devnull),  # pylint:disable=consider-using-with
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        encoding="utf-8",
    )
    exit_code = p.wait()
    if exit_code == 0:
        ok()
        return  # Fine: Mounted

    if p.stdout is None:
        raise Exception("stdout needs to be set")

    sys.stdout.write(p.stdout.read())
    if is_dockerized():
        sys.stdout.write(
            tty.warn + ": "
            "Could not mount tmpfs. You may either start the container in "
            'privileged mode or use the "docker run" option "--tmpfs" to '
            "make docker do the tmpfs mount for the site.\n"
        )

    sys.stdout.write(
        tty.warn + ": You may continue without tmpfs, but the "
        "performance of Check_MK may be degraded.\n"
    )
Beispiel #2
0
def remove_from_fstab(site: SiteContext) -> None:
    if not os.path.exists("/etc/fstab"):
        return  # Don't do anything in case there is no fstab

    mountpoint = site.tmp_dir
    sys.stdout.write("Removing %s from /etc/fstab..." % mountpoint)
    newtab = open("/etc/fstab.new", "w")
    for line in open("/etc/fstab"):
        if "uid=%s," % site.name in line and mountpoint in line:
            continue
        newtab.write(line)
    os.rename("/etc/fstab.new", "/etc/fstab")
    ok()
Beispiel #3
0
def unmount_tmpfs(site: SiteContext,
                  output: bool = True,
                  kill: bool = False) -> bool:
    # During omd update TMPFS hook might not be set so assume
    # that the hook is enabled by default.
    # If kill is True, then we do an fuser -k on the tmp
    # directory first.

    # For some files in tmpfs we want the IO performance of the tmpfs and
    # want to keep the files between unmount / mount operations (if possible).
    if os.path.exists(site.tmp_dir):
        if output:
            sys.stdout.write("Saving temporary filesystem contents...")
        save_tmpfs_dump(site)
        if output:
            ok()

    # Clear directory hierarchy when not using a tmpfs
    if not tmpfs_mounted(site.name) or _tmpfs_is_managed_by_node(site):
        tmp = site.tmp_dir
        if os.path.exists(tmp):
            if output:
                sys.stdout.write("Cleaning up tmp directory...")
                sys.stdout.flush()
            delete_directory_contents(tmp)
            if output:
                ok()
        return True

    if output:
        sys.stdout.write("Unmounting temporary filesystem...")

    for _t in range(0, 10):
        if not tmpfs_mounted(site.name):
            if output:
                ok()
            return True

        if _unmount(site):
            if output:
                ok()
            return True

        if kill:
            if output:
                sys.stdout.write("Killing processes still using '%s'\n" %
                                 site.tmp_dir)
            subprocess.call(["fuser", "--silent", "-k", site.tmp_dir])

        if output:
            sys.stdout.write(kill and "K" or ".")
            sys.stdout.flush()
        time.sleep(1)

    if output:
        raise SystemExit(tty.error + ": Cannot unmount temporary filesystem.")

    return False
Beispiel #4
0
def remove_from_fstab(site: SiteContext) -> None:
    if not (path_fstab := fstab_path()).exists():
        return  # Don't do anything in case there is no fstab

    mountpoint = site.tmp_dir
    sys.stdout.write(f"Removing {mountpoint} from {path_fstab}...")

    with (path_new_fstab := Path(str(path_fstab) + ".new")).open(
        mode="w"
    ) as newtab, path_fstab.open() as current_fstab:
        for line in current_fstab:
            if "uid=%s," % site.name in line and mountpoint in line:
                continue
            newtab.write(line)
    path_new_fstab.rename(path_fstab)
    ok()


def save_tmpfs_dump(site):
    # type: (SiteContext) -> None
    """Dump tmpfs content for later restore after remount

    Creates a tar archive from the current tmpfs contents that is restored to the
    tmpfs later after mounting it again.

    Please note that this only preserves specific files, not the whole tmpfs.
    """
    save_paths = [
        Path(site.tmp_dir) / "check_mk" / "piggyback",
        Path(site.tmp_dir) / "check_mk" / "piggyback_sources",
    ]