mirror of
https://github.com/YuzuZensai/Minikura.git
synced 2026-09-13 10:49:21 +00:00
✨ feat: add plugin registry and server operations
This commit is contained in:
@@ -60,13 +60,16 @@ type JVMOptions struct {
|
||||
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +kubebuilder:validation:Maximum=100
|
||||
// +kubebuilder:default=80
|
||||
// +kubebuilder:default=60
|
||||
HeapPercent int32 `json:"heapPercent,omitempty"`
|
||||
}
|
||||
|
||||
type MinecraftServerSpec struct {
|
||||
Type ServerKind `json:"type"`
|
||||
|
||||
// +kubebuilder:default=true
|
||||
Running *bool `json:"running,omitempty"`
|
||||
|
||||
// +optional
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
|
||||
@@ -132,6 +132,11 @@ func (in *MinecraftServerList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MinecraftServerSpec) DeepCopyInto(out *MinecraftServerSpec) {
|
||||
*out = *in
|
||||
if in.Running != nil {
|
||||
in, out := &in.Running, &out.Running
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
out.Resources = in.Resources
|
||||
out.JVM = in.JVM
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
controller-gen.kubebuilder.io/version: v0.21.0
|
||||
name: minecraftservers.minikura.kirameki.cafe
|
||||
spec:
|
||||
group: minikura.kirameki.cafe
|
||||
@@ -220,7 +220,7 @@ spec:
|
||||
jvm:
|
||||
properties:
|
||||
heapPercent:
|
||||
default: 80
|
||||
default: 60
|
||||
format: int32
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
@@ -300,6 +300,9 @@ spec:
|
||||
minimum: 256
|
||||
type: integer
|
||||
type: object
|
||||
running:
|
||||
default: true
|
||||
type: boolean
|
||||
serviceType:
|
||||
default: ClusterIP
|
||||
enum:
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
controller-gen.kubebuilder.io/version: v0.21.0
|
||||
name: reverseproxyservers.minikura.kirameki.cafe
|
||||
spec:
|
||||
group: minikura.kirameki.cafe
|
||||
|
||||
@@ -15,7 +15,7 @@ const (
|
||||
MinecraftImage = "itzg/minecraft-server"
|
||||
ProxyImage = "itzg/mc-proxy:latest"
|
||||
ContainerPort = 25565
|
||||
DefaultHeapPercent = 80
|
||||
DefaultHeapPercent = 60
|
||||
DefaultMemoryLimitMB = 2048
|
||||
MinHeapMB = 256
|
||||
)
|
||||
|
||||
@@ -16,12 +16,12 @@ func TestHeapMB(t *testing.T) {
|
||||
heapPercent int32
|
||||
want string
|
||||
}{
|
||||
{"default percent when unset", 2048, 0, "1638M"},
|
||||
{"default percent when unset", 2048, 0, "1228M"},
|
||||
{"explicit percent", 2048, 50, "1024M"},
|
||||
{"out of range falls back", 1024, 150, "819M"},
|
||||
{"out of range falls back", 1024, 150, "614M"},
|
||||
{"floor applies to tiny limits", 128, 80, "256M"},
|
||||
{"full allocation", 1000, 100, "1000M"},
|
||||
{"zero limit uses default memory", 0, 80, "1638M"},
|
||||
{"zero limit uses default memory", 0, 60, "1228M"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -113,8 +113,12 @@ func minecraftPodSpec(mc *v1alpha1.MinecraftServer, stateful bool) corev1.PodSpe
|
||||
|
||||
return corev1.PodSpec{
|
||||
Containers: []corev1.Container{{
|
||||
Name: "minecraft",
|
||||
Image: MinecraftImage,
|
||||
Name: "minecraft",
|
||||
Image: MinecraftImage,
|
||||
Command: []string{"/bin/sh", "-c"},
|
||||
Args: []string{
|
||||
"rm -f /tmp/minikura-console && mkfifo /tmp/minikura-console && exec 3<>/tmp/minikura-console && exec /start <&3",
|
||||
},
|
||||
Ports: []corev1.ContainerPort{{
|
||||
Name: "minecraft",
|
||||
ContainerPort: ContainerPort,
|
||||
@@ -132,10 +136,14 @@ func MinecraftDeployment(mc *v1alpha1.MinecraftServer) *appsv1.Deployment {
|
||||
name := ServerName(mc.Name)
|
||||
labels := ServerLabels(mc)
|
||||
|
||||
replicas := int32(1)
|
||||
if mc.Spec.Running != nil && !*mc.Spec.Running {
|
||||
replicas = 0
|
||||
}
|
||||
return &appsv1.Deployment{
|
||||
ObjectMeta: ObjectMeta(name, mc.Namespace, labels),
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: ptr(int32(1)),
|
||||
Replicas: ptr(replicas),
|
||||
Selector: &metav1.LabelSelector{MatchLabels: SelectorLabels(name)},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: labels},
|
||||
@@ -158,11 +166,15 @@ func MinecraftStatefulSet(mc *v1alpha1.MinecraftServer) (*appsv1.StatefulSet, er
|
||||
return nil, fmt.Errorf("invalid storageSize %q: %w", size, err)
|
||||
}
|
||||
|
||||
replicas := int32(1)
|
||||
if mc.Spec.Running != nil && !*mc.Spec.Running {
|
||||
replicas = 0
|
||||
}
|
||||
return &appsv1.StatefulSet{
|
||||
ObjectMeta: ObjectMeta(name, mc.Namespace, labels),
|
||||
Spec: appsv1.StatefulSetSpec{
|
||||
ServiceName: name,
|
||||
Replicas: ptr(int32(1)),
|
||||
Replicas: ptr(replicas),
|
||||
Selector: &metav1.LabelSelector{MatchLabels: SelectorLabels(name)},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: labels},
|
||||
|
||||
@@ -153,6 +153,37 @@ func TestStatelessHasNoDataVolume(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinecraftUsesPersistentConsolePipe(t *testing.T) {
|
||||
podSpec := minecraftPodSpec(testServer(), true)
|
||||
container := podSpec.Containers[0]
|
||||
|
||||
if len(container.Command) != 2 || container.Command[0] != "/bin/sh" {
|
||||
t.Fatalf("command = %v, want shell wrapper", container.Command)
|
||||
}
|
||||
if len(container.Args) != 1 || container.Args[0] != "rm -f /tmp/minikura-console && mkfifo /tmp/minikura-console && exec 3<>/tmp/minikura-console && exec /start <&3" {
|
||||
t.Fatalf("args = %v, want persistent console pipe", container.Args)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoppedServerHasZeroReplicas(t *testing.T) {
|
||||
mc := testServer()
|
||||
stopped := false
|
||||
mc.Spec.Running = &stopped
|
||||
|
||||
dep := MinecraftDeployment(mc)
|
||||
if dep.Spec.Replicas == nil || *dep.Spec.Replicas != 0 {
|
||||
t.Fatalf("deployment replicas = %v, want 0", dep.Spec.Replicas)
|
||||
}
|
||||
|
||||
sts, err := MinecraftStatefulSet(mc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if sts.Spec.Replicas == nil || *sts.Spec.Replicas != 0 {
|
||||
t.Fatalf("statefulset replicas = %v, want 0", sts.Spec.Replicas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinecraftConfigMap(t *testing.T) {
|
||||
cm := MinecraftConfigMap(testServer())
|
||||
if cm.Name != "minecraft-smp-config" {
|
||||
|
||||
Reference in New Issue
Block a user