Files
actions-runner-controller/controllers/runnerreplicaset_controller.go

317 lines
10 KiB
Go
Raw Permalink Normal View History

/*
Copyright 2020 The actions-runner-controller authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers
import (
"context"
"errors"
"fmt"
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
"reflect"
"time"
"github.com/go-logr/logr"
gogithub "github.com/google/go-github/v39/github"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
"github.com/actions-runner-controller/actions-runner-controller/github"
)
// RunnerReplicaSetReconciler reconciles a Runner object
type RunnerReplicaSetReconciler struct {
client.Client
Log logr.Logger
Recorder record.EventRecorder
Scheme *runtime.Scheme
GitHubClient *github.Client
Name string
}
// +kubebuilder:rbac:groups=actions.summerwind.dev,resources=runnerreplicasets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=actions.summerwind.dev,resources=runnerreplicasets/finalizers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=actions.summerwind.dev,resources=runnerreplicasets/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=actions.summerwind.dev,resources=runners,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=actions.summerwind.dev,resources=runners/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
feat: RunnerSet backed by StatefulSet (#629) * feat: RunnerSet backed by StatefulSet Unlike a runner deployment, a runner set can manage a set of stateful runners by combining a statefulset and an admission webhook that mutates statefulset-managed pods with required envvars and registration tokens. Resolves #613 Ref #612 * Upgrade controller-runtime to 0.9.0 * Bump Go to 1.16.x following controller-runtime 0.9.0 * Upgrade kubebuilder to 2.3.2 for updated etcd and apiserver following local setup * Fix startup failure due to missing LeaderElectionID * Fix the issue that any pods become unable to start once actions-runner-controller got failed after the mutating webhook has been registered * Allow force-updating statefulset * Fix runner container missing work and certs-client volume mounts and DOCKER_HOST and DOCKER_TLS_VERIFY envvars when dockerdWithinRunner=false * Fix runnerset-controller not applying statefulset.spec.template.spec changes when there were no changes in runnerset spec * Enable running acceptance tests against arbitrary kind cluster * RunnerSet supports non-ephemeral runners only today * fix: docker-build from root Makefile on intel mac * fix: arch check fixes for mac and ARM * ci: aligning test data format and patching checks * fix: removing namespace in test data * chore: adding more ignores * chore: removing leading space in shebang * Re-add metrics to org hra testdata * Bump cert-manager to v1.1.1 and fix deploy.sh Co-authored-by: toast-gear <15716903+toast-gear@users.noreply.github.com> Co-authored-by: Callum James Tait <callum.tait@photobox.com>
2021-06-22 17:10:09 +09:00
func (r *RunnerReplicaSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := r.Log.WithValues("runnerreplicaset", req.NamespacedName)
var rs v1alpha1.RunnerReplicaSet
if err := r.Get(ctx, req.NamespacedName, &rs); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
if !rs.ObjectMeta.DeletionTimestamp.IsZero() {
return ctrl.Result{}, nil
}
selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector)
if err != nil {
return ctrl.Result{}, err
}
// Get the Runners managed by the target RunnerReplicaSet
var allRunners v1alpha1.RunnerList
if err := r.List(
ctx,
&allRunners,
client.InNamespace(req.Namespace),
client.MatchingLabelsSelector{Selector: selector},
); err != nil {
if !kerrors.IsNotFound(err) {
return ctrl.Result{}, err
}
}
var myRunners []v1alpha1.Runner
var (
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
current int
ready int
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
available int
)
for _, r := range allRunners.Items {
// This guard is required to avoid the RunnerReplicaSet created by the controller v0.17.0 or before
// to not treat all the runners in the namespace as its children.
if metav1.IsControlledBy(&r, &rs) && !metav1.HasAnnotation(r.ObjectMeta, annotationKeyRegistrationOnly) {
myRunners = append(myRunners, r)
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
current += 1
if r.Status.Phase == string(corev1.PodRunning) {
ready += 1
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
// available is currently the same as ready, as we don't yet have minReadySeconds for runners
available += 1
}
}
}
var desired int
if rs.Spec.Replicas != nil {
desired = *rs.Spec.Replicas
} else {
desired = 1
}
// TODO: remove this registration runner cleanup later (v0.23.0 or v0.24.0)
//
// We had to have a registration-only runner to support scale-from-zero before.
// But since Sep 2021 Actions update on GitHub Cloud and GHES 3.3, it is unneceesary.
// See the below issues for more contexts:
// https://github.com/actions-runner-controller/actions-runner-controller/issues/516
// https://github.com/actions-runner-controller/actions-runner-controller/issues/859
//
// In the below block, we have a logic to remove existing registration-only runners as unnecessary.
// This logic is introduced since actions-runner-controller 0.21.0 and probably last one or two minor releases
// so that actions-runner-controller instance in everyone's cluster won't leave dangling registration-only runners.
registrationOnlyRunnerNsName := req.NamespacedName
registrationOnlyRunnerNsName.Name = registrationOnlyRunnerNameFor(rs.Name)
registrationOnlyRunner := v1alpha1.Runner{}
registrationOnlyRunnerExists := false
if err := r.Get(
ctx,
registrationOnlyRunnerNsName,
&registrationOnlyRunner,
); err != nil {
if !kerrors.IsNotFound(err) {
return ctrl.Result{}, err
}
} else {
registrationOnlyRunnerExists = true
}
if registrationOnlyRunnerExists {
if err := r.Client.Delete(ctx, &registrationOnlyRunner); err != nil {
log.Error(err, "Retrying soon because we failed to delete registration-only runner")
return ctrl.Result{Requeue: true}, nil
}
}
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
if current > desired {
n := current - desired
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
log.V(0).Info(fmt.Sprintf("Deleting %d runners", n), "desired", desired, "current", current, "ready", ready)
// get runners that are currently offline/not busy/timed-out to register
var deletionCandidates []v1alpha1.Runner
Manage runner with label (#355) * Update RunnerDeploymentSpec to have Selector field Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Update RunnerReplicaSetSpec to have Selector field Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Add CloneSelectorAndAddLabel to add Selector field Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Fix tests Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Use label to find RunnerReplicaSet/Runner Signed-off-by: binoue <banji-inoue@cybozu.co.jp> * Update controller-gen versions in CRD Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Update autoscaler to list Pods with labels Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Add debug log Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Modify RunnerDeployment tests Signed-off-by: binoue <banji-inoue@cybozu.co.jp> * Modify RunnerReplicaset test Signed-off-by: binoue <banji-inoue@cybozu.co.jp> * Modify integration test Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Use RunnerDeployment Template Labels as the default selector for backward compatibility * Fix labeling Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Update func in Eventually to return (int, error) Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Update RunnerDeployment controller not to use label selector Signed-off-by: Hiroshi Muraoka <h.muraoka714@gmail.com> * Fix potential replicaset controller breakage on replicaset created before v0.17.0 * Fix errors on existing runner replica sets * Ensure RunnerReplicaSet Spec Selector addition does not break controller * Ensure RunnerDeployment Template.Spec.Labels change does result in template hash change * Fix comment Co-authored-by: binoue <banji-inoue@cybozu.co.jp> Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
2021-03-05 10:15:39 +09:00
for _, runner := range allRunners.Items {
busy, err := r.GitHubClient.IsRunnerBusy(ctx, runner.Spec.Enterprise, runner.Spec.Organization, runner.Spec.Repository, runner.Name)
if err != nil {
notRegistered := false
offline := false
var notFoundException *github.RunnerNotFound
var offlineException *github.RunnerOffline
if errors.As(err, &notFoundException) {
log.V(1).Info("Failed to check if runner is busy. Either this runner has never been successfully registered to GitHub or it still needs more time.", "runnerName", runner.Name)
notRegistered = true
} else if errors.As(err, &offlineException) {
offline = true
} else {
var e *gogithub.RateLimitError
if errors.As(err, &e) {
// We log the underlying error when we failed calling GitHub API to list or unregisters,
// or the runner is still busy.
log.Error(
err,
fmt.Sprintf(
"Failed to check if runner is busy due to GitHub API rate limit. Retrying in %s to avoid excessive GitHub API calls",
retryDelayOnGitHubAPIRateLimitError,
),
)
return ctrl.Result{RequeueAfter: retryDelayOnGitHubAPIRateLimitError}, err
}
return ctrl.Result{}, err
}
registrationTimeout := 15 * time.Minute
currentTime := time.Now()
registrationDidTimeout := currentTime.Sub(runner.CreationTimestamp.Add(registrationTimeout)) > 0
if notRegistered && registrationDidTimeout {
log.Info(
"Runner failed to register itself to GitHub in timely manner. "+
"Marking the runner for scale down. "+
"CAUTION: If you see this a lot, you should investigate the root cause. "+
"See https://github.com/actions-runner-controller/actions-runner-controller/issues/288",
"runnerCreationTimestamp", runner.CreationTimestamp,
"currentTime", currentTime,
"configuredRegistrationTimeout", registrationTimeout,
)
deletionCandidates = append(deletionCandidates, runner)
}
// offline runners should always be a great target for scale down
if offline {
deletionCandidates = append(deletionCandidates, runner)
}
} else if !busy {
deletionCandidates = append(deletionCandidates, runner)
}
}
if len(deletionCandidates) < n {
n = len(deletionCandidates)
}
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
log.V(0).Info(fmt.Sprintf("Deleting %d runner(s)", n), "desired", desired, "current", current, "ready", ready)
for i := 0; i < n; i++ {
if err := r.Client.Delete(ctx, &deletionCandidates[i]); client.IgnoreNotFound(err) != nil {
log.Error(err, "Failed to delete runner resource")
return ctrl.Result{}, err
}
r.Recorder.Event(&rs, corev1.EventTypeNormal, "RunnerDeleted", fmt.Sprintf("Deleted runner '%s'", deletionCandidates[i].Name))
log.Info("Deleted runner")
}
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
} else if desired > current {
n := desired - current
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
log.V(0).Info(fmt.Sprintf("Creating %d runner(s)", n), "desired", desired, "available", current, "ready", ready)
for i := 0; i < n; i++ {
newRunner, err := r.newRunner(rs)
if err != nil {
log.Error(err, "Could not create runner")
return ctrl.Result{}, err
}
if err := r.Client.Create(ctx, &newRunner); err != nil {
log.Error(err, "Failed to create runner resource")
return ctrl.Result{}, err
}
}
}
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
var status v1alpha1.RunnerReplicaSetStatus
status.Replicas = &current
status.AvailableReplicas = &available
status.ReadyReplicas = &ready
if !reflect.DeepEqual(rs.Status, status) {
updated := rs.DeepCopy()
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
updated.Status = status
Fix additionalPrinterColumns (#556) This fixes human-readable output of `kubectl get` on `runnerdeployment`, `runnerreplicaset`, and `runner`. Most notably, CURRENT and READY of runner replicasets are now computed and printed correctly. Runner deployments now have UP-TO-DATE and AVAILABLE instead of READY so that it is consistent with columns of K8s deployments. A few fixes has been also made to runner deployment and runner replicaset controllers so that those numbers stored in Status objects are reliably updated and in-sync with actual values. Finally, `AGE` columns are added to runnerdeployment, runnerreplicaset, runnner to make that more visible to users. `kubectl get` outputs should now look like the below examples: ``` # Immediately after runnerdeployment updated/created $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 0 8d # A few dozens of seconds after update/create all the runners are registered that "available" numbers increase $ k get runnerdeployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-runnerdeploy 0 0 0 0 8d org-runnerdeploy 5 5 5 5 8d ``` ``` $ k get runnerreplicaset NAME DESIRED CURRENT READY AGE example-runnerdeploy-wnpf6 0 0 0 61m org-runnerdeploy-fsnmr 2 2 0 8m41s ``` ``` $ k get runner NAME ENTERPRISE ORGANIZATION REPOSITORY LABELS STATUS AGE example-runnerdeploy-wnpf6-registration-only actions-runner-controller/mumoshu-actions-test Running 61m org-runnerdeploy-fsnmr-n8kkx actions-runner-controller ["mylabel 1","mylabel 2"] 21s org-runnerdeploy-fsnmr-sq6m8 actions-runner-controller ["mylabel 1","mylabel 2"] 21s ``` Fixes #490
2021-05-21 09:10:47 +09:00
if err := r.Status().Patch(ctx, updated, client.MergeFrom(&rs)); err != nil {
log.Info("Failed to update runnerreplicaset status. Retrying immediately", "error", err.Error())
Compact excessive error message on runnerreplicaset status update conflict (#350) We occasionally see logs like the below: ``` 2021-02-24T02:48:26.769ZERRORFailed to update runner status{"runnerreplicaset": "testns-244ol/example-runnerdeploy-j5wzf", "error": "Operation cannot be fulfilled on runnerreplicasets.actions.summerwind.dev \"example-runnerdeploy-j5wzf\": the object has been modified; please apply your changes to the latest version and try again"} github.com/go-logr/zapr.(*zapLogger).Error /home/runner/go/pkg/mod/github.com/go-logr/zapr@v0.1.0/zapr.go:128 github.com/summerwind/actions-runner-controller/controllers.(*RunnerReplicaSetReconciler).Reconcile /home/runner/work/actions-runner-controller/actions-runner-controller/controllers/runnerreplicaset_controller.go:207 sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler /home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/internal/controller/controller.go:256 sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem /home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/internal/controller/controller.go:232 sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker /home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/internal/controller/controller.go:211 k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1 /home/runner/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20190913080033-27d36303b655/pkg/util/wait/wait.go:152 k8s.io/apimachinery/pkg/util/wait.JitterUntil /home/runner/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20190913080033-27d36303b655/pkg/util/wait/wait.go:153 k8s.io/apimachinery/pkg/util/wait.Until /home/runner/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20190913080033-27d36303b655/pkg/util/wait/wait.go:88 2021-02-24T02:48:26.769ZERRORcontroller-runtime.controllerReconciler error{"controller": "testns-244olrunnerreplicaset", "request": "testns-244ol/example-runnerdeploy-j5wzf", "error": "Operation cannot be fulfilled on runnerreplicasets.actions.summerwind.dev \"example-runnerdeploy-j5wzf\": the object has been modified; please apply your changes to the latest version and try again"} github.com/go-logr/zapr.(*zapLogger).Error /home/runner/go/pkg/mod/github.com/go-logr/zapr@v0.1.0/zapr.go:128 sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler /home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/internal/controller/controller.go:258 sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem /home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/internal/controller/controller.go:232 sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker /home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.4.0/pkg/internal/controller/controller.go:211 k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1 /home/runner/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20190913080033-27d36303b655/pkg/util/wait/wait.go:152 k8s.io/apimachinery/pkg/util/wait.JitterUntil /home/runner/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20190913080033-27d36303b655/pkg/util/wait/wait.go:153 k8s.io/apimachinery/pkg/util/wait.Until /home/runner/go/pkg/mod/k8s.io/apimachinery@v0.0.0-20190913080033-27d36303b655/pkg/util/wait/wait.go:88 ``` which can be compacted into one-liner, without the useless stack trace, without double-logging the same error from the logger and the controller.
2021-02-25 09:01:02 +09:00
return ctrl.Result{
Requeue: true,
}, nil
}
}
return ctrl.Result{}, nil
}
func (r *RunnerReplicaSetReconciler) newRunner(rs v1alpha1.RunnerReplicaSet) (v1alpha1.Runner, error) {
objectMeta := rs.Spec.Template.ObjectMeta.DeepCopy()
2020-03-15 21:50:45 +09:00
objectMeta.GenerateName = rs.ObjectMeta.Name + "-"
objectMeta.Namespace = rs.ObjectMeta.Namespace
runner := v1alpha1.Runner{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: *objectMeta,
Spec: rs.Spec.Template.Spec,
}
if err := ctrl.SetControllerReference(&rs, &runner, r.Scheme); err != nil {
return runner, err
}
return runner, nil
}
func (r *RunnerReplicaSetReconciler) SetupWithManager(mgr ctrl.Manager) error {
name := "runnerreplicaset-controller"
if r.Name != "" {
name = r.Name
}
r.Recorder = mgr.GetEventRecorderFor(name)
return ctrl.NewControllerManagedBy(mgr).
For(&v1alpha1.RunnerReplicaSet{}).
Owns(&v1alpha1.Runner{}).
Named(name).
Complete(r)
}
func registrationOnlyRunnerNameFor(rsName string) string {
return rsName + "-registration-only"
}