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

Commit 3964bbc

Browse files
authored
fix: remove resolvedOfferings, defaults, and scheduling for containers not defined in app (#2468)
Signed-off-by: Grant Linville <grant@acorn.io>
1 parent 9761944 commit 3964bbc

File tree

22 files changed

+649
-0
lines changed

22 files changed

+649
-0
lines changed

pkg/apis/internal.acorn.io/v1/appinstance.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package v1
55
import (
66
"strings"
77

8+
"golang.org/x/exp/maps"
9+
"golang.org/x/exp/slices"
810
corev1 "k8s.io/api/core/v1"
911
"k8s.io/apimachinery/pkg/api/resource"
1012
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -122,6 +124,19 @@ func (in *AppInstance) GetStopped() bool {
122124
return in.Spec.Stop != nil && *in.Spec.Stop && in.DeletionTimestamp.IsZero()
123125
}
124126

127+
// GetAllContainerNames returns a string slice containing the name of every container, job, and sidecar defined in Status.AppSpec.
128+
func (in *AppInstance) GetAllContainerNames() []string {
129+
allContainers := append(maps.Keys(in.Status.AppSpec.Containers), maps.Keys(in.Status.AppSpec.Jobs)...)
130+
for _, container := range in.Status.AppSpec.Containers {
131+
allContainers = append(allContainers, maps.Keys(container.Sidecars)...)
132+
}
133+
for _, job := range in.Status.AppSpec.Jobs {
134+
allContainers = append(allContainers, maps.Keys(job.Sidecars)...)
135+
}
136+
slices.Sort[[]string](allContainers)
137+
return allContainers
138+
}
139+
125140
func (in *AppInstanceSpec) GetAutoUpgrade() bool {
126141
return in.AutoUpgrade != nil && *in.AutoUpgrade
127142
}

pkg/controller/defaults/memory.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
adminv1 "github.com/acorn-io/runtime/pkg/apis/internal.admin.acorn.io/v1"
88
"github.com/acorn-io/runtime/pkg/computeclasses"
99
apierrors "k8s.io/apimachinery/pkg/api/errors"
10+
"k8s.io/utils/strings/slices"
1011
)
1112

1213
// defaultMemory calculates the default that should be used and considers the defaults from the Config, ComputeClass, and
@@ -54,6 +55,17 @@ func addDefaultMemory(req router.Request, cfg *apiv1.Config, appInstance *v1.App
5455
return err
5556
}
5657

58+
// Remove any memory defaults for containers that are no longer defined in the app.
59+
allContainers := appInstance.GetAllContainerNames()
60+
for containerName := range appInstance.Status.Defaults.Memory {
61+
if containerName == "" {
62+
continue
63+
}
64+
if !slices.Contains(allContainers, containerName) {
65+
delete(appInstance.Status.Defaults.Memory, containerName)
66+
}
67+
}
68+
5769
return nil
5870
}
5971

pkg/controller/defaults/memory_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,7 @@ func TestTwoPCCDefaultsShouldError(t *testing.T) {
7272

7373
assert.True(t, resp.NoPrune, "NoPrune should be true when error occurs")
7474
}
75+
76+
func TestRemovedContainer(t *testing.T) {
77+
tester.DefaultTest(t, scheme.Scheme, "testdata/memory/removed-container", Calculate)
78+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
kind: ProjectInstance
2+
apiVersion: internal.acorn.io/v1
3+
metadata:
4+
name: app-namespace
5+
spec: {}
6+
status:
7+
defaultRegion: local
8+
supportedRegions:
9+
- local
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
`apiVersion: internal.acorn.io/v1
2+
kind: AppInstance
3+
metadata:
4+
creationTimestamp: null
5+
name: app-name
6+
namespace: app-namespace
7+
uid: 1234567890abcdef
8+
spec:
9+
image: test
10+
memory:
11+
oneimage: 1048576
12+
status:
13+
appImage:
14+
buildContext: {}
15+
id: test
16+
imageData: {}
17+
vcs: {}
18+
appSpec:
19+
containers:
20+
oneimage:
21+
build:
22+
context: .
23+
dockerfile: Dockerfile
24+
image: image-name
25+
metrics: {}
26+
ports:
27+
- port: 80
28+
protocol: http
29+
targetPort: 81
30+
probes: null
31+
sidecars:
32+
left:
33+
image: foo
34+
metrics: {}
35+
ports:
36+
- port: 90
37+
protocol: tcp
38+
targetPort: 91
39+
probes: null
40+
appStatus: {}
41+
columns: {}
42+
conditions:
43+
reason: Success
44+
status: "True"
45+
success: true
46+
type: defaults
47+
defaults:
48+
memory:
49+
"": 0
50+
left: 0
51+
oneimage: 0
52+
region: local
53+
namespace: app-created-namespace
54+
observedGeneration: 1
55+
resolvedOfferings: {}
56+
staged:
57+
appImage:
58+
buildContext: {}
59+
imageData: {}
60+
vcs: {}
61+
summary: {}
62+
`
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
kind: AppInstance
2+
apiVersion: internal.acorn.io/v1
3+
metadata:
4+
name: app-name
5+
namespace: app-namespace
6+
uid: 1234567890abcdef
7+
spec:
8+
image: test
9+
memory:
10+
oneimage: 1048576 # 1Mi
11+
status:
12+
observedGeneration: 1
13+
namespace: app-created-namespace
14+
appImage:
15+
id: test
16+
appSpec:
17+
containers:
18+
oneimage:
19+
sidecars:
20+
left:
21+
image: "foo"
22+
ports:
23+
- port: 90
24+
targetPort: 91
25+
protocol: tcp
26+
ports:
27+
- port: 80
28+
targetPort: 81
29+
protocol: http
30+
image: "image-name"
31+
build:
32+
dockerfile: "Dockerfile"
33+
context: "."
34+
defaults:
35+
memory:
36+
twoimage: 0

pkg/controller/resolvedofferings/computeclass.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
adminv1 "github.com/acorn-io/runtime/pkg/apis/internal.admin.acorn.io/v1"
88
"github.com/acorn-io/runtime/pkg/computeclasses"
99
apierrors "k8s.io/apimachinery/pkg/api/errors"
10+
"k8s.io/utils/strings/slices"
1011
)
1112

1213
// resolveComputeClasses resolves the compute class information for each container in the AppInstance
@@ -69,6 +70,17 @@ func resolveComputeClasses(req router.Request, cfg *apiv1.Config, appInstance *v
6970
return err
7071
}
7172

73+
// Remove any resolved offerings for containers that are no longer defined in the app.
74+
allContainers := appInstance.GetAllContainerNames()
75+
for containerName := range appInstance.Status.ResolvedOfferings.Containers {
76+
if containerName == "" {
77+
continue
78+
}
79+
if !slices.Contains(allContainers, containerName) {
80+
delete(appInstance.Status.ResolvedOfferings.Containers, containerName)
81+
}
82+
}
83+
7284
return nil
7385
}
7486

pkg/controller/resolvedofferings/computeclass_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,7 @@ func TestUserOverrideComputeClass(t *testing.T) {
8888
func TestWithAcornfileMemoryAndSpecOverride(t *testing.T) {
8989
tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/with-acornfile-memory-and-spec-override", Calculate)
9090
}
91+
92+
func TestRemovedContainer(t *testing.T) {
93+
tester.DefaultTest(t, scheme.Scheme, "testdata/computeclass/removed-container", Calculate)
94+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
kind: ProjectInstance
2+
apiVersion: internal.acorn.io/v1
3+
metadata:
4+
name: app-namespace
5+
spec: {}
6+
status:
7+
defaultRegion: local
8+
supportedRegions:
9+
- local
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
`apiVersion: internal.acorn.io/v1
2+
kind: AppInstance
3+
metadata:
4+
creationTimestamp: null
5+
name: app-name
6+
namespace: app-namespace
7+
uid: 1234567890abcdef
8+
spec:
9+
image: test
10+
memory:
11+
oneimage: 1048576
12+
status:
13+
appImage:
14+
buildContext: {}
15+
id: test
16+
imageData: {}
17+
vcs: {}
18+
appSpec:
19+
containers:
20+
oneimage:
21+
build:
22+
context: .
23+
dockerfile: Dockerfile
24+
image: image-name
25+
metrics: {}
26+
ports:
27+
- port: 80
28+
protocol: http
29+
targetPort: 81
30+
probes: null
31+
sidecars:
32+
left:
33+
image: foo
34+
metrics: {}
35+
ports:
36+
- port: 90
37+
protocol: tcp
38+
targetPort: 91
39+
probes: null
40+
appStatus: {}
41+
columns: {}
42+
conditions:
43+
reason: Success
44+
status: "True"
45+
success: true
46+
type: resolved-offerings
47+
defaults: {}
48+
namespace: app-created-namespace
49+
observedGeneration: 1
50+
resolvedOfferings:
51+
containers:
52+
"":
53+
memory: 0
54+
left:
55+
memory: 0
56+
oneimage:
57+
memory: 1048576
58+
region: local
59+
staged:
60+
appImage:
61+
buildContext: {}
62+
imageData: {}
63+
vcs: {}
64+
summary: {}
65+
`

0 commit comments

Comments
 (0)