[ARVADOS] created: bf234475965f5908355435b246ac696c35d54556
git at public.curoverse.com
git at public.curoverse.com
Mon Dec 14 14:04:47 EST 2015
at bf234475965f5908355435b246ac696c35d54556 (commit)
commit bf234475965f5908355435b246ac696c35d54556
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date: Fri Dec 11 14:49:01 2015 -0500
7939: Move daemonize to _run_standalone() after llfuse.init(), preserving open
file descriptors. Add tests for various error conditions that can prevent
successful mount.
diff --git a/services/fuse/arvados_fuse/command.py b/services/fuse/arvados_fuse/command.py
index 93bcd20..11935ad 100644
--- a/services/fuse/arvados_fuse/command.py
+++ b/services/fuse/arvados_fuse/command.py
@@ -4,6 +4,7 @@ import daemon
import llfuse
import logging
import os
+import resource
import signal
import subprocess
import sys
@@ -95,14 +96,6 @@ class Mount(object):
if self.args.logfile:
self.args.logfile = os.path.realpath(self.args.logfile)
- # Daemonize as early as possible, so we don't accidentally close
- # file descriptors we're using.
- self.daemon_ctx = None
- if not (self.args.exec_args or self.args.foreground):
- os.chdir(self.args.mountpoint)
- self.daemon_ctx = daemon.DaemonContext(working_directory='.')
- self.daemon_ctx.open()
-
try:
self._setup_logging()
self._setup_api()
@@ -141,8 +134,6 @@ class Mount(object):
# Configure a log handler based on command-line switches.
if self.args.logfile:
log_handler = logging.FileHandler(self.args.logfile)
- elif self.daemon_ctx:
- log_handler = logging.NullHandler()
else:
log_handler = None
@@ -162,6 +153,7 @@ class Mount(object):
keep_params={
"block_cache": arvados.keep.KeepBlockCache(self.args.file_cache)
})
+ self.api.users().current().execute()
def _setup_mount(self):
self.operations = Operations(
@@ -189,6 +181,8 @@ class Mount(object):
if self.args.collection is not None:
# Set up the request handler with the collection at the root
+ # First check that the collection is readable
+ self.api.collections().get(uuid=self.args.collection).execute()
self.args.mode = 'collection'
dir_class = CollectionDirectory
dir_args.append(self.args.collection)
@@ -326,6 +320,11 @@ From here, the following directories are available:
try:
llfuse.init(self.operations, self.args.mountpoint, self._fuse_options())
+ if not (self.args.exec_args or self.args.foreground):
+ self.daemon_ctx = daemon.DaemonContext(working_directory=os.path.dirname(self.args.mountpoint),
+ files_preserve=range(3, resource.getrlimit(resource.RLIMIT_NOFILE)[1]))
+ self.daemon_ctx.open()
+
# Subscribe to change events from API server
self.operations.listen_for_events()
diff --git a/services/fuse/tests/test_command_args.py b/services/fuse/tests/test_command_args.py
index 19d56a9..8f040bc 100644
--- a/services/fuse/tests/test_command_args.py
+++ b/services/fuse/tests/test_command_args.py
@@ -187,3 +187,65 @@ class MountArgsTest(unittest.TestCase):
'--mount-tmp', name,
'--foreground', self.mntdir])
arvados_fuse.command.Mount(args)
+
+class MountErrorTest(unittest.TestCase):
+ def setUp(self):
+ self.mntdir = tempfile.mkdtemp()
+ run_test_server.run()
+ run_test_server.authorize_with("active")
+ self.logger = logging.getLogger("null")
+ self.logger.setLevel(logging.CRITICAL+1)
+
+ def tearDown(self):
+ if os.path.exists(self.mntdir):
+ # If the directory was not unmounted, this will raise an exception.
+ os.rmdir(self.mntdir)
+ run_test_server.reset()
+
+ def test_no_token(self):
+ del arvados.config._settings["ARVADOS_API_TOKEN"]
+ arvados.config._settings = {}
+ with self.assertRaises(SystemExit):
+ args = arvados_fuse.command.ArgumentParser().parse_args([self.mntdir])
+ arvados_fuse.command.Mount(args, logger=self.logger).run()
+
+ def test_no_host(self):
+ del arvados.config._settings["ARVADOS_API_HOST"]
+ with self.assertRaises(SystemExit):
+ args = arvados_fuse.command.ArgumentParser().parse_args([self.mntdir])
+ arvados_fuse.command.Mount(args, logger=self.logger).run()
+
+ def test_bogus_host(self):
+ arvados.config._settings["ARVADOS_API_HOST"] = "example.null"
+ with self.assertRaises(SystemExit):
+ args = arvados_fuse.command.ArgumentParser().parse_args([self.mntdir])
+ arvados_fuse.command.Mount(args, logger=self.logger).run()
+
+ def test_bogus_mount_dir(self):
+ # All FUSE errors in llfuse.init() are raised as RuntimeError
+ # An easy error to trigger is to supply a nonexistent mount point,
+ # so test that one.
+ #
+ # Other possible errors that also raise RuntimeError (but are much
+ # harder to test automatically because they depend on operating
+ # system configuration):
+ #
+ # The user doesn't have permission to use FUSE
+ # The user specified --allow-other but user_allow_other is not set
+ # in /etc/fuse.conf
+ os.rmdir(self.mntdir)
+ with self.assertRaises(SystemExit):
+ args = arvados_fuse.command.ArgumentParser().parse_args([self.mntdir])
+ arvados_fuse.command.Mount(args, logger=self.logger).run()
+
+ def test_unreadable_collection(self):
+ with self.assertRaises(SystemExit):
+ args = arvados_fuse.command.ArgumentParser().parse_args([
+ "--collection", "zzzzz-4zz18-zzzzzzzzzzzzzzz", self.mntdir])
+ arvados_fuse.command.Mount(args, logger=self.logger).run()
+
+ def test_unreadable_project(self):
+ with self.assertRaises(SystemExit):
+ args = arvados_fuse.command.ArgumentParser().parse_args([
+ "--project", "zzzzz-j7d0g-zzzzzzzzzzzzzzz", self.mntdir])
+ arvados_fuse.command.Mount(args, logger=self.logger).run()
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list