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 ¶
- Variables
- type ConfigFile
- type InstanceRef
- type InstanceServiceSpec
- type IntegrationSpec
- type NetworkSpec
- type ProxySpec
- type RedroidInstance
- type RedroidInstanceConditionType
- type RedroidInstanceList
- type RedroidInstancePhase
- type RedroidInstanceSpec
- type RedroidInstanceStatus
- type RedroidTask
- type RedroidTaskConditionType
- type RedroidTaskList
- type RedroidTaskSpec
- type RedroidTaskStatus
- type ScreenSpec
- type SuspendedStatus
- type WokenStatus
Constants ¶
This section is empty.
Variables ¶
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 ¶
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxySpec.
func (*ProxySpec) DeepCopyInto ¶
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"`
// +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 ¶
func (in *RedroidInstanceStatus) DeepCopy() *RedroidInstanceStatus
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.