Implement finalizer
This commit is contained in:
parent
497ddba82d
commit
a436216d5e
|
|
@ -38,9 +38,17 @@ import (
|
|||
|
||||
const (
|
||||
containerName = "runner"
|
||||
finalizerName = "runner.actions.summerwind.dev"
|
||||
)
|
||||
|
||||
type RegistrationToken struct {
|
||||
type GitHubRunner struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
OS string `json:"os"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type GitHubRegistrationToken struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt string `json:"expires_at"`
|
||||
}
|
||||
|
|
@ -69,6 +77,48 @@ func (r *RunnerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
if runner.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
finalizers, added := addFinalizer(runner.ObjectMeta.Finalizers)
|
||||
|
||||
if added {
|
||||
newRunner := runner.DeepCopy()
|
||||
newRunner.ObjectMeta.Finalizers = finalizers
|
||||
|
||||
if err := r.Update(ctx, newRunner); err != nil {
|
||||
log.Error(err, "Failed to update runner")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
} else {
|
||||
finalizers, removed := removeFinalizer(runner.ObjectMeta.Finalizers)
|
||||
|
||||
if removed {
|
||||
ok, err := r.unregisterRunner(ctx, runner.Spec.Repository, runner.Name)
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to unregister runner")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
log.V(1).Info("Runner no longer exists on GitHub")
|
||||
}
|
||||
|
||||
newRunner := runner.DeepCopy()
|
||||
newRunner.ObjectMeta.Finalizers = finalizers
|
||||
|
||||
if err := r.Update(ctx, newRunner); err != nil {
|
||||
log.Error(err, "Failed to update runner")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
log.Info("Removed runner from GitHub", "repository", runner.Spec.Repository)
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
if !runner.IsRegisterable() {
|
||||
reg, err := r.newRegistration(ctx, runner.Spec.Repository)
|
||||
if err != nil {
|
||||
|
|
@ -190,8 +240,8 @@ func (r *RunnerReconciler) newRegistration(ctx context.Context, repo string) (v1
|
|||
return reg, err
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) getRegistrationToken(ctx context.Context, repo string) (RegistrationToken, error) {
|
||||
var regToken RegistrationToken
|
||||
func (r *RunnerReconciler) getRegistrationToken(ctx context.Context, repo string) (GitHubRegistrationToken, error) {
|
||||
var regToken GitHubRegistrationToken
|
||||
|
||||
req, err := r.GitHubClient.NewRequest("POST", fmt.Sprintf("/repos/%s/actions/runners/registration-token", repo), nil)
|
||||
if err != nil {
|
||||
|
|
@ -210,6 +260,69 @@ func (r *RunnerReconciler) getRegistrationToken(ctx context.Context, repo string
|
|||
return regToken, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) unregisterRunner(ctx context.Context, repo, name string) (bool, error) {
|
||||
runners, err := r.listRunners(ctx, repo)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
id := 0
|
||||
for _, runner := range runners {
|
||||
if runner.Name == name {
|
||||
id = runner.ID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if id == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := r.removeRunner(ctx, repo, id); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) listRunners(ctx context.Context, repo string) ([]GitHubRunner, error) {
|
||||
runners := []GitHubRunner{}
|
||||
|
||||
req, err := r.GitHubClient.NewRequest("GET", fmt.Sprintf("/repos/%s/actions/runners", repo), nil)
|
||||
if err != nil {
|
||||
return runners, err
|
||||
}
|
||||
|
||||
res, err := r.GitHubClient.Do(ctx, req, &runners)
|
||||
if err != nil {
|
||||
return runners, err
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
return runners, fmt.Errorf("unexpected status: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
return runners, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) removeRunner(ctx context.Context, repo string, id int) error {
|
||||
req, err := r.GitHubClient.NewRequest("DELETE", fmt.Sprintf("/repos/%s/actions/runners/%d", repo, id), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := r.GitHubClient.Do(ctx, req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res.StatusCode != 204 {
|
||||
return fmt.Errorf("unexpected status: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
||||
var (
|
||||
privileged bool = true
|
||||
|
|
@ -297,3 +410,33 @@ func (r *RunnerReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
|||
Owns(&corev1.Pod{}).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
func addFinalizer(finalizers []string) ([]string, bool) {
|
||||
exists := false
|
||||
for _, name := range finalizers {
|
||||
if name == finalizerName {
|
||||
exists = true
|
||||
}
|
||||
}
|
||||
|
||||
if exists {
|
||||
return finalizers, false
|
||||
}
|
||||
|
||||
return append(finalizers, finalizerName), true
|
||||
}
|
||||
|
||||
func removeFinalizer(finalizers []string) ([]string, bool) {
|
||||
removed := false
|
||||
result := []string{}
|
||||
|
||||
for _, name := range finalizers {
|
||||
if name == finalizerName {
|
||||
removed = true
|
||||
continue
|
||||
}
|
||||
result = append(result, name)
|
||||
}
|
||||
|
||||
return result, removed
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue