2025-07-22 13:16:53 +02:00
#!/bin/sh
oci = $( which podman || which docker)
2025-07-30 15:09:03 +02:00
test -n " $APPNAME " || APPNAME = xrforge
test -n " $UPLOAD_PATH " || UPLOAD_PATH = /mnt/models
2025-07-28 17:52:11 +02:00
db = /config/manyfold.sqlite3
# utility funcs
error( ) { echocolor "[error]" " $* " ; exit 1; }
echocolor( ) { printf "\033[96m%s\033[0m \033[95m%s\033[0m %s\n" " $1 " " $2 " " $3 " ; }
debug( ) { set -x; " $@ " ; set +x; }
2025-07-22 13:16:53 +02:00
create_config( ) {
test -d ./config || mkdir config
test -d ./experiences || mkdir experiences
}
run( ) {
test -x ${ oci } || { echo "warning: not running manyfold OCI container [install podman/docker/etc]" ; exit; }
2025-07-28 17:52:11 +02:00
echocolor " [ $APPNAME ] " " $( basename ${ oci } ) detected..starting OCI container "
${ oci } rm -f xrforge
2025-08-01 11:41:59 +02:00
#-e NO_OVERLAYFS=true \
#-e NO_DEFAULTDB=true \
#-e PUBLIC_HOSTNAME=localhost \
#-e PUBLIC_PORT=80 \
2025-07-28 17:52:11 +02:00
debug ${ oci } run " $@ " -p 8790:3214 --name xrforge \
2025-07-22 13:16:53 +02:00
-e SECRET_KEY_BASE = lkjwljlkwejrlkjek34k234l \
-e DATABASE_ADAPTER = sqlite3 \
-e SUDO_RUN_UNSAFELY = enabled \
-e MULTIUSER = enabled \
-e FEDERATION = enabled \
2025-07-28 17:52:11 +02:00
-e THEME = vapor \
--cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse \
2025-08-01 11:41:59 +02:00
xrforge
#ghcr.io/manyfold3d/manyfold-solo:latest
2025-07-28 17:52:11 +02:00
}
overlayfs( ) {
test -d /manyfold || return 0; # nothing to override
echocolor " [ $APPNAME ] " "applying filesystem overlay"
cd /manyfold
rsync -ravuzi * /.
}
db( ) {
default( ) {
test -f /manyfold/manyfold.sql && ! test -f /config/manyfold.sql && {
echocolor " [ $APPNAME ] " "copying default database"
test -d /config || mkdir /config
cat /manyfold/manyfold.sql | sqlite3 $db
}
}
dump( ) {
sqlite3 source.db ".dump" > /manyfold/manyfold.sql
}
import( ) {
sqlite3 $db < " $1 " #/manyfold/manyfold.sql
}
" $@ "
}
2025-07-30 15:09:03 +02:00
add_lib_to_db( ) {
name = $( basename $1 )
debug sqlite3 $db " INSERT INTO libraries SELECT NULL, ' $1 ', DATE('NOW'), DATE('NOW'), '', '', ' $name ', NULL, '', 'filesystem', '', '', '', '', '', ' $name ', 1 WHERE NOT EXISTS (SELECT 1 FROM libraries WHERE path = ' $1 '); "
}
set_upload_path( ) {
echocolor " [ $APPNAME ] " "configuring upload library"
test -d $UPLOAD_PATH || mkdir $UPLOAD_PATH
add_lib_to_db $UPLOAD_PATH
id = $( sqlite3 $db " select id from libraries where path = ' $UPLOAD_PATH '; " )
debug sqlite3 $db " UPDATE settings set value = $id where var = 'default_library'; "
}
2025-07-28 17:52:11 +02:00
rclone_mount( ) {
libraries( ) {
rclone listremotes | while read remote; do
dir = " ${ remote / : / } "
test -d /mnt/$dir || mkdir /mnt/$dir
echocolor " [ $APPNAME ] " " rclone: mounting $remote to /mnt/ $dir "
debug rclone mount --daemon $remote /mnt/$dir -vv
2025-07-30 15:09:03 +02:00
add_lib_to_db /mnt/$dir
2025-07-28 17:52:11 +02:00
done
}
library( ) {
2025-07-30 15:09:03 +02:00
echocolor " [ $APPNAME ] " " rclone: mounting $RCLONE_REMOTE to /mnt/ $RCLONE_REMOTE "
test -d /mnt/$RCLONE_REMOTE || mkdir /mnt/$RCLONE_REMOTE
debug rclone mount --daemon ${ RCLONE_REMOTE } : /mnt/$RCLONE_REMOTE -vv
add_lib_to_db /mnt/$RCLONE_REMOTE
2025-07-28 17:52:11 +02:00
}
test -n " $RCLONE_REMOTE " && library
test -n " $RCLONE_REMOTE " || libraries
2025-07-22 13:16:53 +02:00
}
2025-07-28 17:52:11 +02:00
set_theme( ) {
test -z " $THEME " && return 0 # nothing to do
echocolor " [ $APPNAME ] " " setting theme to ' $THEME ' "
debug sqlite3 /config/manyfold.sqlite3 "UPDATE settings SET value = '" $THEME "' WHERE var == 'theme';"
2025-07-22 13:16:53 +02:00
}
2025-07-28 18:02:11 +02:00
set_modelpath( ) {
echocolor " [ $APPNAME ] " "enforcing modelpath"
2025-07-31 11:30:07 +02:00
debug sqlite3 /config/manyfold.sqlite3 "UPDATE settings SET value = replace('--- \"{creator}/{modelName}/{modelId}\"\n','\n',char(10)) WHERE var == 'model_path_template';"
2025-07-28 18:02:11 +02:00
}
2025-07-28 17:52:11 +02:00
rename_app( ) {
echocolor " [ $APPNAME ] " " renaming manyfold to $APPNAME "
sed -i 's/title: Manyfold/title: ' $APPNAME '/g' /usr/src/app/config/locales/*.yml
2025-07-31 11:30:07 +02:00
sed -i 's|powered_by_html:.*|powered_by_html: Powered by <a href="https://forgejo.isvery.ninja/coderofsalvation/xrforge">XR Forge</a>, <a href="https://manifold.app" target="_blank">Manyfold</a>, <a href="https://xrfragment.org">XR Fragments</a> and <a href="https://nixos.org" target="_blank">NIX</a>|g' /usr/src/app/config/locales/*.yml
2025-07-28 17:52:11 +02:00
}
# The new entrypoint of the docker
boot( ) {
echocolor " [ $APPNAME ] " "booting..."
test -z " $NO_OVERLAYFS " && overlayfs
test -z " $NO_DEFAULTDB " && db default
rename_app
set_theme
2025-07-28 18:02:11 +02:00
set_modelpath
2025-07-28 17:52:11 +02:00
rclone_mount
2025-07-30 15:09:03 +02:00
set_upload_path
2025-07-28 17:52:11 +02:00
exec " $@ " # exec prevents error 's6-overlay-suexec: fatal: can only run as pid 1'
2025-07-22 13:16:53 +02:00
}
is_inside_container( ) {
test -d /package/admin && return 0 || return 1
}
usage( ) {
2025-07-28 17:52:11 +02:00
echocolor "Usage:" manyfold.sh "<cmd>"
echocolor "Cmds:"
echocolor " " "run [-d] " "# runs a OCI container (needs podman/docker)"
2025-07-22 13:16:53 +02:00
exit 0
}
2025-07-28 17:52:11 +02:00
test -n " $1 " && " $@ "
test -n " $1 " || usage