Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Commit

Permalink
Allow acorn rm --ignore-cleanup on services (#1795) (#1878)
Browse files Browse the repository at this point in the history
Signed-off-by: Grant Linville <grant@acorn.io>
  • Loading branch information
g-linville committed Jul 3, 2023
1 parent 1ec7bd7 commit 6aae4d0
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 4 deletions.
56 changes: 54 additions & 2 deletions integration/services/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package services

import (
"testing"
"time"

"github.com/acorn-io/runtime/integration/helper"
apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
"github.com/acorn-io/runtime/pkg/client"
"github.com/stretchr/testify/assert"
)

func TestServices(t *testing.T) {
Expand All @@ -14,8 +16,8 @@ func TestServices(t *testing.T) {
ctx := helper.GetCTX(t)
c, _ := helper.ClientAndNamespace(t)

image, err := c.AcornImageBuild(ctx, "./testdata/Acornfile", &client.AcornImageBuildOptions{
Cwd: "./testdata",
image, err := c.AcornImageBuild(ctx, "./testdata/main/Acornfile", &client.AcornImageBuildOptions{
Cwd: "./testdata/main",
})
if err != nil {
t.Fatal(err)
Expand All @@ -35,3 +37,53 @@ func TestServices(t *testing.T) {
return obj.Status.AppStatus.Jobs["test"].Ready
})
}

func TestServiceIgnoreCleanup(t *testing.T) {
helper.StartController(t)

ctx := helper.GetCTX(t)
c, _ := helper.ClientAndNamespace(t)

image, err := c.AcornImageBuild(ctx, "./testdata/ignorecleanup/Acornfile", &client.AcornImageBuildOptions{
Cwd: "./testdata/ignorecleanup",
})
if err != nil {
t.Fatal(err)
}

_, err = c.AppRun(ctx, image.ID, &client.AppRunOptions{Name: "myapp"})
if err != nil {
t.Fatal(err)
}

// Sleep for 1 second to give the controller time to create the service.
time.Sleep(1 * time.Second)

// Delete the app.
if _, err := c.AppDelete(ctx, "myapp"); err != nil {
t.Fatal(err)
}

// This app's service has a delete event job that will fail to run.
// Make sure it still shows up in the app list.
list, err := c.AppList(ctx)
if err != nil {
t.Fatal(err)
}

assert.Len(t, list, 1)
assert.Equal(t, "myapp.myservice", list[0].Name)

// Delete it next.
if err := c.AppIgnoreDeleteCleanup(ctx, "myapp.myservice"); err != nil {
t.Fatal(err)
}

// Make sure there are no apps remaining.
list, err = c.AppList(ctx)
if err != nil {
t.Fatal(err)
}

assert.Len(t, list, 0)
}
3 changes: 3 additions & 0 deletions integration/services/testdata/ignorecleanup/Acornfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
services: myservice: build: "./service"

containers: nginx: image: "ghcr.io/acorn-io/images-mirror/nginx:latest"
16 changes: 16 additions & 0 deletions integration/services/testdata/ignorecleanup/service/Acornfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
containers: "never-ready": {
image: "ghcr.io/acorn-io/images-mirror/nginx:latest"
probes: readiness: tcp: url: "tcp://localhost:5555"
}

jobs: "fail-on-delete": {
image: "ghcr.io/acorn-io/images-mirror/nginx:latest"
events: ["delete"]
entrypoint: ["/script.sh"]
files: "/script.sh": """
#!/bin/sh
echo Starting
sleep 3
dne
"""
}
36 changes: 34 additions & 2 deletions pkg/server/registry/apigroups/acorn/apps/ignorecleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ package apps
import (
"context"
"fmt"
"strings"

"github.com/acorn-io/mink/pkg/stores"
"github.com/acorn-io/mink/pkg/types"
apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1"
"github.com/acorn-io/runtime/pkg/controller/jobs"
kclient "github.com/acorn-io/runtime/pkg/k8sclient"
"github.com/acorn-io/runtime/pkg/labels"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/utils/strings/slices"
Expand All @@ -20,7 +26,21 @@ func NewIgnoreCleanup(c client.WithWatch) rest.Storage {
return stores.NewBuilder(c.Scheme(), &apiv1.IgnoreCleanup{}).
WithCreate(&ignoreCleanupStrategy{
client: c,
}).Build()
}).
WithValidateName(ignoreCleanupValidator{}).
Build()
}

type ignoreCleanupValidator struct{}

func (s ignoreCleanupValidator) ValidateName(ctx context.Context, _ runtime.Object) (result field.ErrorList) {
ri, _ := request.RequestInfoFrom(ctx)
for _, piece := range strings.Split(ri.Name, ".") {
if errs := validation.IsDNS1035Label(piece); len(errs) > 0 {
result = append(result, field.Invalid(field.NewPath("metadata", "name"), ri.Name, strings.Join(errs, ",")))
}
}
return
}

type ignoreCleanupStrategy struct {
Expand All @@ -38,7 +58,19 @@ func (s *ignoreCleanupStrategy) Create(ctx context.Context, obj types.Object) (t
// The app validation logic should not run there.
app := &v1.AppInstance{}
err := s.client.Get(ctx, kclient.ObjectKey{Namespace: ri.Namespace, Name: ri.Name}, app)
if err != nil {
if err != nil && apierrors.IsNotFound(err) {
// See if this is a public name
appList := &v1.AppInstanceList{}
listErr := s.client.List(ctx, appList, client.MatchingLabels{labels.AcornPublicName: ri.Name}, client.InNamespace(ri.Namespace))
if listErr != nil {
return nil, listErr
}
if len(appList.Items) != 1 {
// return the NotFound error we got originally
return nil, err
}
app = &appList.Items[0]
} else if err != nil {
return nil, err
}

Expand Down

0 comments on commit 6aae4d0

Please sign in to comment.