feat(deploy): add one-line bootstrap installer and container image
bootstrap.sh auto-detects the host package manager (apt/dnf) and installs whatever is missing: Docker, k3s, and PostgreSQL. It builds and imports the felis image, opens pg_hba to the pod CIDR, runs migrations, and applies the rendered control-plane bundle, leaving Web disabled pending 'felis setup'. The Dockerfile builds the distroless felis image; deploy/crd holds the MinecraftServer CRD.
This commit is contained in:
4 files changed
+869
No files matched your search
@@ -0,0 +1,391 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: minecraftservers.felis.lolicon.best
|
||||
spec:
|
||||
group: felis.lolicon.best
|
||||
names:
|
||||
kind: MinecraftServer
|
||||
listKind: MinecraftServerList
|
||||
plural: minecraftservers
|
||||
singular: minecraftserver
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
MinecraftServer is the lifecycle source-of-truth for a single managed
|
||||
Minecraft server (spec §4). The operator reconciles the StatefulSet, Service
|
||||
and PVC from this object; readiness is gated exclusively on an RCON probe.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: MinecraftServerSpec is the desired state (spec §4 spec.*).
|
||||
properties:
|
||||
args:
|
||||
description: Args are extra arguments appended after the jar.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
autostartPolicy:
|
||||
description: AutostartPolicy controls who may wake the server (spec
|
||||
§8).
|
||||
enum:
|
||||
- public
|
||||
- allowlist
|
||||
- ownerOnly
|
||||
type: string
|
||||
description:
|
||||
description: Description is free-form operator/owner notes.
|
||||
type: string
|
||||
desiredState:
|
||||
description: DesiredState toggles the server up or down (default Stopped).
|
||||
enum:
|
||||
- Running
|
||||
- Stopped
|
||||
type: string
|
||||
displayName:
|
||||
description: DisplayName is the human-facing name shown in the panel
|
||||
and MOTD.
|
||||
type: string
|
||||
env:
|
||||
description: Env are extra environment variables injected into the
|
||||
server container.
|
||||
items:
|
||||
description: |-
|
||||
EnvVar is a name/value pair injected into the server container. It is a
|
||||
deliberately narrow subset of corev1.EnvVar (no valueFrom) so the CRD cannot
|
||||
be used to exfiltrate arbitrary cluster secrets.
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
fallbackServer:
|
||||
description: |-
|
||||
FallbackServer is the Velocity server name traffic routes to while this
|
||||
server is stopped or starting.
|
||||
type: string
|
||||
idle:
|
||||
description: Idle configures empty-server auto-stop (spec §8).
|
||||
properties:
|
||||
autoStopEnabled:
|
||||
description: AutoStopEnabled turns on idle auto-stop.
|
||||
type: boolean
|
||||
emptySecondsBeforeStop:
|
||||
description: |-
|
||||
EmptySecondsBeforeStop is how long the server may sit empty before the
|
||||
operator scales it down.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
image:
|
||||
description: Image is the fully-qualified container image (loader-agnostic).
|
||||
type: string
|
||||
jar:
|
||||
description: |-
|
||||
Jar is the server jar path/name inside the image, if the entrypoint
|
||||
needs it explicitly.
|
||||
type: string
|
||||
javaFlags:
|
||||
description: JavaFlags are additional JVM flags (e.g. Aikar's flags).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
javaMemory:
|
||||
description: JavaMemory is the heap sizing passed as -Xmx/-Xms (e.g.
|
||||
"4G").
|
||||
type: string
|
||||
lifecycle:
|
||||
description: Lifecycle tunes graceful shutdown (spec §7).
|
||||
properties:
|
||||
preStopSaveAndStop:
|
||||
description: PreStopSaveAndStop enables the operator-injected
|
||||
RCON save+stop preStop.
|
||||
type: boolean
|
||||
terminationGracePeriodSeconds:
|
||||
description: TerminationGracePeriodSeconds is the pod grace period
|
||||
(default 300).
|
||||
format: int64
|
||||
type: integer
|
||||
type: object
|
||||
motd:
|
||||
description: Motd holds the per-phase MOTD strings surfaced to status
|
||||
pings.
|
||||
properties:
|
||||
failed:
|
||||
type: string
|
||||
running:
|
||||
type: string
|
||||
starting:
|
||||
type: string
|
||||
stopped:
|
||||
type: string
|
||||
type: object
|
||||
onlineMode:
|
||||
description: |-
|
||||
OnlineMode mirrors server.properties online-mode. Wake/claim semantics
|
||||
only hold when the Velocity proxy enforces online-mode=true (spec §8).
|
||||
type: boolean
|
||||
rcon:
|
||||
description: |-
|
||||
Rcon configures the RCON endpoint the operator probes for readiness and
|
||||
uses for graceful shutdown (spec §5, §7).
|
||||
properties:
|
||||
enabled:
|
||||
description: Enabled must be true for readiness probing and graceful
|
||||
shutdown.
|
||||
type: boolean
|
||||
port:
|
||||
description: Port is the RCON TCP port (default 25575).
|
||||
format: int32
|
||||
type: integer
|
||||
secretRef:
|
||||
description: SecretRef points at the Secret holding the RCON password.
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
reaperExempt:
|
||||
description: ReaperExempt opts this server out of the world reaper
|
||||
entirely (spec §18).
|
||||
type: boolean
|
||||
resources:
|
||||
description: Resources are the container resource requests/limits.
|
||||
properties:
|
||||
claims:
|
||||
description: |-
|
||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||
that are used by this container.
|
||||
|
||||
This is an alpha field and requires enabling the
|
||||
DynamicResourceAllocation feature gate.
|
||||
|
||||
This field is immutable. It can only be set for containers.
|
||||
items:
|
||||
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
|
||||
properties:
|
||||
name:
|
||||
description: |-
|
||||
Name must match the name of one entry in pod.spec.resourceClaims of
|
||||
the Pod where this field is used. It makes that resource available
|
||||
inside a container.
|
||||
type: string
|
||||
request:
|
||||
description: |-
|
||||
Request is the name chosen for a request in the referenced claim.
|
||||
If empty, everything from the claim is made available, otherwise
|
||||
only the result of this request.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- name
|
||||
x-kubernetes-list-type: map
|
||||
limits:
|
||||
additionalProperties:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: |-
|
||||
Limits describes the maximum amount of compute resources allowed.
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: |-
|
||||
Requests describes the minimum amount of compute resources required.
|
||||
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
|
||||
otherwise to an implementation-defined value. Requests cannot exceed Limits.
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
type: object
|
||||
startup:
|
||||
description: Startup bounds how long Starting may last before Failed
|
||||
(spec §5).
|
||||
properties:
|
||||
readinessTimeoutSeconds:
|
||||
description: ReadinessTimeoutSeconds is the budget for the first
|
||||
successful RCON probe.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: TimeoutSeconds is the overall budget before the server
|
||||
is marked Failed.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
storage:
|
||||
description: Storage configures the world PVC.
|
||||
properties:
|
||||
retainOnDelete:
|
||||
description: RetainOnDelete keeps the PVC when the MinecraftServer
|
||||
is deleted.
|
||||
type: boolean
|
||||
size:
|
||||
description: Size is the requested PVC capacity (e.g. "10Gi").
|
||||
type: string
|
||||
storageClassName:
|
||||
description: StorageClassName selects the StorageClass; empty
|
||||
uses the default.
|
||||
type: string
|
||||
type: object
|
||||
subdomain:
|
||||
description: |-
|
||||
Subdomain is the per-server label under the deployment zone. It is the
|
||||
only routing identity; the operator never hardcodes the parent domain.
|
||||
type: string
|
||||
required:
|
||||
- image
|
||||
- subdomain
|
||||
type: object
|
||||
status:
|
||||
description: MinecraftServerStatus is the observed state (spec §4 status.*).
|
||||
properties:
|
||||
conditions:
|
||||
description: Conditions are the standard metav1 conditions (Ready,
|
||||
RconReached, ...).
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
endpoint:
|
||||
description: Endpoint is where the proxy should route traffic.
|
||||
properties:
|
||||
address:
|
||||
description: Address is the host:port the proxy should dial.
|
||||
type: string
|
||||
mode:
|
||||
description: Mode is "direct" or "fallback".
|
||||
type: string
|
||||
type: object
|
||||
liveMotd:
|
||||
description: LiveMotd is the MOTD currently advertised for the active
|
||||
phase.
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: ObservedGeneration is the spec generation this status
|
||||
reflects.
|
||||
format: int64
|
||||
type: integer
|
||||
phase:
|
||||
description: Phase is the coarse lifecycle phase.
|
||||
type: string
|
||||
players:
|
||||
description: Players is the last observed player count.
|
||||
properties:
|
||||
max:
|
||||
format: int32
|
||||
type: integer
|
||||
online:
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- max
|
||||
- online
|
||||
type: object
|
||||
ready:
|
||||
description: |-
|
||||
Ready is true only after a successful RCON probe (loader-agnostic; a
|
||||
status ping is never sufficient — spec §5).
|
||||
type: boolean
|
||||
readySignalAt:
|
||||
description: ReadySignalAt is when the first RCON probe succeeded.
|
||||
format: date-time
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
Reference in new issue
Block a user