diff --git a/docs/configuration.rst b/docs/configuration.rst
index e076547..12641d6 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -1,48 +1,59 @@
.. _swh-fuse-config:
+
Configuration
=============
-All configuration for the Software Heritage virtual file system should be done
-in a single `.yml` file, containing the following fields:
+The configuration for the Software Heritage virtual file system resides in the
+``swh > fuse`` section of the shared `YAML `_ configuration
+file used by all Software Heritage tools, located by default at
+``~/.config/swh/global.yml``.
+
+The configuration file location is subject to the `XDG Base Directory
+`_ specification as
+well as explicitly overridden on the :ref:`command line ` via the
+``-C/--config-file`` flag.
-- `cache`:
+The following sub-sections and fields can be used within the `swh > fuse`
+stanza:
- - `metadata`: where to store the metadata cache, must have either a
- `in-memory` boolean entry or a `path` string entry (with the corresponding
- disk path)
- - `blob`: where to store the blob cache, same entries as the `metadata` cache
+- ``cache``:
-- `web-api`:
+ - ``metadata``: where to store the metadata cache, must have either a
+ ``in-memory`` boolean entry or a ``path`` string entry (with the
+ corresponding disk path)
+ - ``blob``: where to store the blob cache, same entries as the ``metadata``
+ cache
- - `url`: archive API URL
- - `auth-token`: authentication token used with the API URL
+- ``web-api``:
-Set the `-C/--config-file` option of the :ref:`CLI ` to use your
-configuration file.
+ - ``url``: archive API URL
+ - ``auth-token``: authentication token used with the API URL
If no configuration is given, default values are:
-- `cache`: all cache files are stored in `$XDG_CACHE_HOME/swh/fuse/` (or
- `$HOME/.cache/swh/fuse` if `XDG_CACHE_HOME` is not set)
-- `web-api`: default URL is https://archive.softwareheritage.org/api/1/ (with no
- authentication token)
+- ``cache``: all cache files are stored in ``$XDG_CACHE_HOME/swh/fuse/`` (or
+ ``~/.cache/swh/fuse`` if ``XDG_CACHE_HOME`` is not set)
+- ``web-api``: default URL is ,
+ with no authentication token
Example
-------
-Here is a complete example showcasing different cache storage strategies
-(in-memory for metadata and on-disk for blob), using the default Web API
-service:
+Here is a full ``~/.config/swh/global.yml`` example, showcasing different cache
+storage strategies (in-memory for metadata and on-disk for blob), using the
+default Web API service:
.. code:: yaml
- cache:
- metadata:
- in-memory: true
- blob:
- path: "/path/to/cache/blob.sqlite"
- web-api:
- url: "https://archive.softwareheritage.org/api/1/"
- auth-token: null
+ swh:
+ fuse:
+ cache:
+ metadata:
+ in-memory: true
+ blob:
+ path: "/path/to/cache/blob.sqlite"
+ web-api:
+ url: "https://archive.softwareheritage.org/api/1/"
+ auth-token: null
diff --git a/docs/index.rst b/docs/index.rst
index a266a73..c858cb8 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,12 +1,13 @@
.. _swh-fuse:
.. include:: README.rst
.. toctree::
:maxdepth: 1
:caption: Overview
cli
+ configuration
Design notes
- /apidoc/swh.fuse
+ API reference
diff --git a/swh/fuse/cli.py b/swh/fuse/cli.py
index 336c9fd..c3105e6 100644
--- a/swh/fuse/cli.py
+++ b/swh/fuse/cli.py
@@ -1,112 +1,112 @@
# Copyright (C) 2020 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import asyncio
from contextlib import ExitStack
import os
# WARNING: do not import unnecessary things here to keep cli startup time under
# control
from pathlib import Path
from typing import Any, Dict
import click
from daemon import DaemonContext
from swh.core import config
from swh.core.cli import CONTEXT_SETTINGS
from swh.core.cli import swh as swh_cli_group
from swh.model.cli import SWHIDParamType
# All generic config code should reside in swh.core.config
DEFAULT_CONFIG_PATH = os.environ.get(
"SWH_CONFIG_FILE", os.path.join(click.get_app_dir("swh"), "global.yml")
)
CACHE_HOME_DIR: Path = (
Path(os.environ["XDG_CACHE_HOME"])
if "XDG_CACHE_HOME" in os.environ
else Path.home() / ".cache"
)
DEFAULT_CONFIG: Dict[str, Any] = {
"cache": {
"metadata": {"path": CACHE_HOME_DIR / "swh/fuse/metadata.sqlite"},
"blob": {"path": CACHE_HOME_DIR / "swh/fuse/blob.sqlite"},
},
"web-api": {
"url": "https://archive.softwareheritage.org/api/1",
"auth-token": None,
},
}
@swh_cli_group.group(name="fuse", context_settings=CONTEXT_SETTINGS)
@click.option(
"-C",
"--config-file",
default=None,
type=click.Path(exists=True, dir_okay=False, path_type=str),
- help="YAML configuration file",
+ help=f"Configuration file (default: {DEFAULT_CONFIG_PATH})",
)
@click.pass_context
def fuse(ctx, config_file):
"""Software Heritage virtual file system"""
if not config_file and config.config_exists(DEFAULT_CONFIG_PATH):
config_file = DEFAULT_CONFIG_PATH
if not config_file:
conf = DEFAULT_CONFIG
else:
# recursive merge not done by config.read
conf = config.read_raw_config(config.config_basepath(config_file))
conf = config.merge_configs(DEFAULT_CONFIG, conf)
ctx.ensure_object(dict)
ctx.obj["config"] = conf
@fuse.command(name="mount")
@click.argument(
"path",
required=True,
metavar="PATH",
type=click.Path(exists=True, dir_okay=True, file_okay=False),
)
@click.argument("swhids", nargs=-1, metavar="[SWHID]...", type=SWHIDParamType())
@click.option(
"-f/-d",
"--foreground/--daemon",
default=False,
help="whether to run FUSE attached to the console (foreground) "
"or daemonized in the background (default: daemon)",
)
@click.pass_context
def mount(ctx, swhids, path, foreground):
"""Mount the Software Heritage archive at PATH
If specified, objects referenced by the given SWHIDs will be prefetched and used to
populate the virtual file system (VFS). Otherwise the VFS will be populated
on-demand, when accessing its content.
\b
Example:
\b
$ mkdir swhfs
$ swh fuse mount swhfs/
$ grep printf swhfs/archive/swh:1:cnt:c839dea9e8e6f0528b468214348fee8669b305b2
printf("Hello, World!");
$
"""
from swh.fuse import fuse
with ExitStack() as stack:
if not foreground:
stack.enter_context(DaemonContext())
asyncio.run(fuse.main(swhids, path, ctx.obj["config"]))