Skip to content

Commit 0cc96f4

Browse files
pbuskomodulo11nicolasbenderc0d1ngm0nk3ya-b
authored
[RFC0028] Support for Cloud Native Buildpacks lifecycle (#2871)
Co-authored-by: Johannes Dillmann <[email protected]> Co-authored-by: Nicolas Bender <[email protected]> Co-authored-by: Pavel Busko <[email protected]> Co-authored-by: Ralf Pannemans <[email protected]> Co-authored-by: Al Berez <[email protected]> Co-authored-by: João Pereira <[email protected]>
1 parent 301073b commit 0cc96f4

37 files changed

+857
-222
lines changed

.github/workflows/tests-integration-reusable.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ jobs:
207207
"include_container_networking": true,
208208
"include_detect": true,
209209
"include_docker": true,
210+
"include_cnb": true,
210211
"include_internet_dependent": true,
211212
"include_isolation_segments": true,
212213
"isolation_segment_name": "persistent_isolation_segment",
@@ -237,6 +238,7 @@ jobs:
237238
cf api ${API} --skip-ssl-validation
238239
cf auth
239240
cf enable-feature-flag diego_docker
241+
cf enable-feature-flag diego_cnb
240242
cf enable-feature-flag service_instance_sharing
241243
242244
- name: Run CATS Tests

actor/v7action/application.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ func (actor Actor) CreateApplicationInSpace(app resources.Application, spaceGUID
162162
LifecycleBuildpacks: app.LifecycleBuildpacks,
163163
StackName: app.StackName,
164164
Name: app.Name,
165+
Credentials: app.Credentials,
165166
SpaceGUID: spaceGUID,
166167
})
167168

actor/v7pushaction/actor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ func NewActor(v3Actor V7Actor, sharedActor SharedActor) *Actor {
4242

4343
HandleInstancesOverride,
4444
HandleStartCommandOverride,
45+
HandleCNBCredentialsOverride,
46+
47+
HandleLifecycleOverride,
4548

4649
// Type must come before endpoint because endpoint validates against type
4750
HandleHealthCheckTypeOverride,

actor/v7pushaction/create_push_plans.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ func (actor Actor) CreatePushPlans(
3131
BitsPath: manifestApplication.Path,
3232
}
3333

34+
if manifestApplication.Lifecycle != "" {
35+
plan.Application.LifecycleType = manifestApplication.Lifecycle
36+
}
37+
38+
if overrides.Lifecycle != "" {
39+
plan.Application.LifecycleType = overrides.Lifecycle
40+
}
41+
42+
if overrides.CNBCredentials != nil {
43+
plan.Application.Credentials = overrides.CNBCredentials
44+
}
45+
3446
if manifestApplication.Docker != nil {
3547
plan.DockerImageCredentials = v7action.DockerImageCredentials{
3648
Path: manifestApplication.Docker.Image,

actor/v7pushaction/create_push_plans_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,17 @@ var _ = Describe("CreatePushPlans", func() {
4141

4242
manifest = manifestparser.Manifest{
4343
Applications: []manifestparser.Application{
44-
{Name: "name-1", Path: "path1"},
44+
{Name: "name-1", Path: "path1", Lifecycle: "cnb"},
4545
{Name: "name-2", Path: "path2", Docker: &manifestparser.Docker{Image: "image", Username: "uname"}},
4646
},
4747
}
4848
orgGUID = "org"
4949
spaceGUID = "space"
5050
flagOverrides = FlagOverrides{
5151
DockerPassword: "passwd",
52+
CNBCredentials: map[string]interface{}{
53+
"foo": "bar",
54+
},
5255
}
5356

5457
testUpdatePlanCount = 0
@@ -120,6 +123,10 @@ var _ = Describe("CreatePushPlans", func() {
120123
Expect(pushPlans[0].DockerImageCredentials.Username).To(Equal(""))
121124
Expect(pushPlans[0].DockerImageCredentials.Password).To(Equal(""))
122125
Expect(pushPlans[0].BitsPath).To(Equal("path1"))
126+
Expect(pushPlans[0].Application.LifecycleType).To(BeEquivalentTo("cnb"))
127+
Expect(pushPlans[0].Application.Credentials).To(Equal(map[string]interface{}{
128+
"foo": "bar",
129+
}))
123130
Expect(pushPlans[1].Application.Name).To(Equal("name-2"))
124131
Expect(pushPlans[1].Application.GUID).To(Equal("app-guid-2"))
125132
Expect(pushPlans[1].SpaceGUID).To(Equal(spaceGUID))
@@ -128,7 +135,20 @@ var _ = Describe("CreatePushPlans", func() {
128135
Expect(pushPlans[1].DockerImageCredentials.Username).To(Equal("uname"))
129136
Expect(pushPlans[1].DockerImageCredentials.Password).To(Equal("passwd"))
130137
Expect(pushPlans[1].BitsPath).To(Equal("path2"))
138+
Expect(pushPlans[1].Application.LifecycleType).To(BeEquivalentTo(""))
131139
})
140+
})
132141

142+
When("lifecycle is overwritten", func() {
143+
BeforeEach(func() {
144+
flagOverrides = FlagOverrides{
145+
Lifecycle: "buildpack",
146+
}
147+
})
148+
149+
It("uses the lifecycle from the command line", func() {
150+
Expect(pushPlans[0].Application.LifecycleType).To(BeEquivalentTo("buildpack"))
151+
})
133152
})
153+
134154
})
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package v7pushaction
2+
3+
import (
4+
"code.cloudfoundry.org/cli/command/translatableerror"
5+
"code.cloudfoundry.org/cli/util/manifestparser"
6+
)
7+
8+
func HandleCNBCredentialsOverride(manifest manifestparser.Manifest, overrides FlagOverrides) (manifestparser.Manifest, error) {
9+
if overrides.CNBCredentials != nil {
10+
if manifest.ContainsMultipleApps() {
11+
return manifest, translatableerror.CommandLineArgsWithMultipleAppsError{}
12+
}
13+
14+
app := manifest.GetFirstApp()
15+
if app.RemainingManifestFields == nil {
16+
app.RemainingManifestFields = map[string]interface{}{}
17+
}
18+
19+
app.RemainingManifestFields["cnb-credentials"] = overrides.CNBCredentials
20+
}
21+
22+
return manifest, nil
23+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package v7pushaction_test
2+
3+
import (
4+
. "code.cloudfoundry.org/cli/actor/v7pushaction"
5+
"code.cloudfoundry.org/cli/util/manifestparser"
6+
7+
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
)
10+
11+
var _ = Describe("HandleCNBCredentialsOverride", func() {
12+
var (
13+
originalManifest manifestparser.Manifest
14+
transformedManifest manifestparser.Manifest
15+
overrides FlagOverrides
16+
executeErr error
17+
)
18+
19+
BeforeEach(func() {
20+
originalManifest = manifestparser.Manifest{
21+
Applications: []manifestparser.Application{{}},
22+
}
23+
overrides = FlagOverrides{}
24+
})
25+
26+
JustBeforeEach(func() {
27+
transformedManifest, executeErr = HandleCNBCredentialsOverride(originalManifest, overrides)
28+
})
29+
30+
When("the cnb credentials are present", func() {
31+
BeforeEach(func() {
32+
overrides.CNBCredentials = map[string]interface{}{
33+
"foo": "bar",
34+
}
35+
})
36+
37+
It("add it to the raw manifest", func() {
38+
Expect(executeErr).NotTo(HaveOccurred())
39+
Expect(transformedManifest).To(Equal(manifestparser.Manifest{
40+
Applications: []manifestparser.Application{{
41+
RemainingManifestFields: map[string]interface{}{
42+
"cnb-credentials": map[string]interface{}{
43+
"foo": "bar",
44+
},
45+
},
46+
}},
47+
}))
48+
})
49+
50+
})
51+
52+
When("the credentials are not present", func() {
53+
BeforeEach(func() {
54+
overrides.CNBCredentials = nil
55+
})
56+
57+
It("does not add it to the raw manifest", func() {
58+
Expect(executeErr).NotTo(HaveOccurred())
59+
Expect(transformedManifest).To(Equal(manifestparser.Manifest{
60+
Applications: []manifestparser.Application{{}},
61+
}))
62+
63+
})
64+
65+
})
66+
})
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package v7pushaction
2+
3+
import (
4+
"code.cloudfoundry.org/cli/command/translatableerror"
5+
"code.cloudfoundry.org/cli/util/manifestparser"
6+
)
7+
8+
func HandleLifecycleOverride(manifest manifestparser.Manifest, overrides FlagOverrides) (manifestparser.Manifest, error) {
9+
if overrides.Lifecycle != "" {
10+
if manifest.ContainsMultipleApps() {
11+
return manifest, translatableerror.CommandLineArgsWithMultipleAppsError{}
12+
}
13+
14+
app := manifest.GetFirstApp()
15+
app.Lifecycle = overrides.Lifecycle
16+
}
17+
18+
return manifest, nil
19+
}

actor/v7pushaction/push_plan.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type FlagOverrides struct {
4343
DockerImage string
4444
DockerPassword string
4545
DockerUsername string
46+
CNBCredentials map[string]interface{}
4647
HealthCheckEndpoint string
4748
HealthCheckTimeout int64
4849
HealthCheckType constant.HealthCheckType
@@ -62,6 +63,7 @@ type FlagOverrides struct {
6263
NoManifest bool
6364
Task bool
6465
LogRateLimit string
66+
Lifecycle constant.AppLifecycleType
6567
}
6668

6769
func (state PushPlan) String() string {

api/cloudcontroller/ccv3/application_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@ var _ = Describe("Application", func() {
9696
})
9797
})
9898

99+
When("lifecycle type cnb is provided", func() {
100+
BeforeEach(func() {
101+
app.LifecycleType = constant.AppLifecycleTypeCNB
102+
app.LifecycleBuildpacks = []string{"docker://nodejs"}
103+
})
104+
105+
It("sets the lifecycle buildpack to be empty in the JSON", func() {
106+
Expect(string(appBytes)).To(MatchJSON(`{"lifecycle":{"data":{"buildpacks":["docker://nodejs"]},"type":"cnb"}}`))
107+
})
108+
})
109+
99110
When("null buildpack is provided", func() {
100111
BeforeEach(func() {
101112
app.LifecycleBuildpacks = []string{"null"}

0 commit comments

Comments
 (0)