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

Commit 3dc0733

Browse files
Add function builder support
Signed-off-by: Darren Shepherd <[email protected]>
1 parent 407ca5d commit 3dc0733

20 files changed

+365
-127
lines changed

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ go 1.21.5
55
require (
66
cuelang.org/go v0.6.0
77
github.com/AlecAivazis/survey/v2 v2.3.6
8-
github.com/acorn-io/aml v0.0.0-20240104225813-e936fb3bc7b6
9-
github.com/acorn-io/aml/cli v0.0.0-20231113171943-4844e2f3e1a2
8+
github.com/acorn-io/aml v0.0.0-20240106192317-21afc7320c77
9+
github.com/acorn-io/aml/cli v0.0.0-20240106192317-21afc7320c77
1010
github.com/acorn-io/baaah v0.0.0-20240105013849-c4f82d7a5a41
1111
github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d
12+
github.com/acorn-io/function-builder v0.0.0-20240106051830-f0d368d2382c
1213
github.com/acorn-io/mink v0.0.0-20240105015834-b1f7af4fadea
1314
github.com/acorn-io/namegenerator v0.0.0-20220915160418-9e3d5a0ffe78
1415
github.com/acorn-io/schemer v0.0.0-20240105014212-9739d5485208

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,18 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH
107107
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
108108
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
109109
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
110-
github.com/acorn-io/aml v0.0.0-20240104225813-e936fb3bc7b6 h1:rRaCOn7EkIxkfDZieDbm6HlpUIHIN8DpVZfGMIbohA0=
111-
github.com/acorn-io/aml v0.0.0-20240104225813-e936fb3bc7b6/go.mod h1:z/Tz4f5dWHj/F5THru0+IQBIq31Xq06S5b7YpPkV7K0=
112-
github.com/acorn-io/aml/cli v0.0.0-20231113171943-4844e2f3e1a2 h1:CtflOEPAvtpALuC3SM1WApsfTuECXcDuq25E3fZaPdg=
113-
github.com/acorn-io/aml/cli v0.0.0-20231113171943-4844e2f3e1a2/go.mod h1:D4tWmJlLdsmMbQ/MI4T+Tj4j2PjgTAdde2QDGkeWH20=
110+
github.com/acorn-io/aml v0.0.0-20240106192317-21afc7320c77 h1:MFaoLSKZj1z9c+U7S0GGkS7LXfMeBfQTgGRGVs1HwMg=
111+
github.com/acorn-io/aml v0.0.0-20240106192317-21afc7320c77/go.mod h1:z/Tz4f5dWHj/F5THru0+IQBIq31Xq06S5b7YpPkV7K0=
112+
github.com/acorn-io/aml/cli v0.0.0-20240106192317-21afc7320c77 h1:KdXktTqCv1OlmkFYl7+P11Dh0NDiYnQFblNDdLXPhT4=
113+
github.com/acorn-io/aml/cli v0.0.0-20240106192317-21afc7320c77/go.mod h1:tTw5qUW+S3cAoYepBLFdLNqaRV/DHV3YhHFhB2FzZhE=
114114
github.com/acorn-io/baaah v0.0.0-20240105013849-c4f82d7a5a41 h1:ZzzhWJ2ZP1QQlibd9pll9UTfmitIGReW0x3VNNBg5Qw=
115115
github.com/acorn-io/baaah v0.0.0-20240105013849-c4f82d7a5a41/go.mod h1:13nTO3svO8zTD3j9E5c86tCtK5YrKsK5sxca4Lwkbc0=
116116
github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d h1:hfpNQkJ4I2b8+DbMr8m97gG67ku0uPsMzUfskVu3cHU=
117117
github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d/go.mod h1:WF6FYrEqW0+ZtY5OKb21JhSL0aeL5VJoVrm+u0d4gOE=
118118
github.com/acorn-io/cmd v0.0.0-20230929053520-ebe1b9879b38 h1:oJMGvI702ZW5L0JjJfGV9ekzU2IqqTGjmAQl4gkO6Ro=
119119
github.com/acorn-io/cmd v0.0.0-20230929053520-ebe1b9879b38/go.mod h1:bo9ONX4kagbQmXcG4bnfoK53MBFFtbUZ5fR7s9NfS+M=
120+
github.com/acorn-io/function-builder v0.0.0-20240106051830-f0d368d2382c h1:xfOXFsu5BBsZg6B+xkD4mrP1vacp+WofRTfReSYpS1A=
121+
github.com/acorn-io/function-builder v0.0.0-20240106051830-f0d368d2382c/go.mod h1:yf8qvacJItEV62UVTgNoTTnZHF/1/kqu+eU0CNf9hLw=
120122
github.com/acorn-io/mink v0.0.0-20240105015834-b1f7af4fadea h1:HyH8nh7zZ7qZeWOjBGtK/iAI5gCu/c5iSnN703hlHHY=
121123
github.com/acorn-io/mink v0.0.0-20240105015834-b1f7af4fadea/go.mod h1:EmoDPUYsPyBEhEpSC+LpRGUs2GeSI5nPOTa7WO7jwlc=
122124
github.com/acorn-io/namegenerator v0.0.0-20220915160418-9e3d5a0ffe78 h1:5zs9L/CXNkuTdJSbhFWczAorbmx67nqlqswx5CQi7XI=

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type Build struct {
5050
BaseImage string `json:"baseImage,omitempty"`
5151
ContextDirs map[string]string `json:"contextDirs,omitempty"`
5252
BuildArgs map[string]string `json:"buildArgs,omitempty"`
53+
WatchFiles []string `json:"watchFiles,omitempty"`
5354
}
5455

5556
func (in Build) BaseBuild() Build {
@@ -636,6 +637,7 @@ type Container struct {
636637
Files Files `json:"files,omitempty"`
637638
Image string `json:"image,omitempty"`
638639
Build *Build `json:"build,omitempty"`
640+
Src string `json:"src,omitempty"`
639641
Command CommandSlice `json:"command,omitempty"`
640642
Interactive bool `json:"interactive,omitempty"`
641643
Entrypoint CommandSlice `json:"entrypoint,omitempty"`

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var (
1111
type ContainerImageBuilderSpec struct {
1212
Image string `json:"image,omitempty"`
1313
Build *Build `json:"build,omitempty"`
14+
Src string `json:"src,omitempty"`
1415
// Sidecars is only populated for non-sidecar containers
1516
Sidecars map[string]ContainerImageBuilderSpec `json:"sidecars,omitempty"`
1617
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import (
55
)
66

77
type ContainerData struct {
8-
Image string `json:"image,omitempty"`
9-
Sidecars map[string]ImageData `json:"sidecars,omitempty"`
8+
Image string `json:"image,omitempty"`
9+
Sidecars map[string]ImageData `json:"sidecars,omitempty"`
10+
AcornfileFragment string `json:"acornfileFragment,omitempty"`
1011
}
1112

1213
type ImageData struct {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ func checkForDuplicateNames(in *AppSpec) error {
469469
return nil
470470
}
471471

472-
func addImpliedResources(in *AppSpec) error {
472+
func AddImpliedResources(in *AppSpec) error {
473473
if in.Volumes == nil {
474474
in.Volumes = map[string]VolumeRequest{}
475475
}
@@ -549,7 +549,7 @@ func (in *AppSpec) UnmarshalJSON(data []byte) error {
549549
return err
550550
}
551551

552-
if err := addImpliedResources(in); err != nil {
552+
if err := AddImpliedResources(in); err != nil {
553553
return err
554554
}
555555

pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/appdefinition/acornfile-schema.acorn

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ let types: {
1717
additionalContexts?: StringMap
1818
dockerfile?: string
1919
target?: string
20+
watchFiles: [string]
2021
}
2122

2223
EnvVars: StringArray || StringMap
@@ -60,6 +61,7 @@ let types: {
6061
NameDescription
6162
Metadata
6263

64+
src?: string
6365
match "consumes": string || [string]
6466
match "dirs|directories": {
6567
string: FunctionDir
@@ -211,6 +213,10 @@ let types: {
211213

212214
ContainerBase: {
213215
ContainerCommon
216+
217+
// 1 or both of image or build is required
218+
image?: string
219+
build?: string || Build
214220
match "dirs|directories": {
215221
string: ContainerDir
216222
}
@@ -224,9 +230,6 @@ let types: {
224230
files?: {
225231
string: FileContent
226232
}
227-
// 1 or both of image or build is required
228-
image?: string
229-
build?: string || Build
230233
entrypoint?: string || [string]
231234
match "command|cmd": string || [string]
232235
match "env|environment": EnvVars

pkg/appdefinition/appdefinition.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,39 @@ func (a *AppDefinition) imagesData() (result v1.ImagesData) {
217217
return
218218
}
219219

220+
func getFragment(imagesData v1.ImagesData, imageID string) string {
221+
for _, check := range []map[string]v1.ContainerData{
222+
imagesData.Containers,
223+
imagesData.Functions,
224+
imagesData.Jobs,
225+
} {
226+
for _, imageData := range check {
227+
if imageData.Image == imageID && imageData.AcornfileFragment != "" {
228+
return imageData.AcornfileFragment
229+
}
230+
}
231+
}
232+
return ""
233+
}
234+
235+
func overlayFragment(con *v1.Container, imagesData v1.ImagesData, imageID, serviceName string) error {
236+
fragment := getFragment(imagesData, imageID)
237+
if fragment == "" {
238+
return nil
239+
}
240+
241+
containerData, err := json.Marshal(con)
242+
if err != nil {
243+
return err
244+
}
245+
246+
strData := fmt.Sprintf(`
247+
let serviceName: "%s"
248+
{ %s } + { %s }`, serviceName, containerData, fragment)
249+
250+
return aml.Unmarshal([]byte(strData), con)
251+
}
252+
220253
func (a *AppDefinition) AppSpec() (*v1.AppSpec, error) {
221254
spec := &v1.AppSpec{}
222255
if err := a.decode(spec); err != nil {
@@ -231,6 +264,9 @@ func (a *AppDefinition) AppSpec() (*v1.AppSpec, error) {
231264

232265
for containerName, conSpec := range spec.Containers {
233266
if image, ok := GetImageReferenceForServiceName(containerName, spec, imagesData); ok {
267+
if err := overlayFragment(&conSpec, imagesData, image, containerName); err != nil {
268+
return nil, err
269+
}
234270
conSpec.Image, conSpec.Build = assignImage(conSpec.Image, conSpec.Build, image)
235271
} else {
236272
return nil, fmt.Errorf("failed to find image for container [%s] in Acornfile"+messageSuffix, containerName)
@@ -248,6 +284,9 @@ func (a *AppDefinition) AppSpec() (*v1.AppSpec, error) {
248284

249285
for functionName, conSpec := range spec.Functions {
250286
if image, ok := GetImageReferenceForServiceName(functionName, spec, imagesData); ok {
287+
if err := overlayFragment(&conSpec, imagesData, image, functionName); err != nil {
288+
return nil, err
289+
}
251290
conSpec.Image, conSpec.Build = assignImage(conSpec.Image, conSpec.Build, image)
252291
} else {
253292
return nil, fmt.Errorf("failed to find image for function [%s] in Acornfile"+messageSuffix, functionName)
@@ -265,6 +304,9 @@ func (a *AppDefinition) AppSpec() (*v1.AppSpec, error) {
265304

266305
for containerName, conSpec := range spec.Jobs {
267306
if image, ok := GetImageReferenceForServiceName(containerName, spec, imagesData); ok {
307+
if err := overlayFragment(&conSpec, imagesData, image, containerName); err != nil {
308+
return nil, err
309+
}
268310
conSpec.Image, conSpec.Build = assignImage(conSpec.Image, conSpec.Build, image)
269311
} else {
270312
return nil, fmt.Errorf("failed to find image for job [%s] in Acornfile"+messageSuffix, containerName)
@@ -314,7 +356,7 @@ func (a *AppDefinition) AppSpec() (*v1.AppSpec, error) {
314356
spec.Services[serviceName] = serviceSpec
315357
}
316358

317-
return spec, nil
359+
return spec, v1.AddImpliedResources(spec)
318360
}
319361

320362
func addContainerFiles(fileSet map[string]bool, builds map[string]v1.ContainerImageBuilderSpec, cwd string) {

pkg/appdefinition/appdefinition_test.go

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,87 +1090,65 @@ images: {
10901090
t.Fatal(err)
10911091
}
10921092

1093-
assert.Equal(t, &v1.BuilderSpec{
1093+
autogold.Expect(&v1.BuilderSpec{
10941094
Containers: map[string]v1.ContainerImageBuilderSpec{
1095-
"image": {
1096-
Image: "image-image",
1097-
Sidecars: map[string]v1.ContainerImageBuilderSpec{
1098-
"side": {
1099-
Image: "image-image-side",
1100-
},
1101-
},
1102-
},
11031095
"build": {
11041096
Build: &v1.Build{
11051097
Context: ".",
11061098
Dockerfile: "Dockerfile",
1099+
WatchFiles: []string{},
11071100
},
1108-
Sidecars: map[string]v1.ContainerImageBuilderSpec{
1109-
"side": {
1110-
Build: &v1.Build{
1111-
Context: ".",
1112-
Dockerfile: "Dockerfile",
1113-
},
1114-
},
1115-
},
1101+
Sidecars: map[string]v1.ContainerImageBuilderSpec{"side": {Build: &v1.Build{
1102+
Context: ".",
1103+
Dockerfile: "Dockerfile",
1104+
WatchFiles: []string{},
1105+
}}},
11161106
},
11171107
"buildcontext": {
11181108
Build: &v1.Build{
1119-
Context: ".",
1120-
Dockerfile: "Dockerfile",
1121-
ContextDirs: map[string]string{
1122-
"/var/tmp": "./foo/bar",
1123-
},
1124-
},
1125-
Sidecars: map[string]v1.ContainerImageBuilderSpec{
1126-
"side": {
1127-
Build: &v1.Build{
1128-
Context: ".",
1129-
Dockerfile: "Dockerfile",
1130-
ContextDirs: map[string]string{
1131-
"/var/tmp": "./foo/bar",
1132-
},
1133-
},
1134-
},
1109+
Context: ".",
1110+
Dockerfile: "Dockerfile",
1111+
ContextDirs: map[string]string{"/var/tmp": "./foo/bar"},
1112+
WatchFiles: []string{},
11351113
},
1114+
Sidecars: map[string]v1.ContainerImageBuilderSpec{"side": {Build: &v1.Build{
1115+
Context: ".",
1116+
Dockerfile: "Dockerfile",
1117+
ContextDirs: map[string]string{"/var/tmp": "./foo/bar"},
1118+
WatchFiles: []string{},
1119+
}}},
1120+
},
1121+
"image": {
1122+
Image: "image-image",
1123+
Sidecars: map[string]v1.ContainerImageBuilderSpec{"side": {Image: "image-image-side"}},
11361124
},
11371125
"imagecontext": {
11381126
Image: "imagecontext-image",
11391127
Build: &v1.Build{
1140-
BaseImage: "imagecontext-image",
1141-
Context: ".",
1142-
Dockerfile: "Dockerfile",
1143-
ContextDirs: map[string]string{
1144-
"/var/tmp": "./foo/bar",
1145-
},
1128+
Context: ".",
1129+
Dockerfile: "Dockerfile",
1130+
BaseImage: "imagecontext-image",
1131+
ContextDirs: map[string]string{"/var/tmp": "./foo/bar"},
11461132
},
1147-
Sidecars: map[string]v1.ContainerImageBuilderSpec{
1148-
"side": {
1149-
Image: "imagecontext-image-side",
1150-
Build: &v1.Build{
1151-
BaseImage: "imagecontext-image-side",
1152-
Context: ".",
1153-
Dockerfile: "Dockerfile",
1154-
ContextDirs: map[string]string{
1155-
"/var/tmp": "./foo/bar",
1156-
},
1157-
},
1133+
Sidecars: map[string]v1.ContainerImageBuilderSpec{"side": {
1134+
Image: "imagecontext-image-side",
1135+
Build: &v1.Build{
1136+
Context: ".",
1137+
Dockerfile: "Dockerfile",
1138+
BaseImage: "imagecontext-image-side",
1139+
ContextDirs: map[string]string{"/var/tmp": "./foo/bar"},
11581140
},
1159-
},
1141+
}},
11601142
},
11611143
},
11621144
Images: map[string]v1.ImageBuilderSpec{
1163-
"ibuild": {
1164-
AcornBuild: &v1.AcornBuild{
1165-
Context: ".",
1166-
Acornfile: "Acornfile",
1167-
},
1168-
},
1169-
"iimage": {
1170-
Image: "images-image-image",
1171-
},
1145+
"ibuild": {AcornBuild: &v1.AcornBuild{
1146+
Context: ".",
1147+
Acornfile: "Acornfile",
1148+
}},
1149+
"iimage": {Image: "images-image-image"},
11721150
},
1173-
}, buildSpec)
1151+
}).Equal(t, buildSpec)
11741152

11751153
app := appImage.WithImageData(v1.ImagesData{
11761154
Containers: map[string]v1.ContainerData{
@@ -3039,7 +3017,7 @@ func TestNestedScopedLabels(t *testing.T) {
30393017

30403018
func TestFunction(t *testing.T) {
30413019
appImage, err := NewAppDefinition([]byte(`functions: foo: {
3042-
image: "foo:latest"
3020+
src: "somewhere"
30433021
}`))
30443022
if err != nil {
30453023
t.Fatal(err)
@@ -3052,11 +3030,11 @@ func TestFunction(t *testing.T) {
30523030
}
30533031

30543032
autogold.Expect(v1.Container{
3055-
Image: "foo:latest",
3033+
Src: "somewhere",
30563034
}).Equal(t, appSpec.Functions["foo"])
30573035

30583036
_, err = NewAppDefinition([]byte(`functions: foo: {
3059-
image: "foo:latest"
3037+
src: "somewhere"
30603038
}
30613039
containers: foo: {
30623040
image: "foo:latest"

pkg/build/assemble.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ func digestOnlyContainers(data map[string]v1.ContainerData) (map[string]v1.Conta
4545
return nil, err
4646
}
4747
result[k] = v1.ContainerData{
48-
Image: t.DigestStr(),
49-
Sidecars: sidecars,
48+
Image: t.DigestStr(),
49+
AcornfileFragment: v.AcornfileFragment,
50+
Sidecars: sidecars,
5051
}
5152
}
5253
if len(result) == 0 {

0 commit comments

Comments
 (0)