3 Commits

Author SHA1 Message Date
acoolname 54b6631fd0 feat(example): add factorio image example
Build and Push Docker Image / Build image (push) Successful in 1m50s
2026-06-28 22:06:12 +03:00
acoolname 04ad3616c9 chore(filebrowser): migrate from filebrowser to filebrowser quantum
Build and Push Docker Image / Build image (push) Successful in 9m10s
2026-06-28 19:22:35 +03:00
acoolname 7158764d2c fix(browser): change auth method to noauth
Build and Push Docker Image / Build image (push) Successful in 1m45s
2026-06-22 20:12:02 +00:00
3 changed files with 179 additions and 24 deletions
+24
View File
@@ -0,0 +1,24 @@
apiVersion: server-manager.acooldomain.co/v1alpha1
kind: Image
metadata:
labels:
app.kubernetes.io/name: kubernetes-operator
app.kubernetes.io/managed-by: kustomize
name: minecraft-paper-1-21-5
spec:
location: git.acooldomain.co/server-manager/minecraft:paper-1.21.5
name: minecraft
tag: paper-1.21.5
working_dir: /opt/server
ports:
- port: 25565
protocol: TCP
init_script:
image: alpine:latest
command:
- /bin/sh
args:
- /bin/sh
- "-c"
- "echo eula=true >> /data/eula.txt"
+66
View File
@@ -0,0 +1,66 @@
package controller
type SourceRule struct {
FolderPath string `yaml:"folderPath"`
Viewable bool `yaml:"viewable"`
}
type SourceConfig struct {
DefaultEnabled bool `yaml:"defaultEnabled"`
Rules []SourceRule `yaml:"rules"`
}
type SourceDefinition struct {
Path string `yaml:"path"`
Config SourceConfig `yaml:"config"`
}
type ServerConfig struct {
Port int `yaml:"port"`
BaseUrl string `yaml:"baseURL"`
Sources []SourceDefinition `yaml:"sources"`
}
type UserDefaultPermissionConfig struct {
Modify bool `yaml:"modify"`
Share bool `yaml:"share"`
Realtime bool `yaml:"realtime"`
Create bool `yaml:"create"`
Delete bool `yaml:"delete"`
Api bool `yaml:"api"`
}
type UserDefaultsConfig struct {
Permissions UserDefaultPermissionConfig `yaml:"permissions"`
}
type AuthPasswordMethodConfig struct {
Enabled bool `yaml:"enabled"`
MinLength int `yaml:"minLength"`
}
type AuthProxyMethodConfig struct {
Enabled bool `yaml:"enabled"`
Header string `yaml:"header"`
}
type AuthMethodsConfig struct {
Password AuthPasswordMethodConfig `yaml:"password"`
Proxy AuthProxyMethodConfig `yaml:"proxy"`
}
type AuthConfig struct {
AdminUsername string `yaml:"adminUsername"`
Methods AuthMethodsConfig `yaml:"methods"`
}
type FrontendConfig struct {
Name string `yaml:"name"`
}
type FileBrowserConfig struct {
Server ServerConfig `yaml:"server"`
Auth AuthConfig `yaml:"auth"`
Frontend FrontendConfig `yaml:"frontend"`
UserDefaults UserDefaultsConfig `yaml:"userDefaults"`
}
+89 -24
View File
@@ -23,6 +23,7 @@ import (
"time"
traefikv3 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
"gopkg.in/yaml.v3"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
@@ -297,7 +298,22 @@ func (r *ServerManagerReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}
logging.Info("verified server service")
browserPod := r.BrowserPod(s, pvc, browserPvc)
browserConfigMap, err := r.BrowserConfigMap(s)
if err != nil {
return ctrl.Result{}, err
}
logging.Info("created browser configmap")
var foundBrowserConfigMap corev1.ConfigMap
err = r.Get(ctx, client.ObjectKeyFromObject(browserConfigMap), &foundBrowserConfigMap)
if err != nil {
logging.Info("Failed getting browser configmap", "err", err)
err = r.Create(ctx, browserConfigMap)
return ctrl.Result{Requeue: true}, err
}
logging.Info("verified browser config map")
browserPod := r.BrowserPod(s, pvc, browserPvc, browserConfigMap)
foundBrowser := &corev1.Pod{}
err = r.Get(ctx, client.ObjectKeyFromObject(browserPod), foundBrowser)
if err == nil && !s.Spec.Browser.On {
@@ -519,15 +535,68 @@ func (r *ServerManagerReconciler) BrowserService(s *servermanagerv1alpha1.Server
return service
}
func (r *ServerManagerReconciler) BrowserPod(s *servermanagerv1alpha1.ServerManager, pvc *corev1.PersistentVolumeClaim, browserPvc *corev1.PersistentVolumeClaim) *corev1.Pod {
ports := make([]corev1.ContainerPort, len(s.Spec.Server.Ports))
func (r *ServerManagerReconciler) BrowserConfigMap(s *servermanagerv1alpha1.ServerManager) (*corev1.ConfigMap, error) {
serializedConfig, err := yaml.Marshal(FileBrowserConfig{
Server: ServerConfig{
Port: 80,
BaseUrl: r.GenerateBrowserSubPath(s),
Sources: []SourceDefinition{
{
Path: "/tmp/data",
Config: SourceConfig{
DefaultEnabled: true,
Rules: []SourceRule{
{
FolderPath: "lost+found",
Viewable: false,
},
},
},
},
},
},
Auth: AuthConfig{
AdminUsername: "admin",
Methods: AuthMethodsConfig{
Password: AuthPasswordMethodConfig{
Enabled: false,
},
Proxy: AuthProxyMethodConfig{
Enabled: true,
Header: r.Config.Browser.AuthHeader,
},
},
},
Frontend: FrontendConfig{
Name: "ACoolFileBrowser",
},
UserDefaults: UserDefaultsConfig{
Permissions: UserDefaultPermissionConfig{
Modify: true,
Create: true,
Delete: true,
Api: true,
Share: true,
Realtime: true,
},
},
})
for i, port := range s.Spec.Server.Ports {
ports[i] = corev1.ContainerPort{
ContainerPort: port.Port,
Protocol: port.Protocol,
}
if err != nil {
return nil, err
}
return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-browser-config", s.Name),
Namespace: s.Namespace,
Labels: map[string]string{"browser": s.Name},
},
Data: map[string]string{"config.yaml": string(serializedConfig)},
}, nil
}
func (r *ServerManagerReconciler) BrowserPod(s *servermanagerv1alpha1.ServerManager, pvc *corev1.PersistentVolumeClaim, browserPvc *corev1.PersistentVolumeClaim, browserConfigMap *corev1.ConfigMap) *corev1.Pod {
var fsGroupValue int64 = 2000
var runAsUserValue int64 = 1000
policy := corev1.FSGroupChangeOnRootMismatch // Optimizes startup speed
@@ -562,19 +631,12 @@ func (r *ServerManagerReconciler) BrowserPod(s *servermanagerv1alpha1.ServerMana
},
},
},
},
InitContainers: []corev1.Container{
{
Name: "proxy-setter",
Image: "filebrowser/filebrowser",
ImagePullPolicy: corev1.PullIfNotPresent,
Ports: ports,
Command: []string{"/bin/sh"},
Args: []string{"-c", fmt.Sprintf("rm /tmp/database/filebrowser.db; filebrowser config init -d /tmp/database/filebrowser.db && filebrowser config set --auth.method=proxy --auth.header=%s -d /tmp/database/filebrowser.db", r.Config.Browser.AuthHeader)},
VolumeMounts: []corev1.VolumeMount{
{
Name: "browser-volume",
MountPath: "/tmp/database",
{Name: "config-volume",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: browserConfigMap.Name,
},
},
},
},
@@ -582,10 +644,9 @@ func (r *ServerManagerReconciler) BrowserPod(s *servermanagerv1alpha1.ServerMana
Containers: []corev1.Container{
{
Name: "browser",
Image: "filebrowser/filebrowser",
Image: "ghcr.io/gtsteffaniak/filebrowser",
ImagePullPolicy: corev1.PullIfNotPresent,
Ports: ports,
Args: []string{"-d", "/tmp/database/filebrowser.db", "-r", "/tmp/data", "-b", r.GenerateBrowserSubPath(s)},
Args: []string{"-c", "/tmp/config/config.yaml"},
VolumeMounts: []corev1.VolumeMount{
{
Name: "volume",
@@ -595,6 +656,10 @@ func (r *ServerManagerReconciler) BrowserPod(s *servermanagerv1alpha1.ServerMana
Name: "browser-volume",
MountPath: "/tmp/database",
},
{
Name: "config-volume",
MountPath: "/tmp/config",
},
},
},
},