Skip to content

Commit

Permalink
Merge pull request #359 from kubilus1/mountplaceholder
Browse files Browse the repository at this point in the history
Restore a placeholder dir for each scenery when unmounting.
  • Loading branch information
kubilus1 authored Sep 1, 2023
2 parents 6b74b5c + 0fbb4ee commit e74b701
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 71 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ autoortho.pyz:

lin_bin: autoortho_lin_$(VERSION).bin
autoortho_lin_$(VERSION).bin: autoortho/*.py
docker run --rm -v `pwd`:/code ubuntu:focal /bin/bash -c "cd /code; ./buildreqs.sh; time make bin"
docker run --rm -v `pwd`:/code ubuntu:focal /bin/bash -c "cd /code; ./buildreqs.sh; time make bin VERSION=$(VERSION)"
mv autoortho_lin.bin $@

enter:
Expand Down
171 changes: 101 additions & 70 deletions autoortho/autoortho.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,95 @@
#!/usr/bin/env python

import os
import signal
import sys
import time
import ctypes
import shutil
import signal
import tempfile
import platform
import argparse
import threading
import tempfile
import importlib

from pathlib import Path
from contextlib import contextmanager

import aoconfig
import aostats
import winsetup
import config_ui

import flighttrack
import importlib

from version import __version__

import logging
log = logging.getLogger(__name__)

import geocoder
import ctypes

class MountError(Exception):
pass

class AutoOrthoError(Exception):
pass

@contextmanager
def setupmount(mountpoint, systemtype):
mountpoint = os.path.expanduser(mountpoint)

placeholder_path = os.path.join(mountpoint, ".AO_PLACEHOLDER")

# Stash placeholder
if os.path.isdir(mountpoint):
log.info(f"Existing mountpoint detected: {mountpoint}")
if os.path.lexists(placeholder_path):
log.info(f"Detected placeholder dir. Removing: {mountpoint}")
shutil.rmtree(mountpoint)

# Setup
log.info(f"Setting up mountpoint: {mountpoint}")
if systemtype == "Linux-FUSE":
if not os.path.exists(mountpoint):
os.makedirs(mountpoint)
if not os.path.isdir(mountpoint):
raise MountError(f"Failed to setup mount point {mountpoint}!")

elif systemtype == "dokan-FUSE":
ret = winsetup.setup_dokan_mount(mountpoint)
if not ret:
raise MountError(f"Failed to setup mount point {mountpoint}!")

elif systemtype == "winfsp-FUSE":
ret = winsetup.setup_winfsp_mount(mountpoint)
if not ret:
raise MountError(f"Failed to setup mount point {mountpoint}!")

else:
log.error(f"Unknown mount type of {systemtype}!")
time.sleep(5)
raise MountError(f"Unknown system type: {systemtype} for mount {mountpoint}")

yield mountpoint

# Cleanup
if os.path.lexists(mountpoint):
log.info(f"Cleaning up mountpoint: {mountpoint}")
os.rmdir(mountpoint)

# Restore placeholder
log.info(f"Restoring placeholder for mountpoint: {mountpoint}")
structure = [
os.path.join(mountpoint, 'Earth nav data'),
os.path.join(mountpoint, 'terrain'),
os.path.join(mountpoint, 'textures'),
]

for d in structure:
os.makedirs(d)

Path(placeholder_path).touch()
log.info(f"Mount point {mountpoint} exiting.")


def diagnose(CFG):
Expand Down Expand Up @@ -88,9 +154,6 @@ def diagnose(CFG):

def run(root, mountpoint, threading=True):
global RUNNING
#aostats.STATS = statsdict
#import flighttrack
#flighttrack.ft.running = flight_running

if threading:
log.info("Running in multi-threaded mode.")
Expand All @@ -99,69 +162,37 @@ def run(root, mountpoint, threading=True):
log.info("Running in single-threaded mode.")
nothreads = True

if platform.system() == 'Windows':
systemtype, libpath = winsetup.find_win_libs()
if systemtype == "dokan-FUSE":
# Windows user mode FS support is kind of a mess, so try a few things.
log.info("Running in Windows FUSE mode with Dokan.")
os.environ['FUSE_LIBRARY_PATH'] = libpath
root = os.path.expanduser(root)
mountpoint = os.path.expanduser(mountpoint)
ret = winsetup.setup_dokan_mount(mountpoint)
if not ret:
log.error(f"Mount point setup failed for {mountpoint}!")
RUNNING = False
return
log.info(f"AutoOrtho: root: {root} mountpoint: {mountpoint}")
import autoortho_fuse
from refuse import high
high._libfuse = ctypes.CDLL(libpath)
autoortho_fuse.run(
autoortho_fuse.AutoOrtho(root),
mountpoint,
nothreads
)
elif systemtype == "winfsp-FUSE":
log.info("Running in Windows FUSE mode with WinFSP.")
os.environ['FUSE_LIBRARY_PATH'] = libpath
root = os.path.expanduser(root)
mountpoint = os.path.expanduser(mountpoint)
ret = winsetup.setup_winfsp_mount(mountpoint)
if not ret:
log.error(f"Mount point setup failed for {mountpoint}!")
RUNNING = False
return
log.info(f"AutoOrtho: root: {root} mountpoint: {mountpoint}")
import autoortho_fuse
from refuse import high
high._libfuse = ctypes.CDLL(libpath)
autoortho_fuse.run(
autoortho_fuse.AutoOrtho(root),
mountpoint,
nothreads
)
root = os.path.expanduser(root)

try:
if platform.system() == 'Windows':
systemtype, libpath = winsetup.find_win_libs()
with setupmount(mountpoint, systemtype) as mount:
log.info(f"AutoOrtho: root: {root} mountpoint: {mount}")
import autoortho_fuse
from refuse import high
high._libfuse = ctypes.CDLL(libpath)
autoortho_fuse.run(
autoortho_fuse.AutoOrtho(root),
mount,
nothreads
)
else:
log.error(f"Unknown mount type of {systemtype}!")
time.sleep(5)
sys.exit(1)
else:
log.info("Running in FUSE mode.")
root = os.path.expanduser(root)
mountpoint = os.path.expanduser(mountpoint)

if not os.path.exists(mountpoint):
os.makedirs(mountpoint)
if not os.path.isdir(mountpoint):
log.error(f"WARNING: {mountpoint} is not a directory. Exiting.")
sys.exit(1)

log.info(f"AutoOrtho: root: {root} mountpoint: {mountpoint}")
import autoortho_fuse
autoortho_fuse.run(
autoortho_fuse.AutoOrtho(root),
mountpoint,
nothreads
)
with setupmount(mountpoint, "Linux-FUSE") as mount:
log.info("Running in FUSE mode.")
log.info(f"AutoOrtho: root: {root} mountpoint: {mount}")
import autoortho_fuse
autoortho_fuse.run(
autoortho_fuse.AutoOrtho(root),
mount,
nothreads
)

except Exception as err:
log.error(f"Exception detected when running FUSE mount: {err}. Exiting...")
RUNNING = False
time.sleep(5)


def unmount(mountpoint):
mounted = True
Expand Down
24 changes: 24 additions & 0 deletions autoortho/test_autoortho.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,27 @@ def test_read_dds_abs(mount):


log.info(f"CWD: {os.getcwd()}")

@pytest.mark.parametrize("prefer_winfsp", [True, False])
def test_mount_restore(tmpdir, scenery_dir, prefer_winfsp):
mountdir = str(os.path.abspath(os.path.join(tmpdir, 'mount')))
cachedir = str(os.path.join(tmpdir, 'cache'))
rootdir = scenery_dir


t = threading.Thread(
daemon = True,
target = autoortho.run,
args = (rootdir, mountdir)
)

t.start()
time.sleep(1)

assert os.path.isdir(os.path.join(mountdir, "textures"))

log.debug(f"Unmount {mountdir}")
autoortho.unmount(mountdir)
t.join(1)

assert os.path.lexists(os.path.join(mountdir, ".AO_PLACEHOLDER"))

0 comments on commit e74b701

Please sign in to comment.