Skip to content

Commit

Permalink
Merge pull request #74 from hvalev/feature/update-params
Browse files Browse the repository at this point in the history
passing mergerfs parameters as env var or configuration file
  • Loading branch information
hvalev authored Jul 20, 2024
2 parents ce518a9 + 72c67f1 commit 409f072
Show file tree
Hide file tree
Showing 4 changed files with 349 additions and 5 deletions.
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ RUN echo user_allow_other >> /etc/fuse.conf

COPY entrypoint.sh entrypoint.sh

RUN mkdir /config
COPY parameters.conf /config/parameters.conf

RUN mkdir /disks && \
chmod +x entrypoint.sh

Expand Down
59 changes: 57 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,63 @@ services:
```
## Customizing
* If you would like to customize the mergerfs command with additional options, you can overwrite entrypoint.sh by mounting your own using an additional volume mount.
* If you would like to combine this with samba to share it over the network, you could also use a samba docker container.
* If you would like to customize the mergerfs command with additional options, you can overwrite `parameters.conf` with your own using an additional volume mount that maps onto `/config` inside the docker. You can use the one in the repo as a template.
* You can also override the default `mergerfs` parameters by using the `MERGERFS_PARAMS` environment variable as follows:
```yaml
services:
mergerfs:
image: hvalev/mergerfs:latest
container_name: mergerfs
environment:
MERGERFS_PARAMS: 'moveonenospc=true,dropcacheonclose=true,category.create=mfs,cache.files=partial'
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse:/dev/fuse
volumes:
- /mnt/nd1:/disks/nd1
- /mnt/nd2:/disks/nd2
- /mnt/nd3:/disks/nd3
- /mnt/merged:/merged:shared
restart: always
```
* If you would like to combine this with samba to share it over the network, you could also use a samba docker container. Below is an example with a sample user read-write and guest read-only access.
```yaml
services:
mergerfs:
image: hvalev/mergerfs:latest
container_name: mergerfs
environment:
MERGERFS_PARAMS: 'moveonenospc=true,dropcacheonclose=true,category.create=mfs,cache.files=partial'
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse:/dev/fuse
volumes:
- /mnt/hd1:/disks/hd1
- /mnt/hd2:/disks/hd2
- /mnt/hd3:/disks/hd3
- /mnt/hd:/merged:shared
restart: always
samba:
image: elswork/samba:3.2.8
container_name: samba
environment:
TZ: 'Europe/Amsterdam'
ports:
- 139:139
- 445:445
volumes:
- /mnt/hd:/mnt/hd
command: '-u "1000:1000:user:user:user_password"
-u "1000:1000:guest:guest:guest_password"
-s "hd:/mnt/hd:rw:user"
-s "media:/mnt/hd:ro:guest"'
restart: unless-stopped
depends_on:
- mergerfs
```

## Acknowledgements
The following resources have been extremely helpful:
Expand Down
53 changes: 50 additions & 3 deletions entrypoint.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,16 +1,63 @@
#!/bin/sh

function cleanup {
# Function to clean up on script exit
cleanup() {
echo "Unmounting mergerfs..."
umount /merged
echo "Unmounted mergerfs."
}

mergerfs -o allow_other,use_ino,cache.files=partial,dropcacheonclose=true,moveonenospc=true,category.create=mfs /disks/*: /merged
# Set debugging options
# set -e # Exit immediately if a command exits with a non-zero status
# set -x # Print commands and their arguments as they are executed

# Define the default parameters file
PARAMETERS_FILE="/config/parameters.conf"

log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}

# Determine source of parameters
if [ -n "$MERGERFS_PARAMS" ]; then
log "Using parameters from MERGERFS_PARAMS environment variable."
PARAMS="$MERGERFS_PARAMS"
else
if [ ! -f "$PARAMETERS_FILE" ]; then
log "Error: /config/parameters.conf not found and MERGERFS_PARAMS is not set."
exit 1
fi

# Merge parameters from the file into a single line without comments or empty lines
PARAMS=$(grep -v '^\s*#' "$PARAMETERS_FILE" | sed '/^\s*$/d' | sed 's/^[ \t]*//;s/[ \t]*$//' | paste -sd ',' -)

if [ -z "$PARAMS" ]; then
log "Error: No valid parameters found in $PARAMETERS_FILE."
exit 1
else
log "Collecting parameters from configuration file found at /config/parameters.conf"
fi
fi


# Prepare the mergerfs command
COMMAND="mergerfs -o $PARAMS /disks/*: /merged"

# Print the command being executed
echo "Executing: $COMMAND"

# Mount using mergerfs
$COMMAND

# Trap SIGTERM signal of docker daemon
trap cleanup SIGTERM

# Trap exit signals to ensure cleanup
trap cleanup EXIT INT

# Wait for mergerfs process to finish
while [[ $(ps -eo 'comm' | grep mergerfs -c) -gt 0 ]]; do
sleep 1
done

echo mergerfs terminated
echo "mergerfs terminated"
239 changes: 239 additions & 0 deletions parameters.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
# moveonenospc: When enabled, if a write fails with ENOSPC (no space left on device) or EDQUOT (disk quota exceeded),
# the policy selected will run to find a new location for the file.
# An attempt to move the file to that branch will occur (keeping all metadata possible) and if successful,
# the original is unlinked and the write retried.
# Default: false
moveonenospc=true

# dropcacheonclose: When a file is requested to be closed, call posix_fadvise on it first to instruct the kernel
# that we no longer need the data and it can drop its cache.
# Recommended when cache.files=partial|full|auto-full|per-process to limit double caching.
# Default: false
dropcacheonclose=true

# category.create: Sets policy of all FUSE functions in the create category.
# Default: epmfs - Uses "most free space" policy for creating files
# Available values: epmfs, eplfs, ff, lfs, newest, mfs, rand, all
category.create=mfs

# cache.files: File page caching mode.
# Default: libfuse - Enables partial file caching
# Available values: libfuse, off, partial, full, auto-full, per-process
cache.files=partial

# lazy-umount-mountpoint: mergerfs will attempt to "lazy umount" the mountpoint before mounting itself.
# Useful when performing live upgrades of mergerfs.
# Default: false
# lazy-umount-mountpoint=true

# minfreespace: Minimum space value used for creation policies.
# Default: 4G
# Available values: any size (e.g., 1K, 10M, 5G)
# minfreespace=4G

# inodecalc: Selects the inode calculation algorithm.
# Default: hybrid-hash
# Available values: passthrough, path-hash, devino-hash, hybrid-hash
# inodecalc=hybrid-hash

# symlinkify: When enabled and a file is not writable and its mtime or ctime is older than symlinkify_timeout,
# files will be reported as symlinks to the original files.
# Default: false
# Available values: true, false
# symlinkify=false

# nullrw: Turns reads and writes into no-ops. Useful for benchmarking mergerfs.
# Default: false
# Available values: true, false
# nullrw=false

# ignorepponrename: Ignore path preserving on rename.
# Typically rename and link act differently depending on the policy of create.
# Default: false
# Available values: true, false
# ignorepponrename=false

# export-support: Sets a low-level FUSE feature intended to indicate the filesystem can support being exported via NFS.
# Default: true
# Available values: true, false
# export-support=true

# security_capability: If false, return ENOATTR when xattr security.capability is queried.
# Default: true
# Available values: true, false
# security_capability=true

# xattr: Runtime control of xattrs.
# Default: passthrough
# Available values: passthrough, noattr, nosys
# xattr=passthrough

# link_cow: When enabled, if a regular file is opened which has a link count > 1,
# it will copy the file to a temporary file and rename over the original.
# Breaking the link and providing a basic copy-on-write function similar to cow-shell.
# Default: false
# Available values: true, false
# link_cow=false

# statfs: Controls how statfs works.
# Default: base
# Available values: base, full
# statfs=base

# statfs_ignore: Controls how statfs calculations ignore certain branches.
# Default: none
# Available values: none, ro, nc
# statfs_ignore=none

# nfsopenhack: A workaround for exporting mergerfs over NFS.
# Default: off
# Available values: off, git, all
# nfsopenhack=off

# branches-mount-timeout: Number of seconds to wait at startup for branches to be a mount other than the mountpoint's filesystem.
# Default: 0
# Available values: any integer value
# branches-mount-timeout=0

# follow-symlinks: Turns symlinks into what they point to.
# Default: never
# Available values: never, directory, regular, all
# follow-symlinks=never

# link-exdev: When a link fails with EXDEV, optionally create a symlink to the file instead.
# Default: passthrough
# Available values: passthrough, rel-symlink, abs-base-symlink, abs-pool-symlink
# link-exdev=passthrough

# rename-exdev: When a rename fails with EXDEV, optionally move the file to a special directory and symlink to it.
# Default: passthrough
# Available values: passthrough, rel-symlink, abs-symlink
# rename-exdev=passthrough

# readahead: Set readahead (in kilobytes) for mergerfs and branches if greater than 0.
# Default: 0
# Available values: any integer value
# readahead=0

# posix_acl: Enable POSIX ACL support (if supported by kernel and underlying filesystem).
# Default: false
# Available values: true, false
# posix_acl=false

# async_read: Perform reads asynchronously.
# Default: true
# Available values: true, false
# async_read=true

# fuse_msg_size: Set the max number of pages per FUSE message.
# Default: 256
# Available values: 1 to 256
# fuse_msg_size=256

# threads: Number of threads to use.
# When used alone (process-thread-count=-1), it sets the number of threads reading and processing FUSE messages.
# When used together, it sets the number of threads reading from FUSE.
# Default: 0
# Available values: any integer value
# threads=0

# process-thread-count: Enables a separate thread pool to asynchronously process FUSE requests.
# In this mode, read-thread-count refers to the number of threads reading FUSE messages which are dispatched to process threads.
# Default: -1
# Available values: -1 to any integer value
# process-thread-count=-1

# process-thread-queue-depth: Sets the number of requests any single process thread can have queued up at one time.
# Default: 0
# Available values: any integer value
# process-thread-queue-depth=0

# pin-threads: Selects a strategy to pin threads to CPUs.
# Default: unset
# Available values: any valid strategy string
# pin-threads=

# flush-on-close: Flush data cache on file close.
# Mostly for when writeback is enabled or merging network filesystems.
# Default: opened-for-write
# Available values: never, always, opened-for-write
# flush-on-close=opened-for-write

# scheduling-priority: Set mergerfs' scheduling priority.
# Valid values range from -20 to 19. See setpriority man page for more details.
# Default: -10
# Available values: -20 to 19
# scheduling-priority=-10

# fsname: Sets the name of the filesystem as seen in mount, df, etc.
# Default: dynamically generated
# Available values: any string
# fsname=mergerfs

# category.action: Sets policy of all FUSE functions in the action category.
# Default: epall
# Available values: epall, all
# category.action=epall

# category.search: Sets policy of all FUSE functions in the search category.
# Default: ff
# Available values: ff, lfs, newest, rand, all
# category.search=ff

# cache.open: 'open' policy cache timeout in seconds.
# Default: 0
# Available values: any integer value
# cache.open=0

# cache.statfs: 'statfs' cache timeout in seconds.
# Default: 0
# Available values: any integer value
# cache.statfs=0

# cache.attr: File attribute cache timeout in seconds.
# Default: 1
# Available values: any integer value
# cache.attr=1

# cache.entry: File name lookup cache timeout in seconds.
# Default: 1
# Available values: any integer value
# cache.entry=1

# cache.negative_entry: Negative file name lookup cache timeout in seconds.
# Default: 0
# Available values: any integer value
# cache.negative_entry=0

# cache.writeback: Enable kernel writeback caching.
# Default: false
# Available values: true, false
# cache.writeback=false

# cache.symlinks: Cache symlinks (if supported by kernel).
# Default: false
# Available values: true, false
# cache.symlinks=false

# cache.readdir: Cache readdir (if supported by kernel).
# Default: false
# Available values: true, false
# cache.readdir=false

# parallel-direct-writes: Allow the kernel to dispatch multiple, parallel (non-extending) write requests for files
# opened with cache.files=per-process (if the process is not in process-names) or cache.files=off.
# Default: false
# Available values: true, false
# parallel-direct-writes=false

# Deprecated options (for reference only)
# direct_io=false # Default: false - Bypass page cache. Use cache.files=off instead.
# kernel_cache=false # Default: false - Do not invalidate data cache on file open. Use cache.files=full instead.
# auto_cache=false # Default: false - Invalidate data cache if file mtime or size change. Use cache.files=auto-full instead.
# async_read=true # Default: true - Perform reads asynchronously. Use async_read=true instead.
# sync_read=false # Default: false - Perform reads synchronously. Use async_read=false instead.
# splice_read=false # Default: false - Does nothing.
# splice_write=false # Default: false - Does nothing.
# splice_move=false # Default: false - Does nothing.
# allow_other=true # Default: true if running as root - mergerfs v2.35.0 and newer sets this FUSE option automatically if running as root.
# use_ino=true # Default: true - mergerfs should always control inode calculation so this is enabled all the time.

0 comments on commit 409f072

Please sign in to comment.