v1alpha1

package
v0.1.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package v1alpha1 contains API Schema definitions for the redroid.isning.moe v1alpha1 API group. +groupName=redroid.isning.moe +kubebuilder:object:generate=true

Index

Constants

This section is empty.

Variables

View Source
var (
	// GroupVersion is the group version used to register these objects.
	GroupVersion = schema.GroupVersion{Group: "redroid.isning.moe", Version: "v1alpha1"}

	// SchemeBuilder is used to add functions to this group's scheme.
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)

Functions

This section is empty.

Types

type ConfigFile

type ConfigFile struct {
	// ConfigMapName is the name of the ConfigMap in the same namespace.
	ConfigMapName string `json:"configMapName"`
	// Key is the ConfigMap key to mount.
	Key string `json:"key"`
	// MountPath is the absolute path inside the container where the file is placed.
	MountPath string `json:"mountPath"`
}

ConfigFile mounts a single key from a ConfigMap as a file inside the integration container.

func (*ConfigFile) DeepCopy

func (in *ConfigFile) DeepCopy() *ConfigFile

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigFile.

func (*ConfigFile) DeepCopyInto

func (in *ConfigFile) DeepCopyInto(out *ConfigFile)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type InstanceRef

type InstanceRef struct {
	// Name is the RedroidInstance name in the same namespace.
	Name string `json:"name"`

	// Volumes adds additional volumes specific to this instance's Job Pod.
	// These are merged with task-level spec.volumes; an instance volume overrides
	// only user-defined task-level volumes with the same name. Reserved volumes
	// (data-base, data-diff, dev-dri) and controller-generated ConfigMap volumes
	// (cm-* prefix) are never overrideable — those retain precedence regardless.
	// +optional
	// +listType=map
	// +listMapKey=name
	Volumes []corev1.Volume `json:"volumes,omitempty"`

	// VolumeMounts adds extra volume mounts into every integration container
	// for this instance only. Use together with instance-level Volumes to
	// mount instance-specific ConfigMaps, Secrets, etc.
	// +optional
	VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
}

InstanceRef selects a RedroidInstance by name to include in a task run.

func (*InstanceRef) DeepCopy

func (in *InstanceRef) DeepCopy() *InstanceRef

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRef.

func (*InstanceRef) DeepCopyInto

func (in *InstanceRef) DeepCopyInto(out *InstanceRef)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type InstanceServiceSpec

type InstanceServiceSpec struct {
	// Type is the Service type. Defaults to ClusterIP.
	// Use NodePort or LoadBalancer to expose the ADB port outside the cluster.
	// +optional
	// +kubebuilder:default="ClusterIP"
	// +kubebuilder:validation:Enum=ClusterIP;NodePort;LoadBalancer
	Type corev1.ServiceType `json:"type,omitempty"`

	// Annotations are extra annotations merged onto the Service.
	// Useful for cloud-provider-specific behaviour, e.g. AWS NLB, GCP NEG.
	// +optional
	Annotations map[string]string `json:"annotations,omitempty"`

	// NodePort pins the node port when Type=NodePort.
	// If 0 or unset, Kubernetes auto-assigns a port from the node-port range.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=65535
	NodePort *int32 `json:"nodePort,omitempty"`
}

InstanceServiceSpec customises the Kubernetes Service that the operator creates to front the ADB port of a RedroidInstance.

func (*InstanceServiceSpec) DeepCopy

func (in *InstanceServiceSpec) DeepCopy() *InstanceServiceSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceServiceSpec.

func (*InstanceServiceSpec) DeepCopyInto

func (in *InstanceServiceSpec) DeepCopyInto(out *InstanceServiceSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type IntegrationSpec

type IntegrationSpec struct {
	// Name is a unique identifier for this integration within the task.
	Name string `json:"name"`

	// Image is the container image for this tool.
	Image string `json:"image"`

	// ImagePullPolicy overrides the image pull policy. Defaults to Always.
	// +optional
	// +kubebuilder:default="Always"
	ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`

	// Command overrides the container entrypoint.
	// +optional
	Command []string `json:"command,omitempty"`

	// Args is passed to the container command.
	// +optional
	Args []string `json:"args,omitempty"`

	// WorkingDir sets the current working directory inside the container.
	// +optional
	WorkingDir string `json:"workingDir,omitempty"`

	// Env provides additional environment variables, merged after ADB_ADDRESS/INSTANCE_INDEX.
	// +optional
	Env []corev1.EnvVar `json:"env,omitempty"`

	// Configs mounts ConfigMap keys as files inside this container.
	// +optional
	Configs []ConfigFile `json:"configs,omitempty"`

	// VolumeMounts adds extra volume mounts into the integration container.
	// +optional
	VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`

	// SecurityContext sets per-container security options.
	// +optional
	SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`

	// Resources optionally sets CPU/memory limits on this container.
	// +optional
	Resources corev1.ResourceRequirements `json:"resources,omitempty"`
}

IntegrationSpec describes a tool container that runs against the Redroid ADB. ADB address is injected as ADB_ADDRESS env var; instance index as INSTANCE_INDEX.

func (*IntegrationSpec) DeepCopy

func (in *IntegrationSpec) DeepCopy() *IntegrationSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationSpec.

func (*IntegrationSpec) DeepCopyInto

func (in *IntegrationSpec) DeepCopyInto(out *IntegrationSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type NetworkSpec

type NetworkSpec struct {
	// DNS lists DNS server addresses (up to N servers).
	// They map to androidboot.redroid_net_ndns and androidboot.redroid_net_dns<1..N>.
	// +optional
	DNS []string `json:"dns,omitempty"`

	// Proxy configures HTTP/HTTPS proxy for outbound traffic.
	// +optional
	Proxy *ProxySpec `json:"proxy,omitempty"`
}

NetworkSpec configures DNS and proxy settings for the Redroid instance.

func (*NetworkSpec) DeepCopy

func (in *NetworkSpec) DeepCopy() *NetworkSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkSpec.

func (*NetworkSpec) DeepCopyInto

func (in *NetworkSpec) DeepCopyInto(out *NetworkSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ProxySpec

type ProxySpec struct {
	// Type selects the proxy mode: static, pac, none, or unassigned.
	// +optional
	// +kubebuilder:validation:Enum=static;pac;none;unassigned
	Type string `json:"type,omitempty"`

	// Host is the proxy server hostname or IP (used with Type=static).
	// +optional
	Host string `json:"host,omitempty"`

	// Port is the proxy server port. Defaults to 3128.
	// +optional
	// +kubebuilder:default=3128
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=65535
	Port *int32 `json:"port,omitempty"`

	// ExcludeList is a comma-separated list of hosts bypassing the proxy.
	// +optional
	ExcludeList string `json:"excludeList,omitempty"`

	// PAC is the URL of a proxy auto-config file (used with Type=pac).
	// +optional
	PAC string `json:"pac,omitempty"`
}

ProxySpec configures HTTP/HTTPS proxy for the Redroid network stack.

func (*ProxySpec) DeepCopy

func (in *ProxySpec) DeepCopy() *ProxySpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxySpec.

func (*ProxySpec) DeepCopyInto

func (in *ProxySpec) DeepCopyInto(out *ProxySpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RedroidInstance

type RedroidInstance struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   RedroidInstanceSpec   `json:"spec,omitempty"`
	Status RedroidInstanceStatus `json:"status,omitempty"`
}

RedroidInstance is the Schema for the redroidinstances API. It represents a single persistent Android container instance backed by overlayfs storage.

func (*RedroidInstance) DeepCopy

func (in *RedroidInstance) DeepCopy() *RedroidInstance

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidInstance.

func (*RedroidInstance) DeepCopyInto

func (in *RedroidInstance) DeepCopyInto(out *RedroidInstance)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*RedroidInstance) DeepCopyObject

func (in *RedroidInstance) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type RedroidInstanceConditionType

type RedroidInstanceConditionType string

RedroidInstanceConditionType defines well-known condition types for RedroidInstance.

const (
	// RedroidInstanceConditionReady is true when the Pod is Running and the ADB address is known.
	RedroidInstanceConditionReady RedroidInstanceConditionType = "Ready"

	// RedroidInstanceConditionScheduled is true once a Pod has been successfully created.
	RedroidInstanceConditionScheduled RedroidInstanceConditionType = "Scheduled"
)

type RedroidInstanceList

type RedroidInstanceList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []RedroidInstance `json:"items"`
}

RedroidInstanceList contains a list of RedroidInstance.

func (*RedroidInstanceList) DeepCopy

func (in *RedroidInstanceList) DeepCopy() *RedroidInstanceList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidInstanceList.

func (*RedroidInstanceList) DeepCopyInto

func (in *RedroidInstanceList) DeepCopyInto(out *RedroidInstanceList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*RedroidInstanceList) DeepCopyObject

func (in *RedroidInstanceList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type RedroidInstancePhase

type RedroidInstancePhase string

RedroidInstancePhase describes the lifecycle phase of a RedroidInstance. +kubebuilder:validation:Enum=Pending;Running;Stopped;Failed

const (
	RedroidInstancePending RedroidInstancePhase = "Pending"
	RedroidInstanceRunning RedroidInstancePhase = "Running"
	RedroidInstanceStopped RedroidInstancePhase = "Stopped"
	RedroidInstanceFailed  RedroidInstancePhase = "Failed"
)

RedroidInstance phase constants.

type RedroidInstanceSpec

type RedroidInstanceSpec struct {
	// Index is the overlayfs partition index shared with RedroidTasks.
	// /data-base is shared across all instances; /data-diff/<Index> is this instance's private layer.
	// +kubebuilder:validation:Minimum=0
	Index int `json:"index"`

	// Image is the redroid container image. Defaults to redroid/redroid:16.0.0-latest.
	// +optional
	// +kubebuilder:default="redroid/redroid:16.0.0-latest"
	Image string `json:"image,omitempty"`

	// ImagePullPolicy for the redroid container image. Defaults to IfNotPresent.
	// +optional
	// +kubebuilder:default="IfNotPresent"
	ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`

	// ImagePullSecrets references Secret resources for pulling private images.
	// +optional
	ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`

	// Suspend controls whether the Android instance Pod should be running.
	// Set to false (default) to start the instance; true to stop it without deleting the resource.
	// This follows the same semantics as CronJob.spec.suspend.
	// +optional
	Suspend bool `json:"suspend,omitempty"`

	// SharedDataPVC is the PVC name for the shared /data-base volume (read-only lower layer).
	// +kubebuilder:default="redroid-data-base-pvc"
	SharedDataPVC string `json:"sharedDataPVC"`

	// DiffDataPVC is the PVC name for the per-instance /data-diff volume (writable upper layer).
	// +kubebuilder:default="redroid-data-diff-pvc"
	DiffDataPVC string `json:"diffDataPVC"`

	// BaseMode makes this instance write directly to SharedDataPVC as /data,
	// bypassing the overlayfs per-instance layer. Use this to initialise the shared
	// base image (install common APKs, first-boot setup, etc.).
	//
	// In base mode:
	//   - SharedDataPVC is mounted at /data (read-write).
	//   - DiffDataPVC is NOT mounted.
	//   - androidboot.use_redroid_overlayfs is set to 0.
	//
	// Typical workflow:
	//   1. Create a RedroidInstance with baseMode: true, suspend: false.
	//   2. ADB-connect and perform initial setup (app installs, configs).
	//   3. Set suspend: true (or delete) once satisfied.
	//   4. Normal instances (baseMode: false) sharing the same SharedDataPVC
	//      will see the initialised state as their read-only lower layer.
	//
	// WARNING: running a base-mode instance concurrently with normal instances
	// that share the same SharedDataPVC may corrupt their overlayfs lower layer.
	// Use spec.suspend or status.suspended on all normal instances first.
	// +optional
	BaseMode bool `json:"baseMode,omitempty"`

	// GPUMode sets androidboot.redroid_gpu_mode. Defaults to "host".
	// +optional
	// +kubebuilder:default="host"
	// +kubebuilder:validation:Enum=host;guest;auto;none
	GPUMode string `json:"gpuMode,omitempty"`

	// GPUNode sets androidboot.redroid_gpu_node (DRM device path).
	// When empty the Redroid runtime auto-detects the GPU node.
	// +optional
	GPUNode string `json:"gpuNode,omitempty"`

	// ADBPort is the ADB TCP port exposed by the container. Defaults to 5555.
	// +optional
	// +kubebuilder:default=5555
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=65535
	ADBPort *int32 `json:"adbPort,omitempty"`

	// Screen configures the virtual display (width, height, dpi, fps).
	// +optional
	Screen *ScreenSpec `json:"screen,omitempty"`

	// Network configures DNS and proxy settings for the Android instance.
	// +optional
	Network *NetworkSpec `json:"network,omitempty"`

	// DisableKmsgRedirect disables the default /dev/kmsg redirect.
	// By default (false) the operator injects an init container that copies a
	// musl-statically-linked socat binary into the redroid container via an
	// emptyDir volume. The main container's wrapper script uses it to create a
	// PTY, bind-mounts the PTY slave over /dev/kmsg (preventing host dmesg
	// pollution), and pipes PTY master output to the container's stdout so
	// Android kernel logs are accessible via `kubectl logs <pod>`. Set to true
	// to disable this mechanism entirely.
	// +optional
	DisableKmsgRedirect bool `json:"disableKmsgRedirect,omitempty"`

	// KmsgToolsImage overrides the default init container image used to inject
	// the socat binary. The image must provide /bin/socat (statically linked)
	// and /bin/sh. Has no effect when DisableKmsgRedirect is true.
	// Defaults to ghcr.io/isning/redroid-operator/kmsg-tools:latest.
	// +optional
	KmsgToolsImage string `json:"kmsgToolsImage,omitempty"`

	// ExtraArgs are additional androidboot.* arguments passed to the redroid container.
	// Supports $(VAR_NAME) substitution from ExtraEnv.
	// +optional
	ExtraArgs []string `json:"extraArgs,omitempty"`

	// ExtraEnv defines additional environment variables for the redroid container.
	// Supports valueFrom.secretKeyRef and valueFrom.configMapKeyRef for sensitive params.
	// Can be referenced in ExtraArgs via $(VAR_NAME) syntax.
	// +optional
	ExtraEnv []corev1.EnvVar `json:"extraEnv,omitempty"`

	// NodeSelector constrains which node the Pod is scheduled on.
	// +optional
	NodeSelector map[string]string `json:"nodeSelector,omitempty"`

	// Tolerations allows the Pod to be scheduled on nodes with matching taints.
	// +optional
	Tolerations []corev1.Toleration `json:"tolerations,omitempty"`

	// Affinity provides advanced scheduling constraints.
	// +optional
	Affinity *corev1.Affinity `json:"affinity,omitempty"`

	// Resources optionally sets CPU/memory limits on the redroid container.
	// +optional
	Resources corev1.ResourceRequirements `json:"resources,omitempty"`

	// Service customises the Kubernetes Service the operator creates to expose the ADB port.
	// The Service is always created; this field controls its type, annotations, and node port.
	// +optional
	Service *InstanceServiceSpec `json:"service,omitempty"`
}

RedroidInstanceSpec defines the desired state of a RedroidInstance.

func (*RedroidInstanceSpec) DeepCopy

func (in *RedroidInstanceSpec) DeepCopy() *RedroidInstanceSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidInstanceSpec.

func (*RedroidInstanceSpec) DeepCopyInto

func (in *RedroidInstanceSpec) DeepCopyInto(out *RedroidInstanceSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RedroidInstanceStatus

type RedroidInstanceStatus struct {
	// ObservedGeneration is the most recent generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Phase is the current lifecycle phase.
	// +optional
	Phase RedroidInstancePhase `json:"phase,omitempty"`

	// PodName is the name of the managed Pod, if it exists.
	// +optional
	PodName string `json:"podName,omitempty"`

	// ADBAddress is the in-cluster address (host:port) to reach this instance's ADB.
	// +optional
	ADBAddress string `json:"adbAddress,omitempty"`

	// Conditions holds detailed status conditions (Ready, Scheduled).
	// +optional
	// +listType=map
	// +listMapKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty"`

	// Suspended holds a suspend-override override set by controllers or manual operators.
	// The instance Pod is stopped while this field is non-nil, regardless of spec.suspend.
	// Unlike spec.suspend, this field is not reconciled by GitOps tools (e.g. Flux) so clearing
	// it does not cause config drift.
	//
	// To manually suspend: kubectl patch redroidinstance <name> --subresource=status
	//   --type=merge -p '{"status":{"suspended":{"reason":"maintenance","actor":"manual"}}}'
	// To clear: kubectl patch redroidinstance <name> --subresource=status
	//   --type=merge -p '{"status":{"suspended":null}}'
	// +optional
	Suspended *SuspendedStatus `json:"suspended,omitempty"`

	// Woken holds a wake-override set by the RedroidTask controller when spec.wakeInstance
	// is true. The instance Pod runs while this field is non-nil, even if spec.suspend is true.
	// Unlike spec.suspend, this field is not reconciled by GitOps tools (e.g. Flux).
	//
	// To manually wake: kubectl patch redroidinstance <name> --subresource=status
	//   --type=merge -p '{"status":{"woken":{"reason":"on-demand","actor":"manual"}}}'
	// To clear: kubectl patch redroidinstance <name> --subresource=status
	//   --type=merge -p '{"status":{"woken":null}}'
	// +optional
	Woken *WokenStatus `json:"woken,omitempty"`
}

RedroidInstanceStatus defines the observed state of RedroidInstance.

func (*RedroidInstanceStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidInstanceStatus.

func (*RedroidInstanceStatus) DeepCopyInto

func (in *RedroidInstanceStatus) DeepCopyInto(out *RedroidInstanceStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RedroidTask

type RedroidTask struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   RedroidTaskSpec   `json:"spec,omitempty"`
	Status RedroidTaskStatus `json:"status,omitempty"`
}

RedroidTask is the Schema for the redroidtasks API. It describes a workload (one-shot or recurring via CronJob) that runs integration tool containers against a set of RedroidInstance overlay partitions.

func (*RedroidTask) DeepCopy

func (in *RedroidTask) DeepCopy() *RedroidTask

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidTask.

func (*RedroidTask) DeepCopyInto

func (in *RedroidTask) DeepCopyInto(out *RedroidTask)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*RedroidTask) DeepCopyObject

func (in *RedroidTask) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type RedroidTaskConditionType

type RedroidTaskConditionType string

RedroidTaskConditionType defines well-known condition types for RedroidTask.

const (
	// RedroidTaskConditionActive is true when at least one Job is currently running.
	RedroidTaskConditionActive RedroidTaskConditionType = "Active"

	// RedroidTaskConditionComplete is true when all one-shot Jobs have completed successfully.
	RedroidTaskConditionComplete RedroidTaskConditionType = "Complete"

	// RedroidTaskConditionFailed is true when one or more Jobs have failed beyond the backoff limit.
	RedroidTaskConditionFailed RedroidTaskConditionType = "Failed"
)

type RedroidTaskList

type RedroidTaskList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []RedroidTask `json:"items"`
}

RedroidTaskList contains a list of RedroidTask.

func (*RedroidTaskList) DeepCopy

func (in *RedroidTaskList) DeepCopy() *RedroidTaskList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidTaskList.

func (*RedroidTaskList) DeepCopyInto

func (in *RedroidTaskList) DeepCopyInto(out *RedroidTaskList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*RedroidTaskList) DeepCopyObject

func (in *RedroidTaskList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type RedroidTaskSpec

type RedroidTaskSpec struct {
	// Instances lists the RedroidInstance resources that this task targets.
	// Each instance runs its own Job/CronJob execution, inheriting
	// the instance's image, overlayfs PVCs, and GPU settings.
	// +kubebuilder:validation:MinItems=1
	// +listType=map
	// +listMapKey=name
	Instances []InstanceRef `json:"instances"`

	// Schedule is a Cron expression for recurring execution (e.g. "0 4 * * *").
	// If empty, the task is one-shot and runs immediately upon creation.
	// +optional
	Schedule string `json:"schedule,omitempty"`

	// Suspend pauses CronJob execution without deleting it. Ignored for one-shot tasks.
	// Follows the same semantics as CronJob.spec.suspend.
	// +optional
	Suspend bool `json:"suspend,omitempty"`

	// Timezone is the IANA timezone name for the CronJob schedule (e.g. "Asia/Shanghai").
	// Requires Kubernetes >= 1.27. Ignored for one-shot tasks.
	// +optional
	Timezone string `json:"timezone,omitempty"`

	// StartingDeadlineSeconds is the optional deadline (seconds) for starting a CronJob
	// if it misses scheduled time. Ignored for one-shot tasks.
	// +optional
	// +kubebuilder:validation:Minimum=0
	StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty"`

	// BackoffLimit specifies the number of retries before marking the Job as failed.
	// Defaults to 0 (no retries).
	// +optional
	// +kubebuilder:default=0
	// +kubebuilder:validation:Minimum=0
	BackoffLimit *int32 `json:"backoffLimit,omitempty"`

	// SuspendInstance temporarily stops the referenced RedroidInstance Pod while the
	// one-shot Job runs, then automatically restores it on Job completion/failure.
	// This prevents overlayfs conflicts when both the instance Pod and the task Job
	// would otherwise write to the same /data-diff volume simultaneously.
	//
	// Mechanism: the task controller sets status.suspended on each instance
	// before creating the Job, waits until the instance Pod is stopped (phase=Stopped),
	// then creates the Job. After the Job finishes the controller clears the field.
	//
	// This field is ignored for CronJob-based (scheduled) tasks.
	// Mutually exclusive with WakeInstance.
	// +optional
	SuspendInstance bool `json:"suspendInstance,omitempty"`

	// WakeInstance temporarily starts the referenced RedroidInstance Pod while the
	// one-shot Job runs, then restores the original suspended state on Job completion/failure.
	// Use this for on-demand instances that are normally stopped (spec.suspend: true).
	//
	// Mechanism: the task controller sets status.woken on each instance before creating the
	// Job, waits until the instance Pod reaches phase=Running, then creates the Job.
	// After the Job finishes the controller clears status.woken, allowing spec.suspend to
	// take effect again.
	//
	// This field is ignored for CronJob-based (scheduled) tasks.
	// Mutually exclusive with SuspendInstance.
	// +optional
	WakeInstance bool `json:"wakeInstance,omitempty"`

	// ActiveDeadlineSeconds limits the duration of each Job in seconds.
	// Jobs exceeding this limit are terminated. 0 means no limit.
	// +optional
	// +kubebuilder:validation:Minimum=1
	ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`

	// TTLSecondsAfterFinished automatically removes completed one-shot Jobs after
	// this many seconds. Ignored for scheduled tasks.
	// +optional
	// +kubebuilder:validation:Minimum=0
	TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"`

	// Parallelism controls how many instance Pods run concurrently.
	// Defaults to the number of Instances (run all in parallel).
	// +optional
	// +kubebuilder:validation:Minimum=1
	Parallelism *int32 `json:"parallelism,omitempty"`

	// Integrations is the ordered list of tool containers executed per instance.
	// They run as regular containers alongside the redroid sidecar, sharing localhost.
	// +kubebuilder:validation:MinItems=1
	// +listType=map
	// +listMapKey=name
	Integrations []IntegrationSpec `json:"integrations"`

	// Volumes defines additional volumes to attach to the Job Pod.
	// Use this together with integration VolumeMounts to mount arbitrary volume
	// sources (Secrets, projected ConfigMaps, emptyDir, etc.) that are not covered
	// by the per-key Configs shorthand.
	// +optional
	// +listType=map
	// +listMapKey=name
	Volumes []corev1.Volume `json:"volumes,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use for all Pods
	// created by this task. Applies at the PodSpec level and is shared by every
	// integration container. If empty, the namespace default ServiceAccount is used.
	// +optional
	ServiceAccountName string `json:"serviceAccountName,omitempty"`

	// ImagePullSecrets applies to all integration containers in this task.
	// +optional
	ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`

	// SuccessfulJobsHistoryLimit controls how many successful CronJob-spawned Jobs to retain. Defaults to 3.
	// +optional
	// +kubebuilder:default=3
	// +kubebuilder:validation:Minimum=0
	SuccessfulJobsHistoryLimit *int32 `json:"successfulJobsHistoryLimit,omitempty"`

	// FailedJobsHistoryLimit controls how many failed CronJob-spawned Jobs to retain. Defaults to 3.
	// +optional
	// +kubebuilder:default=3
	// +kubebuilder:validation:Minimum=0
	FailedJobsHistoryLimit *int32 `json:"failedJobsHistoryLimit,omitempty"`
}

RedroidTaskSpec defines the desired state of RedroidTask. +kubebuilder:validation:XValidation:rule="!(has(self.suspendInstance) && self.suspendInstance == true && has(self.wakeInstance) && self.wakeInstance == true)",message="suspendInstance and wakeInstance are mutually exclusive"

func (*RedroidTaskSpec) DeepCopy

func (in *RedroidTaskSpec) DeepCopy() *RedroidTaskSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidTaskSpec.

func (*RedroidTaskSpec) DeepCopyInto

func (in *RedroidTaskSpec) DeepCopyInto(out *RedroidTaskSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RedroidTaskStatus

type RedroidTaskStatus struct {
	// ObservedGeneration is the most recent generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// LastScheduleTime is the last time the CronJob was scheduled.
	// +optional
	LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`

	// LastSuccessfulTime is the last time a Job completed successfully.
	// +optional
	LastSuccessfulTime *metav1.Time `json:"lastSuccessfulTime,omitempty"`

	// ActiveJobs lists the names of currently running Jobs.
	// +optional
	ActiveJobs []string `json:"activeJobs,omitempty"`

	// Conditions holds detailed status conditions (Active, Complete, Failed).
	// +optional
	// +listType=map
	// +listMapKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty"`
}

RedroidTaskStatus defines the observed state of RedroidTask.

func (*RedroidTaskStatus) DeepCopy

func (in *RedroidTaskStatus) DeepCopy() *RedroidTaskStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RedroidTaskStatus.

func (*RedroidTaskStatus) DeepCopyInto

func (in *RedroidTaskStatus) DeepCopyInto(out *RedroidTaskStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ScreenSpec

type ScreenSpec struct {
	// Width is the screen width in pixels. Defaults to 720.
	// +optional
	// +kubebuilder:validation:Minimum=1
	Width *int32 `json:"width,omitempty"`

	// Height is the screen height in pixels. Defaults to 1280.
	// +optional
	// +kubebuilder:validation:Minimum=1
	Height *int32 `json:"height,omitempty"`

	// DPI is the screen density. Defaults to 320.
	// +optional
	// +kubebuilder:validation:Minimum=1
	DPI *int32 `json:"dpi,omitempty"`

	// FPS is the display frame rate. Defaults to 30 (Android 12+) or 15 (older).
	// +optional
	// +kubebuilder:validation:Minimum=1
	FPS *int32 `json:"fps,omitempty"`
}

ScreenSpec configures the virtual display exposed by the Redroid instance.

func (*ScreenSpec) DeepCopy

func (in *ScreenSpec) DeepCopy() *ScreenSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScreenSpec.

func (*ScreenSpec) DeepCopyInto

func (in *ScreenSpec) DeepCopyInto(out *ScreenSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SuspendedStatus

type SuspendedStatus struct {
	// Reason is a human-readable explanation for the temporary suspend.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Until is an optional expiry timestamp. The controller automatically clears the
	// temporary suspend (and restarts the Pod) once this time has passed.
	// +optional
	Until *metav1.Time `json:"until,omitempty"`

	// Actor identifies who set the temporary suspend, e.g. "manual", "task/maa-task".
	// +optional
	Actor string `json:"actor,omitempty"`
}

SuspendedStatus holds a suspend-override that stops the instance Pod without modifying spec.suspend. Because this field lives in status it is not reconciled by GitOps tools such as Flux, preventing config drift.

Set by: operators (manual kubectl patch), or by the RedroidTask controller when spec.suspendInstance is true. Clear by patching status.suspended to null, or rely on the automatic expiry if Until is set.

func (*SuspendedStatus) DeepCopy

func (in *SuspendedStatus) DeepCopy() *SuspendedStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SuspendedStatus.

func (*SuspendedStatus) DeepCopyInto

func (in *SuspendedStatus) DeepCopyInto(out *SuspendedStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type WokenStatus

type WokenStatus struct {
	// Reason is a human-readable explanation for the temporary wake.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Until is an optional expiry timestamp. The controller automatically clears the
	// temporary wake (and lets spec.suspend take effect again) once this time has passed.
	// +optional
	Until *metav1.Time `json:"until,omitempty"`

	// Actor identifies who set the temporary wake, e.g. "task/maa-task".
	// +optional
	Actor string `json:"actor,omitempty"`
}

WokenStatus holds a wake-override that forces the instance Pod to run even when spec.suspend is true. Because this field lives in status it is not reconciled by GitOps tools such as Flux, preventing config drift.

Set by: the RedroidTask controller when spec.wakeInstance is true. Clear by patching status.woken to null, or rely on the automatic expiry if Until is set.

Priority: woken overrides spec.suspend and status.suspended.

func (*WokenStatus) DeepCopy

func (in *WokenStatus) DeepCopy() *WokenStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WokenStatus.

func (*WokenStatus) DeepCopyInto

func (in *WokenStatus) DeepCopyInto(out *WokenStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL