working with images
This commit is contained in:
parent
f464e8966d
commit
b021c161ca
@ -23,11 +23,23 @@ import (
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
type InitScript struct {
|
||||
Image string `json:"image"`
|
||||
Command []string `json:"command"`
|
||||
Args []string `json:"args"`
|
||||
}
|
||||
|
||||
// ImageSpec defines the desired state of Image
|
||||
type ImageSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
Location string `json:"location"`
|
||||
Name string `json:"name"`
|
||||
Location string `json:"location"`
|
||||
WorkingDir string `json:"working_dir"`
|
||||
Command []string `json:"command,omitempty"`
|
||||
Ports []Port `json:"ports"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
InitScript *InitScript `json:"init_script,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
@ -59,7 +59,7 @@ func (in *Image) DeepCopyInto(out *Image) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image.
|
||||
@ -115,6 +115,26 @@ func (in *ImageList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageSpec) DeepCopyInto(out *ImageSpec) {
|
||||
*out = *in
|
||||
if in.Command != nil {
|
||||
in, out := &in.Command, &out.Command
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Ports != nil {
|
||||
in, out := &in.Ports, &out.Ports
|
||||
*out = make([]Port, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Args != nil {
|
||||
in, out := &in.Args, &out.Args
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.InitScript != nil {
|
||||
in, out := &in.InitScript, &out.InitScript
|
||||
*out = new(InitScript)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageSpec.
|
||||
@ -127,6 +147,31 @@ func (in *ImageSpec) DeepCopy() *ImageSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InitScript) DeepCopyInto(out *InitScript) {
|
||||
*out = *in
|
||||
if in.Command != nil {
|
||||
in, out := &in.Command, &out.Command
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Args != nil {
|
||||
in, out := &in.Args, &out.Args
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InitScript.
|
||||
func (in *InitScript) DeepCopy() *InitScript {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InitScript)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Port) DeepCopyInto(out *Port) {
|
||||
*out = *in
|
||||
|
@ -39,13 +39,57 @@ spec:
|
||||
spec:
|
||||
description: ImageSpec defines the desired state of Image
|
||||
properties:
|
||||
args:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
command:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
init_script:
|
||||
properties:
|
||||
args:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
command:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
image:
|
||||
type: string
|
||||
required:
|
||||
- args
|
||||
- command
|
||||
- image
|
||||
type: object
|
||||
location:
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
type: string
|
||||
ports:
|
||||
items:
|
||||
properties:
|
||||
port:
|
||||
format: int32
|
||||
type: integer
|
||||
protocol:
|
||||
description: Protocol defines network protocols supported for
|
||||
things like container ports.
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
working_dir:
|
||||
type: string
|
||||
required:
|
||||
- location
|
||||
- name
|
||||
- ports
|
||||
- working_dir
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
|
@ -19,6 +19,7 @@ rules:
|
||||
- pods
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
|
@ -4,6 +4,20 @@ metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: kubernetes-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: image-sample
|
||||
name: minecraft-paper-1-21-4
|
||||
spec:
|
||||
# TODO(user): Add fields here
|
||||
location: git.acooldomain.co/server-manager/minecraft:paper-1.21.4
|
||||
name: minecraft:paper-1.21.4
|
||||
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"
|
||||
|
@ -11,8 +11,7 @@ spec:
|
||||
"on": true
|
||||
server:
|
||||
"on": true
|
||||
image: git.acooldomain.co/server-manager/minecraft:paper-1.21.4
|
||||
working_dir: /opt/server
|
||||
image: minecraft-paper-1-21-4
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 25565
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
servermanagerv1alpha1 "git.acooldomain.co/server-manager/kubernetes-operator/api/v1alpha1"
|
||||
)
|
||||
@ -95,7 +96,7 @@ type ServerManagerReconciler struct {
|
||||
// +kubebuilder:rbac:groups=,resources=persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=server-manager.acooldomain.co,resources=servermanagers/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=,resources=services,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=,resources=pods,verbs=get;list;watch;create
|
||||
// +kubebuilder:rbac:groups=,resources=pods,verbs=get;list;watch;create;delete
|
||||
|
||||
// Reconcile is part of the main kubernetes reconciliation loop which aims to
|
||||
// move the current state of the cluster closer to the desired state.
|
||||
@ -151,7 +152,13 @@ func (r *ServerManagerReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||
}
|
||||
logging.Info("verified browserPvc")
|
||||
|
||||
serverPod := r.ServerPod(s, pvc)
|
||||
image, err := r.GetImage(ctx, s)
|
||||
if err != nil {
|
||||
logging.Error(err, "Failed to get image")
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
serverPod := r.ServerPod(s, pvc, image)
|
||||
found := &corev1.Pod{}
|
||||
err = r.Get(ctx, client.ObjectKey{Namespace: pvc.Namespace, Name: pvc.Name}, found)
|
||||
if err == nil && !s.Spec.Server.On {
|
||||
@ -602,8 +609,13 @@ func (r *ServerManagerReconciler) ServerPvc(s *servermanagerv1alpha1.ServerManag
|
||||
return pvc
|
||||
}
|
||||
|
||||
func (r *ServerManagerReconciler) ServerPod(s *servermanagerv1alpha1.ServerManager, pvc *corev1.PersistentVolumeClaim) *corev1.Pod {
|
||||
ports := make([]corev1.ContainerPort, len(s.Spec.Server.Ports))
|
||||
func (r *ServerManagerReconciler) ServerPod(s *servermanagerv1alpha1.ServerManager, pvc *corev1.PersistentVolumeClaim, image *servermanagerv1alpha1.Image) *corev1.Pod {
|
||||
serverPorts := image.Spec.Ports
|
||||
if len(s.Spec.Server.Ports) > 0 {
|
||||
serverPorts = s.Spec.Server.Ports
|
||||
}
|
||||
|
||||
ports := make([]corev1.ContainerPort, len(serverPorts))
|
||||
|
||||
for i, port := range s.Spec.Server.Ports {
|
||||
ports[i] = corev1.ContainerPort{
|
||||
@ -612,6 +624,36 @@ func (r *ServerManagerReconciler) ServerPod(s *servermanagerv1alpha1.ServerManag
|
||||
}
|
||||
}
|
||||
|
||||
command := image.Spec.Command
|
||||
if len(s.Spec.Server.Command) > 0 {
|
||||
command = s.Spec.Server.Command
|
||||
}
|
||||
|
||||
args := image.Spec.Args
|
||||
if len(s.Spec.Server.Args) > 0 {
|
||||
args = s.Spec.Server.Args
|
||||
}
|
||||
|
||||
var initContainers []corev1.Container = nil
|
||||
|
||||
if image.Spec.InitScript != nil {
|
||||
initContainers = []corev1.Container{
|
||||
{
|
||||
Name: "init",
|
||||
Image: image.Spec.InitScript.Image,
|
||||
ImagePullPolicy: corev1.PullIfNotPresent,
|
||||
Command: image.Spec.Command,
|
||||
Args: image.Spec.InitScript.Args,
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{
|
||||
Name: "volume",
|
||||
MountPath: "/data",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pod := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: s.Name,
|
||||
@ -629,18 +671,19 @@ func (r *ServerManagerReconciler) ServerPod(s *servermanagerv1alpha1.ServerManag
|
||||
},
|
||||
},
|
||||
},
|
||||
InitContainers: initContainers,
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "server",
|
||||
Image: s.Spec.Server.Image,
|
||||
Image: image.Spec.Location,
|
||||
ImagePullPolicy: corev1.PullAlways,
|
||||
Command: s.Spec.Server.Command,
|
||||
Args: s.Spec.Server.Args,
|
||||
WorkingDir: s.Spec.Server.WorkingDir,
|
||||
Command: command,
|
||||
Args: args,
|
||||
WorkingDir: image.Spec.WorkingDir,
|
||||
Ports: ports,
|
||||
VolumeMounts: []corev1.VolumeMount{{
|
||||
Name: "volume",
|
||||
MountPath: s.Spec.Server.WorkingDir,
|
||||
MountPath: image.Spec.WorkingDir,
|
||||
}},
|
||||
Stdin: true,
|
||||
TTY: true,
|
||||
@ -648,10 +691,21 @@ func (r *ServerManagerReconciler) ServerPod(s *servermanagerv1alpha1.ServerManag
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
controllerutil.SetControllerReference(s, pod, r.Scheme)
|
||||
return pod
|
||||
}
|
||||
|
||||
func (r *ServerManagerReconciler) GetImage(ctx context.Context, s *servermanagerv1alpha1.ServerManager) (*servermanagerv1alpha1.Image, error) {
|
||||
image := &servermanagerv1alpha1.Image{}
|
||||
err := r.Get(ctx, client.ObjectKey{Name: s.Spec.Server.Image, Namespace: s.Namespace}, image)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return image, nil
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
func (r *ServerManagerReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
|
Loading…
x
Reference in New Issue
Block a user