add internal & external storage.

This commit is contained in:
Miroslav Šedivý
2021-05-22 00:45:09 +02:00
parent edba322ba0
commit e63c43e150
3 changed files with 57 additions and 24 deletions
+6 -3
View File
@@ -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
View File
@@ -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")
+14 -5
View File
@@ -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),