diff --git a/.github/workflows/sidecar.yml b/.github/workflows/sidecar.yml index 2bb13d6..8173f9d 100644 --- a/.github/workflows/sidecar.yml +++ b/.github/workflows/sidecar.yml @@ -17,6 +17,7 @@ jobs: "oneclient-sidecar/Dockerfile" "single-user-eiscat/Dockerfile" "webdav-sidecar/Dockerfile" + "webdav-rclone-sidecar/Dockerfile" sidecar-images: name: Build and push independent images diff --git a/webdav-rclone-sidecar/Dockerfile b/webdav-rclone-sidecar/Dockerfile new file mode 100644 index 0000000..a70ac3d --- /dev/null +++ b/webdav-rclone-sidecar/Dockerfile @@ -0,0 +1,23 @@ +FROM alpine:3.19 + +ENV MOUNT_PATH=/mnt +ENV WEBDAV_URL= +ENV WEBDAV_VENDOR=other +ENV JOVYAN_UID=1000 +ENV JOVYAN_GRP=100 + +RUN apk --no-cache add bash ca-certificates fuse3 rclone tini \ + && rclone config touch + +# to support unprivileged mounts +RUN sed -ie 's/#\s*\(user_allow_other\)/\1/' /etc/fuse.conf + +RUN adduser -u $JOVYAN_UID -g $JOVYAN_GRP -D jovyan + +USER jovyan +RUN rclone config touch +USER '' + +COPY mount.sh /usr/local/bin/ + +ENTRYPOINT [ "tini", "-g", "--", "mount.sh" ] diff --git a/webdav-rclone-sidecar/README.md b/webdav-rclone-sidecar/README.md new file mode 100644 index 0000000..58f8207 --- /dev/null +++ b/webdav-rclone-sidecar/README.md @@ -0,0 +1,28 @@ +# WebDAV Sidecar Image + +WebDAV sidecar image using rclone. + +## Usage + +Using environment: + +* WEBDAV\_URL: WebDAV endpoint +* WEBDAV\_USER: WebDAV user +* WEBDAV\_PWD: WebDAV password +* WEBDAV\_TOKEN: WebDAV OIDC token +* WEBDAV\_VENDOR: WebDAV vendor (default: *other*) +* MOUNT\_OPTS: space separated additional arguments for *rclone mount* command +* MOUNT\_PATH: mount path (default: */mnt*) +* VFS\_CACHE\_MODE: value for rclone VFS cache mode (off, minimal, writes, full) (default: *full*) + +Examples: + + docker run --privileged -it --rm --name oidcmount -v /tmp/webdav:/mnt:shared + -e WEBDAV_URL="$WEBDAV_URL" \ + -e WEBDAV_TOKEN="$(oidc-token my-issuer)" \ + webdav-rclone-sidecar" & + + echo "$(oidc-token my-issuer)" >/tmp/token + docker run --privileged -it --rm --name oidcmount -v /tmp/webdav:/mnt:shared -v /tmp/token:/tmp/token + -e WEBDAV_URL="$WEBDAV_URL" \ + webdav-rclone-sidecar bearer_token_command="cat /tmp/token" & diff --git a/webdav-rclone-sidecar/mount.sh b/webdav-rclone-sidecar/mount.sh new file mode 100755 index 0000000..b9d0532 --- /dev/null +++ b/webdav-rclone-sidecar/mount.sh @@ -0,0 +1,42 @@ +#! /usr/bin/env bash + +# Needs to be run as root! + +MOUNT_OPTS=${MOUNT_OPTS:-} +# where to mount +MOUNT_PATH=${MOUNT_PATH:-/mnt/} +JOVYAN_UID=${JOVYAN_UID:-1000} +JOVYAN_GRP=${JOVYAN_GRP:-100} +VFS_CACHE_MODE=${VFS_CACHE_MODE:-full} + +if [ ! -d "$MOUNT_PATH" ]; then + mkdir -p "$MOUNT_PATH" + chown "$JOVYAN_UID:$JOVYAN_GRP" "$MOUNT_PATH" +fi + +# wait to be killed +do_umount() { + fusermount3 -u -z "$MOUNT_PATH" + exit $? +} + +trap "do_umount" INT +trap "do_umount" TERM + +# Configure rclone client +args+=("url=$WEBDAV_URL") +args+=("vendor=$WEBDAV_VENDOR") +[ -n "$WEBDAV_USER" ] && args+=("user=$WEBDAV_USER") +[ -n "$WEBDAV_PWD" ] && args+=("pass=$WEBDAV_PWD") +[ -n "$WEBDAV_TOKEN" ] && args+=("bearer_token=$WEBDAV_TOKEN") +rclone config create --non-interactive webdav-fs webdav "${args[@]}" "$@" + +# Mount +# allow-non-empty: bind mounts +# allow-other: access from other unix accounts +# uid: unix owner +# gid: unix group +# vfs-cache-mode: random access and cache +IFS=" " read -r -a mount_opts <<<"$MOUNT_OPTS" +mount_opts+=("--vfs-cache-mode=$VFS_CACHE_MODE") +rclone mount webdav-fs:/ "$MOUNT_PATH" --allow-non-empty --allow-other --uid="$JOVYAN_UID" --gid="$JOVYAN_GRP" "${mount_opts[@]}"