mirror of
https://github.com/m1k1o/neko-rooms.git
synced 2026-11-03 07:01:35 -06:00
add internal & external storage.
This commit is contained in:
@@ -9,15 +9,18 @@ fi
|
||||
|
||||
export $(cat ../.env | sed 's/#.*//g' | xargs)
|
||||
|
||||
mkdir -p "./data"
|
||||
DATA_PATH="./data"
|
||||
mkdir -p "${DATA_PATH}"
|
||||
|
||||
docker run --rm -it \
|
||||
--name="neko_rooms_server" \
|
||||
-v "${PWD}/../:/app" \
|
||||
-v "`realpath ..`:/app" \
|
||||
-v "`realpath ${DATA_PATH}`:/data" \
|
||||
-e "TZ=${TZ}" \
|
||||
-e "NEKO_ROOMS_EPR=${NEKO_ROOMS_EPR}" \
|
||||
-e "NEKO_ROOMS_NAT1TO1=${NEKO_ROOMS_NAT1TO1}" \
|
||||
-e "NEKO_ROOMS_INSTANCE_DATA=`realpath ./data`" \
|
||||
-e "NEKO_ROOMS_STORAGE_INTERNAL=/data" \
|
||||
-e "NEKO_ROOMS_STORAGE_EXTERNAL=`realpath ${DATA_PATH}`" \
|
||||
-e "NEKO_ROOMS_TRAEFIK_DOMAIN=${NEKO_ROOMS_TRAEFIK_DOMAIN}" \
|
||||
-e "NEKO_ROOMS_TRAEFIK_ENTRYPOINT=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
|
||||
-e "NEKO_ROOMS_TRAEFIK_NETWORK=${NEKO_ROOMS_TRAEFIK_NETWORK}" \
|
||||
|
||||
+37
-16
@@ -18,9 +18,12 @@ type Room struct {
|
||||
NAT1To1IPs []string
|
||||
NekoImages []string
|
||||
|
||||
StorageEnabled bool
|
||||
StorageInternal string
|
||||
StorageExternal string
|
||||
|
||||
InstanceName string
|
||||
InstanceUrl string
|
||||
InstanceData string
|
||||
|
||||
TraefikDomain string
|
||||
TraefikEntrypoint string
|
||||
@@ -53,6 +56,23 @@ func (Room) Init(cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Data
|
||||
|
||||
cmd.PersistentFlags().Bool("storage.enabled", true, "whether storage is enabled, where peristent containers data will be stored")
|
||||
if err := viper.BindPFlag("storage.enabled", cmd.PersistentFlags().Lookup("storage.enabled")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("storage.external", "", "external absolute path (on the host) to storage folder")
|
||||
if err := viper.BindPFlag("storage.external", cmd.PersistentFlags().Lookup("storage.external")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("storage.internal", "/data", "internal absolute path (inside container) to storage folder")
|
||||
if err := viper.BindPFlag("storage.internal", cmd.PersistentFlags().Lookup("storage.internal")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Instance
|
||||
|
||||
cmd.PersistentFlags().String("instance.name", "neko-rooms", "unique instance name (if running muliple on the same host)")
|
||||
@@ -65,11 +85,6 @@ func (Room) Init(cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("instance.data", "", "absolute path on host to a folder, where peristent containers data will be stored")
|
||||
if err := viper.BindPFlag("instance.data", cmd.PersistentFlags().Lookup("instance.url")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Traefik
|
||||
|
||||
cmd.PersistentFlags().String("traefik.domain", "neko.lan", "traefik: domain on which will be container hosted")
|
||||
@@ -128,22 +143,28 @@ func (s *Room) Set() {
|
||||
s.NAT1To1IPs = viper.GetStringSlice("nat1to1")
|
||||
s.NekoImages = viper.GetStringSlice("neko_images")
|
||||
|
||||
s.StorageEnabled = viper.GetBool("storage.enabled")
|
||||
s.StorageInternal = viper.GetString("storage.internal")
|
||||
s.StorageExternal = viper.GetString("storage.external")
|
||||
|
||||
if s.StorageInternal != "" && s.StorageExternal != "" {
|
||||
s.StorageInternal = filepath.Clean(s.StorageInternal)
|
||||
s.StorageExternal = filepath.Clean(s.StorageExternal)
|
||||
|
||||
if !filepath.IsAbs(s.StorageInternal) || !filepath.IsAbs(s.StorageExternal) {
|
||||
log.Panic().Msg("invalid `storage.internal` or `storage.external`, must be an absolute path")
|
||||
}
|
||||
} else {
|
||||
log.Warn().Msg("missing `storage.internal` or `storage.external`, storage is unavailable")
|
||||
s.StorageEnabled = false
|
||||
}
|
||||
|
||||
s.InstanceName = viper.GetString("instance.name")
|
||||
if !dockerNames.RestrictedNamePattern.MatchString(s.InstanceName) {
|
||||
log.Panic().Msg("invalid `instance.name`, must match " + dockerNames.RestrictedNameChars)
|
||||
}
|
||||
|
||||
s.InstanceUrl = viper.GetString("instance.url")
|
||||
s.InstanceData = viper.GetString("instance.data")
|
||||
if s.InstanceData != "" {
|
||||
s.InstanceData = filepath.Clean(s.InstanceData)
|
||||
|
||||
if !filepath.IsAbs(s.InstanceData) {
|
||||
log.Panic().Msg("invalid `instance.data`, must be an absolute path")
|
||||
}
|
||||
} else {
|
||||
log.Warn().Msg("missing `instance.data`, container mounts are unavailable")
|
||||
}
|
||||
|
||||
s.TraefikDomain = viper.GetString("traefik.domain")
|
||||
s.TraefikEntrypoint = viper.GetString("traefik.entrypoint")
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -25,7 +26,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
frontendPort = 8080
|
||||
frontendPort = 8080
|
||||
roomStoragePath = "./rooms"
|
||||
)
|
||||
|
||||
func New(config *config.Room) *RoomManagerCtx {
|
||||
@@ -91,8 +93,8 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
||||
return "", fmt.Errorf("invalid container name, must match " + dockerNames.RestrictedNameChars)
|
||||
}
|
||||
|
||||
if manager.config.InstanceData == "" && len(settings.Mounts) > 0 {
|
||||
return "", fmt.Errorf("mounts cannot be specified, because `instance.data` config value is not set")
|
||||
if !manager.config.StorageEnabled && len(settings.Mounts) > 0 {
|
||||
return "", fmt.Errorf("mounts cannot be specified, because storage is disabled or unavailable")
|
||||
}
|
||||
|
||||
if in, _ := utils.ArrayIn(settings.NekoImage, manager.config.NekoImages); !in {
|
||||
@@ -198,10 +200,17 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
||||
return "", fmt.Errorf("mount paths must be absolute")
|
||||
}
|
||||
|
||||
externalPath := path.Join(manager.config.StorageExternal, roomStoragePath, roomName, hostPath)
|
||||
internalPath := path.Join(manager.config.StorageInternal, roomStoragePath, roomName, hostPath)
|
||||
|
||||
if err := os.MkdirAll(internalPath, os.ModePerm); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
mounts = append(mounts,
|
||||
dockerMount.Mount{
|
||||
Type: dockerMount.TypeBind,
|
||||
Source: path.Join(manager.config.InstanceData, roomName, hostPath),
|
||||
Source: externalPath,
|
||||
Target: containerPath,
|
||||
ReadOnly: false,
|
||||
Consistency: dockerMount.ConsistencyDefault,
|
||||
@@ -335,7 +344,7 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
|
||||
}
|
||||
|
||||
mounts := []types.RoomMount{}
|
||||
dataRoot := path.Join(manager.config.InstanceData, roomName)
|
||||
dataRoot := path.Join(manager.config.StorageExternal, roomStoragePath, roomName)
|
||||
for _, mount := range container.Mounts {
|
||||
mounts = append(mounts, types.RoomMount{
|
||||
HostPath: strings.TrimPrefix(mount.Source, dataRoot),
|
||||
|
||||
Reference in New Issue
Block a user