Use metrics to display runner statuses instead of status field for EphemeralRunnerSet and AutoscalingRunnerSet

This commit is contained in:
Nikola Jokic
2026-07-14 19:55:19 +02:00
parent 7803f191b1
commit 6d2a1cdcce
30 changed files with 532 additions and 749 deletions
@@ -36,30 +36,23 @@ import (
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:JSONPath=".spec.minRunners",name=Minimum Runners,type=integer
// +kubebuilder:printcolumn:JSONPath=".spec.maxRunners",name=Maximum Runners,type=integer
// +kubebuilder:printcolumn:JSONPath=".status.currentRunners",name=Current Runners,type=integer
// +kubebuilder:printcolumn:JSONPath=".status.phase",name=Phase,type=string
// +kubebuilder:printcolumn:JSONPath=".status.pendingEphemeralRunners",name=Pending Runners,type=integer
// +kubebuilder:printcolumn:JSONPath=".status.runningEphemeralRunners",name=Running Runners,type=integer
// +kubebuilder:printcolumn:JSONPath=".status.failedEphemeralRunners",name=Failed Runners,type=integer
// AutoscalingRunnerSet is the Schema for the autoscalingrunnersets API
type AutoscalingRunnerSet struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// +optional
Spec AutoscalingRunnerSetSpec `json:"spec,omitempty"`
// +optional
Spec AutoscalingRunnerSetSpec `json:"spec,omitempty"`
Status AutoscalingRunnerSetStatus `json:"status,omitempty"`
}
// AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet
type AutoscalingRunnerSetSpec struct {
// +optional
// Required
GitHubConfigUrl string `json:"githubConfigUrl,omitempty"`
// +optional
// Required
GitHubConfigSecret string `json:"githubConfigSecret,omitempty"`
// +optional
@@ -80,7 +73,7 @@ type AutoscalingRunnerSetSpec struct {
// +optional
VaultConfig *VaultConfig `json:"vaultConfig,omitempty"`
// +optional
// Required
Template corev1.PodTemplateSpec `json:"template,omitempty"`
// +optional
@@ -114,16 +107,16 @@ type AutoscalingRunnerSetSpec struct {
EphemeralRunnerConfigSecretMetadata *ResourceMeta `json:"ephemeralRunnerConfigSecretMetadata,omitempty"`
// +optional
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Minimum:=0
MaxRunners *int `json:"maxRunners,omitempty"`
// +optional
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Minimum:=0
MinRunners *int `json:"minRunners,omitempty"`
}
type TLSConfig struct {
// +required
// Required
CertificateFrom *TLSCertificateSource `json:"certificateFrom,omitempty"`
}
@@ -160,7 +153,7 @@ func (c *TLSConfig) ToCertPool(keyFetcher func(name, key string) ([]byte, error)
}
type TLSCertificateSource struct {
// +required
// Required
ConfigMapKeyRef *corev1.ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
}
@@ -181,9 +174,9 @@ func (c *ProxyConfig) ToHTTPProxyConfig(secretFetcher func(string) (*corev1.Secr
}
if c.HTTP != nil {
u, err := url.Parse(c.HTTP.URL)
u, err := url.Parse(c.HTTP.Url)
if err != nil {
return nil, fmt.Errorf("failed to parse proxy http url %q: %w", c.HTTP.URL, err)
return nil, fmt.Errorf("failed to parse proxy http url %q: %w", c.HTTP.Url, err)
}
if c.HTTP.CredentialSecretRef != "" {
@@ -206,9 +199,9 @@ func (c *ProxyConfig) ToHTTPProxyConfig(secretFetcher func(string) (*corev1.Secr
}
if c.HTTPS != nil {
u, err := url.Parse(c.HTTPS.URL)
u, err := url.Parse(c.HTTPS.Url)
if err != nil {
return nil, fmt.Errorf("failed to parse proxy https url %q: %w", c.HTTPS.URL, err)
return nil, fmt.Errorf("failed to parse proxy https url %q: %w", c.HTTPS.Url, err)
}
if c.HTTPS.CredentialSecretRef != "" {
@@ -261,8 +254,8 @@ func (c *ProxyConfig) ProxyFunc(secretFetcher func(string) (*corev1.Secret, erro
}
type ProxyServerConfig struct {
// +required
URL string `json:"url,omitempty"`
// Required
Url string `json:"url,omitempty"`
// +optional
CredentialSecretRef string `json:"credentialSecretRef,omitempty"`
@@ -330,6 +323,20 @@ const (
AutoscalingRunnerSetPhaseOutdated AutoscalingRunnerSetPhase = "Outdated"
)
func (ars *AutoscalingRunnerSet) Hash() string {
type data struct {
Spec *AutoscalingRunnerSetSpec
Labels map[string]string
}
d := &data{
Spec: ars.Spec.DeepCopy(),
Labels: ars.Labels,
}
return hash.ComputeTemplateHash(d)
}
func (ars *AutoscalingRunnerSet) ListenerSpecHash() string {
arsSpec := ars.Spec.DeepCopy()
spec := arsSpec
@@ -23,13 +23,10 @@ import (
// EphemeralRunnerSetSpec defines the desired state of EphemeralRunnerSet
type EphemeralRunnerSetSpec struct {
// Replicas is the number of desired EphemeralRunner resources in the k8s namespace.
// +optional
Replicas int `json:"replicas,omitempty"`
// PatchID is the unique identifier for the patch issued by the listener app
// +optional
PatchID int `json:"patchID"`
// EphemeralRunnerSpec is the spec of the ephemeral runner
// +optional
EphemeralRunnerSpec EphemeralRunnerSpec `json:"ephemeralRunnerSpec,omitempty"`
// EphemeralRunnerMetadata is the metadata to be applied to all ephemeral runners created by this set.
// If the EphemeralRunnerMetadata is updated, the update applies to new ephemeral runners created after the update,
@@ -61,13 +58,10 @@ const (
// EphemeralRunnerSet is the Schema for the ephemeralrunnersets API
type EphemeralRunnerSet struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// +optional
Spec EphemeralRunnerSetSpec `json:"spec,omitempty"`
// +optional
Spec EphemeralRunnerSetSpec `json:"spec,omitempty"`
Status EphemeralRunnerSetStatus `json:"status,omitempty"`
}
@@ -14,11 +14,11 @@ import (
func TestProxyConfig_ToSecret(t *testing.T) {
config := &v1alpha1.ProxyConfig{
HTTP: &v1alpha1.ProxyServerConfig{
URL: "http://proxy.example.com:8080",
Url: "http://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
HTTPS: &v1alpha1.ProxyServerConfig{
URL: "https://proxy.example.com:8080",
Url: "https://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
NoProxy: []string{
@@ -48,11 +48,11 @@ func TestProxyConfig_ToSecret(t *testing.T) {
func TestProxyConfig_ProxyFunc(t *testing.T) {
config := &v1alpha1.ProxyConfig{
HTTP: &v1alpha1.ProxyServerConfig{
URL: "http://proxy.example.com:8080",
Url: "http://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
HTTPS: &v1alpha1.ProxyServerConfig{
URL: "https://proxy.example.com:8080",
Url: "https://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
NoProxy: []string{