diff --git a/cmd/generate-release/scripts/kfsystems-cr.yaml b/cmd/generate-release/scripts/kfsystems-cr.yaml index f2721c493..c9189c27e 100644 --- a/cmd/generate-release/scripts/kfsystems-cr.yaml +++ b/cmd/generate-release/scripts/kfsystems-cr.yaml @@ -106,8 +106,8 @@ spec: # # Use images tagged with SHAs to improve build caching. spaceStacksV2: - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3 + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5 # spaceStacksV3 contains list of default stacks to be used for cloud native # buildpack builds. The value must be a valid JSON or YAML string. diff --git a/config/config-defaults.yaml b/config/config-defaults.yaml index 62adbde2b..360013a4c 100644 --- a/config/config-defaults.yaml +++ b/config/config-defaults.yaml @@ -112,8 +112,8 @@ data: # # Use images tagged with SHAs to improve build caching. spaceStacksV2: | - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3 + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5 # spaceStacksV3 contains list of default stacks to be used for cloud native # buildpack builds. The value must be a valid JSON or YAML string. @@ -225,8 +225,12 @@ data: - name: nginx_buildpack url: https://github.com/cloudfoundry/nginx-buildpack spaceStacksV2: | - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + - name: cflinuxfs4 + image: cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5@sha256:206c68c5753abd24beb85565e9ed525d1f1be24bdab252193793b49b44d4b69e + - name: cflinuxfs3 + image: cloudfoundry/cflinuxfs3 spaceStacksV3: | - name: kf-v2-to-v3-shim description: A V3 stack that wraps the V2 buildpacks. @@ -236,8 +240,16 @@ data: description: Google buildpacks (https://github.com/GoogleCloudPlatform/buildpacks) buildImage: gcr.io/buildpacks/builder:v1 runImage: gcr.io/buildpacks/gcp/run:v1 + - name: org.cloudfoundry.stacks.cflinuxfs4 + description: A large Cloud Foundry stack based on Ubuntu 22.04 (Jammy Jellyfish) + buildImage: paketobuildpacks/builder-jammy-full@sha256:25efe93f3afa866e058f1bf6f72b5734dbd270a4b60e344a0df2d613bc19074c + runImage: paketobuildpacks/run-jammy-full@sha256:43f13c88b7ed100a34520e907fba396c2879605efd14012aa9a696caeff43f9d + - name: org.cloudfoundry.stacks.cflinuxfs5 + description: A large Cloud Foundry stack based on Ubuntu 24.04 (Noble) + buildImage: paketobuildpacks/ubuntu-noble-builder@sha256:fc86fdc15593f47178073b682c75c4991f27b4a2a62d78417fdf505307bb92ae + runImage: paketobuildpacks/ubuntu-noble-run@sha256:013d949ebb61d4771a77f44511eb0de723d092ef4904a83ffa1fee0bdb703275 - name: org.cloudfoundry.stacks.cflinuxfs3 - description: A large Cloud Foundry stack based on Ubuntu 18.04 + description: (Legacy) A large Cloud Foundry stack based on Ubuntu 18.04 buildImage: cloudfoundry/cnb:cflinuxfs3@sha256:f96b6e3528185368dd6af1d9657527437cefdaa5fa135338462f68f9c9db3022 runImage: cloudfoundry/run:full-cnb@sha256:dbe17be507b1cc6ffae1e9edf02806fe0e28ffbbb89a6c7ef41f37b69156c3c2 spaceDefaultToV3Stack: "false" diff --git a/docs/content/en/docs/v2.11/cli/generated/kf-push.md b/docs/content/en/docs/v2.11/cli/generated/kf-push.md index b0d660fdf..9cffeaad4 100644 --- a/docs/content/en/docs/v2.11/cli/generated/kf-push.md +++ b/docs/content/en/docs/v2.11/cli/generated/kf-push.md @@ -17,7 +17,7 @@ description: "Create a new App or apply updates to an existing one." kf push myapp kf push myapp --buildpack my.special.buildpack # Discover via kf buildpacks kf push myapp --env FOO=bar --env BAZ=foo -kf push myapp --stack cloudfoundry/cflinuxfs3 # Use a cflinuxfs3 runtime +kf push myapp --stack cloudfoundry/cflinuxfs5 # Use a cflinuxfs5 runtime kf push myapp --health-check-http-endpoint /myhealthcheck # Specify a healthCheck for the app diff --git a/docs/content/en/docs/v2.11/developer/build-and-deploy/buildpacks-getting-started.md b/docs/content/en/docs/v2.11/developer/build-and-deploy/buildpacks-getting-started.md index 828fa2a20..5cf7c109b 100644 --- a/docs/content/en/docs/v2.11/developer/build-and-deploy/buildpacks-getting-started.md +++ b/docs/content/en/docs/v2.11/developer/build-and-deploy/buildpacks-getting-started.md @@ -31,7 +31,7 @@ kf push java-v2 --path target/helloworld-0.0.1-SNAPSHOT.jar Use [spring initializr](https://start.spring.io/) to create a Java 8 maven project with a spring web dependency and JAR packaging. Download it, extract it, and once extracted, push to Kf with the cloud native buildpack. ```sh -kf push java-v3 --stack org.cloudfoundry.stacks.cflinuxfs3 +kf push java-v3 --stack org.cloudfoundry.stacks.cflinuxfs5 ``` ## Python (v2) buildpack @@ -85,7 +85,7 @@ kf push python --buildpack python\_buildpack Push the Python flask app using cloud native buildpacks. ```sh -kf push pythonv3 --stack org.cloudfoundry.stacks.cflinuxfs3 +kf push pythonv3 --stack org.cloudfoundry.stacks.cflinuxfs5 ``` ## Staticfile (v2) buildpack diff --git a/docs/content/en/docs/v2.11/developer/build-and-deploy/v2-vs-v3-buildpacks.md b/docs/content/en/docs/v2.11/developer/build-and-deploy/v2-vs-v3-buildpacks.md index 82f5cdeb3..f86ebc77a 100644 --- a/docs/content/en/docs/v2.11/developer/build-and-deploy/v2-vs-v3-buildpacks.md +++ b/docs/content/en/docs/v2.11/developer/build-and-deploy/v2-vs-v3-buildpacks.md @@ -80,10 +80,10 @@ The output shows both V2 and V3 Stacks: ``` Getting stacks in Space: myspace Version Name Build Image Run Image -V2 cflinuxfs3 cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 +V2 cflinuxfs5 cloudfoundry/cflinuxfs5@sha256:206c68c5753abd24beb85565e9ed525d1f1be24bdab252193793b49b44d4b69e cloudfoundry/cflinuxfs5@sha256:206c68c5753abd24beb85565e9ed525d1f1be24bdab252193793b49b44d4b69e V3 kf-v2-to-v3-shim gcr.io/kf-releases/v2-to-v3:v2.7.0 gcr.io/buildpacks/gcp/run:v1 This is a stack added by the integration tests to assert that v2->v3 shim works V3 google gcr.io/buildpacks/builder:v1 gcr.io/buildpacks/gcp/run:v1 Google buildpacks (https://github.com/GoogleCloudPlatform/buildpacks) -V3 org.cloudfoundry.stacks.cflinuxfs3 cloudfoundry/cnb:cflinuxfs3@sha256:f96b6e3528185368dd6af1d9657527437cefdaa5fa135338462f68f9c9db3022 cloudfoundry/run:full-cnb@sha256:dbe17be507b1cc6ffae1e9edf02806fe0e28ffbbb89a6c7ef41f37b69156c3c2 A large Cloud Foundry stack based on Ubuntu 18.04 +V3 org.cloudfoundry.stacks.cflinuxfs5 cloudfoundry/cflinuxfs5@sha256:206c68c5753abd24beb85565e9ed525d1f1be24bdab252193793b49b44d4b69e A large Cloud Foundry stack based on Ubuntu 24.04 ``` diff --git a/docs/content/en/docs/v2.11/examples/spring-music/_index.md b/docs/content/en/docs/v2.11/examples/spring-music/_index.md index 0660814d1..7e59582dd 100644 --- a/docs/content/en/docs/v2.11/examples/spring-music/_index.md +++ b/docs/content/en/docs/v2.11/examples/spring-music/_index.md @@ -34,7 +34,7 @@ Music](https://github.com/cloudfoundry-samples/spring-music) reference App using cd spring-music ``` -1. Edit `manifest.yml`, and replace `path: build/libs/spring-music-1.0.jar` with `stack: org.cloudfoundry.stacks.cflinuxfs3`. This instructs Kf to build from source using [cloud native buildpacks](https://cloud.google.com/blog/products/containers-kubernetes/google-cloud-now-supports-buildpacks) so you don't have to compile locally. +1. Edit `manifest.yml`, and replace `path: build/libs/spring-music-1.0.jar` with `stack: org.cloudfoundry.stacks.cflinuxfs5`. This instructs Kf to build from source using [cloud native buildpacks](https://cloud.google.com/blog/products/containers-kubernetes/google-cloud-now-supports-buildpacks) so you don't have to compile locally. ```sh --- diff --git a/docs/content/en/docs/v2.11/migrating/builds.md b/docs/content/en/docs/v2.11/migrating/builds.md index 5b47f226c..7fa25a197 100644 --- a/docs/content/en/docs/v2.11/migrating/builds.md +++ b/docs/content/en/docs/v2.11/migrating/builds.md @@ -23,13 +23,13 @@ Best practices for container runtimes differ from Cloud Foundry's application be In Cloud Foundry and Kf it's common to `push` in every environment which produces a separate build and image. This is a common source of errors if an application development team hasn't pinned the dependencies for their application correctly. -In Cloud Foundry and Kf this pushing provides an additional purpose, a platform operations team can change buildpacks or base images in an environment to patch applications on the fly. This has always been risky, but large base images like `cflinuxfs3`, come with many security vulnerabilities. +In Cloud Foundry and Kf this pushing provides an additional purpose, a platform operations team can change buildpacks or base images in an environment to patch applications on the fly. This has always been risky, but large base images like `cflinuxfs*`, come with many security vulnerabilities. **Things to consider:** * Applications should be built with the dependencies they need for all environments. They shouldn't depend on the environment like the [Spring Autoreconfiguration buildpack](https://github.com/cloudfoundry/java-buildpack-auto-reconfiguration). * Teams should be able to patch and promote an image quickly up through environments as the preferred method of patching. -* Building on smaller base images than `cflinuxfs3` may leave teams without tools they expect to use when using `ssh` to debug containers or may expose hidden dependencies. +* Building on smaller base images than `cflinuxfs*` may leave teams without tools they expect to use when using `ssh` to debug containers or may expose hidden dependencies. * Cloud Foundry and Kf add a [launcher process](https://github.com/cloudfoundry/buildpackapplifecycle/tree/main/launcher) responsible for reading Procfiles and certain environment variables. Applications will need to stop using these, or you should create a drop-in replacement launcher. * Operations teams should monitor deployed images for vulnerabilities. diff --git a/docs/content/en/docs/v2.11/operator/buildpacks/configure-stacks.md b/docs/content/en/docs/v2.11/operator/buildpacks/configure-stacks.md index 76b65900d..f109385c2 100644 --- a/docs/content/en/docs/v2.11/operator/buildpacks/configure-stacks.md +++ b/docs/content/en/docs/v2.11/operator/buildpacks/configure-stacks.md @@ -38,7 +38,7 @@ spec: - name: ruby_buildpack url: https://github.com/cloudfoundry/ruby-buildpack spaceStacksV2: - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5@sha256:206c68c5753abd24beb85565e9ed525d1f1be24bdab252193793b49b44d4b69e ``` diff --git a/docs/content/en/docs/v2.11/operator/security/compute-isolation.md b/docs/content/en/docs/v2.11/operator/security/compute-isolation.md index e9548e75f..36661c26a 100644 --- a/docs/content/en/docs/v2.11/operator/security/compute-isolation.md +++ b/docs/content/en/docs/v2.11/operator/security/compute-isolation.md @@ -75,10 +75,10 @@ To configure the `nodeSelector` on a stack: ..... ..... spaceStacksV2: | - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3 + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5 nodeSelector: - OS_KERNEL: LINUX_4.4.1 + OS_KERNEL: LINUX_6.12.68 ..... ..... ``` diff --git a/operator/cmd/manager/kodata/kf/2.11/v2.11.5_kf.yaml b/operator/cmd/manager/kodata/kf/2.11/v2.11.5_kf.yaml index 0849531cf..de431f95c 100644 --- a/operator/cmd/manager/kodata/kf/2.11/v2.11.5_kf.yaml +++ b/operator/cmd/manager/kodata/kf/2.11/v2.11.5_kf.yaml @@ -7768,8 +7768,8 @@ data: # # Use images tagged with SHAs to improve build caching. spaceStacksV2: | - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3 + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5 # spaceStacksV3 contains list of default stacks to be used for cloud native # buildpack builds. The value must be a valid JSON or YAML string. @@ -7849,8 +7849,12 @@ data: - name: nginx_buildpack url: https://github.com/cloudfoundry/nginx-buildpack spaceStacksV2: | - - name: cflinuxfs3 - image: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + - name: cflinuxfs4 + image: cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b + - name: cflinuxfs5 + image: cloudfoundry/cflinuxfs5@sha256:206c68c5753abd24beb85565e9ed525d1f1be24bdab252193793b49b44d4b69e + - name: cflinuxfs3 + image: cloudfoundry/cflinuxfs3 spaceStacksV3: | - name: kf-v2-to-v3-shim description: A V3 stack that wraps the V2 buildpacks. @@ -7860,8 +7864,16 @@ data: description: Google buildpacks (https://github.com/GoogleCloudPlatform/buildpacks) buildImage: gcr.io/buildpacks/builder:v1 runImage: gcr.io/buildpacks/gcp/run:v1 + - name: org.cloudfoundry.stacks.cflinuxfs4 + description: A large Cloud Foundry stack based on Ubuntu 22.04 (Jammy Jellyfish) + buildImage: paketobuildpacks/builder-jammy-full@sha256:25efe93f3afa866e058f1bf6f72b5734dbd270a4b60e344a0df2d613bc19074c + runImage: paketobuildpacks/run-jammy-full@sha256:43f13c88b7ed100a34520e907fba396c2879605efd14012aa9a696caeff43f9d + - name: org.cloudfoundry.stacks.cflinuxfs5 + description: A large Cloud Foundry stack based on Ubuntu 24.04 (Noble) + buildImage: paketobuildpacks/ubuntu-noble-builder@sha256:fc86fdc15593f47178073b682c75c4991f27b4a2a62d78417fdf505307bb92ae + runImage: paketobuildpacks/ubuntu-noble-run@sha256:013d949ebb61d4771a77f44511eb0de723d092ef4904a83ffa1fee0bdb703275 - name: org.cloudfoundry.stacks.cflinuxfs3 - description: A large Cloud Foundry stack based on Ubuntu 18.04 + description: (Legacy) A large Cloud Foundry stack based on Ubuntu 18.04 buildImage: cloudfoundry/cnb:cflinuxfs3@sha256:f96b6e3528185368dd6af1d9657527437cefdaa5fa135338462f68f9c9db3022 runImage: cloudfoundry/run:full-cnb@sha256:dbe17be507b1cc6ffae1e9edf02806fe0e28ffbbb89a6c7ef41f37b69156c3c2 spaceDefaultToV3Stack: "false" diff --git a/pkg/apis/kf/config/store_test.go b/pkg/apis/kf/config/store_test.go index 23ae47c64..ff5fc7c5f 100644 --- a/pkg/apis/kf/config/store_test.go +++ b/pkg/apis/kf/config/store_test.go @@ -96,8 +96,8 @@ func TestStoreLoadWithContext(t *testing.T) { testutil.AssertEqual(t, "SpaceStacksV2", StackV2List{ { - Name: "cflinuxfs3", - Image: "cloudfoundry/cflinuxfs3", + Name: "cflinuxfs5", + Image: "cloudfoundry/cflinuxfs5", }, }, configDefaults.SpaceStacksV2) diff --git a/pkg/apis/kf/config/types_test.go b/pkg/apis/kf/config/types_test.go index 99664124d..cbee978e8 100644 --- a/pkg/apis/kf/config/types_test.go +++ b/pkg/apis/kf/config/types_test.go @@ -90,15 +90,15 @@ func TestStackV2List_Validate(t *testing.T) { "happy path": { Context: context.Background(), Input: StackV2List{ - {Name: "some-stack", Image: "cloudfoundry/cflinuxfs3"}, + {Name: "some-stack", Image: "cloudfoundry/cflinuxfs5"}, }, Want: nil, }, "duplicate name": { Context: context.Background(), Input: StackV2List{ - {Name: "some-stack", Image: "cloudfoundry/cflinuxfs3"}, - {Name: "some-stack", Image: "cloudfoundry/cflinuxfs3"}, + {Name: "some-stack", Image: "cloudfoundry/cflinuxfs5"}, + {Name: "some-stack", Image: "cloudfoundry/cflinuxfs5"}, }, Want: &apis.FieldError{ Message: "duplicate name", @@ -124,7 +124,7 @@ func TestStackV2_Validate(t *testing.T) { Context: context.Background(), Input: &StackV2Definition{ Name: "some-stack", - Image: "cloudfoundry/cflinuxfs3", + Image: "cloudfoundry/cflinuxfs5", }, Want: nil, }, @@ -138,7 +138,7 @@ func TestStackV2_Validate(t *testing.T) { "missing name": { Context: context.Background(), Input: &StackV2Definition{ - Image: "cloudfoundry/cflinuxfs3", + Image: "cloudfoundry/cflinuxfs5", }, Want: apis.ErrMissingField("name"), }, @@ -171,7 +171,7 @@ func TestStackV3List_Validate(t *testing.T) { "recurses to children": { Context: context.Background(), Input: StackV3List{ - {Name: "some-stack", RunImage: "cloudfoundry/cflinuxfs3:run"}, + {Name: "some-stack", RunImage: "cloudfoundry/cflinuxfs5:run"}, }, Want: apis.ErrMissingField("[0].buildImage"), }, @@ -186,8 +186,8 @@ func TestStackV3_Validate(t *testing.T) { Context: context.Background(), Input: &StackV3Definition{ Name: "some-stack", - BuildImage: "cloudfoundry/cflinuxfs3:build", - RunImage: "cloudfoundry/cflinuxfs3:run", + BuildImage: "cloudfoundry/cflinuxfs5:build", + RunImage: "cloudfoundry/cflinuxfs5:run", }, Want: nil, }, @@ -195,7 +195,7 @@ func TestStackV3_Validate(t *testing.T) { Context: context.Background(), Input: &StackV3Definition{ Name: "some-stack", - RunImage: "cloudfoundry/cflinuxfs3:run", + RunImage: "cloudfoundry/cflinuxfs5:run", }, Want: apis.ErrMissingField("buildImage"), }, @@ -203,15 +203,15 @@ func TestStackV3_Validate(t *testing.T) { Context: context.Background(), Input: &StackV3Definition{ Name: "some-stack", - BuildImage: "cloudfoundry/cflinuxfs3:build", + BuildImage: "cloudfoundry/cflinuxfs5:build", }, Want: apis.ErrMissingField("runImage"), }, "missing name": { Context: context.Background(), Input: &StackV3Definition{ - BuildImage: "cloudfoundry/cflinuxfs3:build", - RunImage: "cloudfoundry/cflinuxfs3:run", + BuildImage: "cloudfoundry/cflinuxfs5:build", + RunImage: "cloudfoundry/cflinuxfs5:run", }, Want: apis.ErrMissingField("name"), }, @@ -223,16 +223,16 @@ func TestStackV3_Validate(t *testing.T) { func ExampleStackV2List_FindStackByName() { list := StackV2List{ { - Name: "cflinuxfs3", - Image: "cloudfoundry/cflinuxfs3", + Name: "cflinuxfs5", + Image: "cloudfoundry/cflinuxfs5", }, } fmt.Println("doesn't exist:", list.FindStackByName("does-not-exist")) - fmt.Println("exists image:", list.FindStackByName("cflinuxfs3").Image) + fmt.Println("exists image:", list.FindStackByName("cflinuxfs5").Image) // Output: doesn't exist: - // exists image: cloudfoundry/cflinuxfs3 + // exists image: cloudfoundry/cflinuxfs5 } func ExampleBuildpackV2List_WithoutDisabled() { diff --git a/pkg/kf/commands/apps/acceptance_test.go b/pkg/kf/commands/apps/acceptance_test.go index 7382ad14e..40278bcf8 100644 --- a/pkg/kf/commands/apps/acceptance_test.go +++ b/pkg/kf/commands/apps/acceptance_test.go @@ -66,9 +66,9 @@ func setupSimpleChineseApp() acceptance.SourceCode { } } -func setupSpringMusic() acceptance.SourceCode { +func setupSpringMusic(cflinuxfsVersion string) acceptance.SourceCode { return acceptance.SourceCode{ - Name: "spring-music", + Name: "spring-music-" + cflinuxfsVersion, Repo: "http://github.com/cloudfoundry-samples/spring-music", Setup: func(t *testing.T) { man, err := manifest.NewFromFile(context.Background(), "manifest.yml", nil) @@ -80,7 +80,7 @@ func setupSpringMusic() acceptance.SourceCode { man.Applications[0].Path = "" delete(man.Applications[0].Env, "JBP_CONFIG_SPRING_AUTO_RECONFIGURATION") man.Applications[0].Env["BP_AUTO_RECONFIGURATION_ENABLED"] = "false" - man.Applications[0].Stack = "org.cloudfoundry.stacks.cflinuxfs3" + man.Applications[0].Stack = "org.cloudfoundry.stacks." + cflinuxfsVersion yamlData, err := yaml.Marshal(man) testutil.AssertNil(t, "yaml.Marshal", err) @@ -104,7 +104,9 @@ func TestAcceptance_Get200(t *testing.T) { setupCfPhpInfo(), setupDotnetCoreHelloWorld(), setupSimpleChineseApp(), - setupSpringMusic(), + setupSpringMusic("cflinuxfs3"), + setupSpringMusic("cflinuxfs4"), + setupSpringMusic("cflinuxfs5"), setupTestApp(), }, func(ctx context.Context, t *testing.T, kf *integration.Kf, appPath string) { diff --git a/pkg/kf/commands/apps/integration_test.go b/pkg/kf/commands/apps/integration_test.go index 2204d23c5..f15780396 100644 --- a/pkg/kf/commands/apps/integration_test.go +++ b/pkg/kf/commands/apps/integration_test.go @@ -17,7 +17,10 @@ package apps import ( "context" "fmt" + "io/ioutil" "net/http" + "os" + "os/exec" "path/filepath" "strings" "testing" @@ -415,18 +418,49 @@ func TestIntegration_Push_SigtermV2Buildpack(t *testing.T) { // and then posts to it. It finally deletes the App. func TestIntegration_Push_binaryBuildpack(t *testing.T) { // This test needs more time because pushes with V2 buildpacks. - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Minute) defer cancel() + integration.RunKfTest(ctx, t, func(ctx context.Context, t *testing.T, kf *integration.Kf) { appName := v1alpha1.GenerateName("integration-push-bin", fmt.Sprint(time.Now().UnixNano())) - // Push an App and then clean it up. This pushes the echo App which - // replies with the same body that was posted. - // For the purposes of this test the results SHOULD NOT be cached. + // Create a temporary directory for the binary test application + tempDir, err := ioutil.TempDir("", "binary-test") + if err != nil { + t.Fatalf("create temp dir: %v", err) + } + defer os.RemoveAll(tempDir) + + // Write a minimal Go web server + mainFile := filepath.Join(tempDir, "main.go") + code := `package main +import ( + "net/http" + "os" +) +func main() { + http.ListenAndServe(":"+os.Getenv("PORT"), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) +}` + if err := ioutil.WriteFile(mainFile, []byte(code), 0644); err != nil { + t.Fatalf("failed to write main.go: %v", err) + } + + // Compile the binary statically for the target container environment + binPath := filepath.Join(tempDir, "server") + cmd := exec.Command("go", "build", "-o", binPath, mainFile) + cmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=amd64", "CGO_ENABLED=0") + if err := cmd.Run(); err != nil { + t.Fatalf("failed to compile test binary: %v", err) + } + kf.Push(ctx, appName, "--buildpack", "binary_buildpack", - "--command", "python -m SimpleHTTPServer $PORT", + "--path", tempDir, + "--command", "./server", ) + integration.CheckApp(ctx, t, kf, appName, []string{integration.ExpectedAddr(appName, "")}, func(ctx context.Context, t *testing.T, addr string) { // Just check to ensure we got a 200 diff --git a/pkg/kf/commands/apps/push.go b/pkg/kf/commands/apps/push.go index 0d8cd9cd0..0c05c0660 100644 --- a/pkg/kf/commands/apps/push.go +++ b/pkg/kf/commands/apps/push.go @@ -124,7 +124,7 @@ func NewPushCommand( kf push myapp kf push myapp --buildpack my.special.buildpack # Discover via kf buildpacks kf push myapp --env FOO=bar --env BAZ=foo - kf push myapp --stack cloudfoundry/cflinuxfs3 # Use a cflinuxfs3 runtime + kf push myapp --stack cloudfoundry/cflinuxfs5 # Use a cflinuxfs5 runtime kf push myapp --health-check-http-endpoint /myhealthcheck # Specify a healthCheck for the app `, Args: cobra.MaximumNArgs(1), diff --git a/pkg/kf/commands/apps/push_test.go b/pkg/kf/commands/apps/push_test.go index 8f71ab665..06547ee5e 100644 --- a/pkg/kf/commands/apps/push_test.go +++ b/pkg/kf/commands/apps/push_test.go @@ -72,9 +72,9 @@ func TestPushCommand(t *testing.T) { Image: "some/stack:latest", } - cflinuxfs3Stack := kfconfig.StackV2Definition{ - Name: "cflinuxfs3", - Image: "cflinuxfs3:latest", + cflinuxfs5Stack := kfconfig.StackV2Definition{ + Name: "cflinuxfs5", + Image: "cflinuxfs5:latest", } v3Stack := kfconfig.StackV3Definition{ @@ -85,14 +85,14 @@ func TestPushCommand(t *testing.T) { ContainerRegistry: "some-registry", StacksV2: kfconfig.StackV2List{ defaultV2Stack, - cflinuxfs3Stack, + cflinuxfs5Stack, }, StacksV3: kfconfig.StackV3List{ v3Stack, }, } - buildpackWithParams := v1alpha1.BuildpackV2Build("some-image", cflinuxfs3Stack, []string{"some-buildpack"}, true) + buildpackWithParams := v1alpha1.BuildpackV2Build("some-image", cflinuxfs5Stack, []string{"some-buildpack"}, true) buildpackWithoutSourceOption := apps.WithPushBuild(bldPtr(buildpackWithoutSource(v1alpha1.BuildpackV2Build("some-image", defaultV2Stack, nil, false)))) buildpackOption := apps.WithPushBuild(bldPtr(v1alpha1.BuildpackV2Build("some-image", defaultV2Stack, nil, false))) buildpackV3WithoutSourceOption := apps.WithPushBuild(bldPtr(buildpackWithoutSource(v1alpha1.BuildpackV3Build("some-image", v3Stack, nil)))) @@ -133,7 +133,7 @@ func TestPushCommand(t *testing.T) { "--no-start", "-u", "http", "-t", "28", - "-s", "cflinuxfs3", + "-s", "cflinuxfs5", "--entrypoint", "start-web.sh", "--args", "a", "--args", "b", diff --git a/pkg/kf/commands/buildpacks/stacks_test.go b/pkg/kf/commands/buildpacks/stacks_test.go index 63c3c5d33..9fd8bd184 100644 --- a/pkg/kf/commands/buildpacks/stacks_test.go +++ b/pkg/kf/commands/buildpacks/stacks_test.go @@ -56,9 +56,9 @@ func TestStacks(t *testing.T) { BuildConfig: v1alpha1.SpaceStatusBuildConfig{ StacksV2: kfconfig.StackV2List{ { - Name: "cflinuxfs3", + Name: "cflinuxfs4", Description: "A CF Compatible Stack", - Image: "cloudfoundry/cflinuxfs3:latest", + Image: "cloudfoundry/cflinuxfs4:latest", }, }, StacksV3: kfconfig.StackV3List{ @@ -81,9 +81,9 @@ func TestStacks(t *testing.T) { BuildConfig: v1alpha1.SpaceStatusBuildConfig{ StacksV2: kfconfig.StackV2List{ { - Name: "cflinuxfs3", + Name: "cflinuxfs5", Description: "A CF Compatible Stack", - Image: "cloudfoundry/cflinuxfs3:latest", + Image: "cloudfoundry/cflinuxfs4:latest", }, }, StacksV3: kfconfig.StackV3List{ diff --git a/pkg/kf/commands/buildpacks/testdata/golden/teststacks_lists_each_stack_output.golden b/pkg/kf/commands/buildpacks/testdata/golden/teststacks_lists_each_stack_output.golden index 99279c58e..ef239e8ef 100644 --- a/pkg/kf/commands/buildpacks/testdata/golden/teststacks_lists_each_stack_output.golden +++ b/pkg/kf/commands/buildpacks/testdata/golden/teststacks_lists_each_stack_output.golden @@ -1,3 +1,3 @@ Version Name Build Image Run Image Description -V2 cflinuxfs3 cloudfoundry/cflinuxfs3:latest cloudfoundry/cflinuxfs3:latest A CF Compatible Stack +V2 cflinuxfs4 cloudfoundry/cflinuxfs4:latest cloudfoundry/cflinuxfs4:latest A CF Compatible Stack V3 google-golang gcr.io/buildpacks/go gcr.io/buildpacks/slim A stack for golang by Google diff --git a/pkg/kf/commands/buildpacks/wrap-v2-buildpack.go b/pkg/kf/commands/buildpacks/wrap-v2-buildpack.go index 7af35d402..cb5bc60a4 100644 --- a/pkg/kf/commands/buildpacks/wrap-v2-buildpack.go +++ b/pkg/kf/commands/buildpacks/wrap-v2-buildpack.go @@ -404,7 +404,7 @@ cp -r . /tmp/app/ cd /tmp/app # Many of the V2 buildpacks expect this environment variable to be set... -export CF_STACK=cflinuxfs3 +export CF_STACK=cflinuxfs4 ${script_path}/v2-lifecycle/builder \ -buildDir=/tmp/app \ diff --git a/pkg/kf/commands/exporttok8s/exporttok8s.go b/pkg/kf/commands/exporttok8s/exporttok8s.go index 51770a994..66fa910aa 100644 --- a/pkg/kf/commands/exporttok8s/exporttok8s.go +++ b/pkg/kf/commands/exporttok8s/exporttok8s.go @@ -199,7 +199,7 @@ func makePipelineSpec(url string, params []tektonv1beta1.Param) *tektonv1beta1.P "-euc", ` echo "/staging/app /tmp/app" | xargs -n 1 cp -r /workspace/output/ -CF_STACK=cflinuxfs3 /workspace/builder \ +CF_STACK=cflinuxfs4 /workspace/builder \ -buildArtifactsCacheDir=/tmp/cache \ -buildDir=/tmp/app \ -buildpacksDir=/tmp/buildpacks \ @@ -489,8 +489,8 @@ func getBuildSpec() (*v1alpha1.BuildSpec, error) { }, StacksV2: kfconfig.StackV2List{ { - Image: "cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5", - Name: "cflinuxfs3", + Image: "cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b", + Name: "cflinuxfs4", }, }, }) diff --git a/pkg/kf/commands/exporttok8s/testdata/golden/testexportstok8scommand_sanity_build_image_yaml.golden b/pkg/kf/commands/exporttok8s/testdata/golden/testexportstok8scommand_sanity_build_image_yaml.golden index 824bfa2f6..8d642c4ab 100644 --- a/pkg/kf/commands/exporttok8s/testdata/golden/testexportstok8scommand_sanity_build_image_yaml.golden +++ b/pkg/kf/commands/exporttok8s/testdata/golden/testexportstok8scommand_sanity_build_image_yaml.golden @@ -244,9 +244,9 @@ spec: - name: push params: - name: RUN_IMAGE - value: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + value: cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b - name: BUILDER_IMAGE - value: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + value: cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b - name: SKIP_DETECT value: "false" - name: IMAGE_DESTINATION @@ -289,7 +289,7 @@ spec: - |2 echo "/staging/app /tmp/app" | xargs -n 1 cp -r /workspace/output/ - CF_STACK=cflinuxfs3 /workspace/builder \ + CF_STACK=cflinuxfs4 /workspace/builder \ -buildArtifactsCacheDir=/tmp/cache \ -buildDir=/tmp/app \ -buildpacksDir=/tmp/buildpacks \ @@ -398,9 +398,9 @@ spec: - name: push params: - name: RUN_IMAGE - value: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + value: cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b - name: BUILDER_IMAGE - value: cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 + value: cloudfoundry/cflinuxfs4@sha256:118249de04f4f7543bc8118a9943c86d1c30504e687f468c4342d22b1e3d713b - name: SKIP_DETECT value: "false" - name: IMAGE_DESTINATION @@ -443,7 +443,7 @@ spec: - |2 echo "/staging/app /tmp/app" | xargs -n 1 cp -r /workspace/output/ - CF_STACK=cflinuxfs3 /workspace/builder \ + CF_STACK=cflinuxfs4 /workspace/builder \ -buildArtifactsCacheDir=/tmp/cache \ -buildDir=/tmp/app \ -buildpacksDir=/tmp/buildpacks \ diff --git a/pkg/kf/internal/last_integration_tests/integration_test.go b/pkg/kf/internal/last_integration_tests/integration_test.go index 67b1bfa9d..fa78ced4c 100644 --- a/pkg/kf/internal/last_integration_tests/integration_test.go +++ b/pkg/kf/internal/last_integration_tests/integration_test.go @@ -201,14 +201,14 @@ func TestIntegration_BuildWithResources(t *testing.T) { { name: "v2 buildpack", push: func(ctx context.Context, appName string) { - kf.Push(ctx, appName, "--stack=cflinuxfs3") + kf.Push(ctx, appName, "--stack=cflinuxfs4") }, containersWithResources: []string{"step-run-lifecycle", "step-build"}, }, { name: "v3 buildpack", push: func(ctx context.Context, appName string) { - kf.Push(ctx, appName, "--stack=org.cloudfoundry.stacks.cflinuxfs3") + kf.Push(ctx, appName, "--stack=org.cloudfoundry.stacks.cflinuxfs4") }, containersWithResources: []string{"step-build"}, }, diff --git a/pkg/kf/manifest/manifest_test.go b/pkg/kf/manifest/manifest_test.go index e57ed8616..332d37c0b 100644 --- a/pkg/kf/manifest/manifest_test.go +++ b/pkg/kf/manifest/manifest_test.go @@ -56,7 +56,7 @@ applications: fileContent: `--- applications: - name: MY-APP - stack: cflinuxfs3 + stack: cflinuxfs5 buildpacks: - java - node @@ -67,7 +67,7 @@ applications: Applications: []manifest.Application{ { Name: "MY-APP", - Stack: "cflinuxfs3", + Stack: "cflinuxfs5", Buildpacks: []string{"java", "node"}, }, }, @@ -109,7 +109,7 @@ applications: fileContent: `--- applications: - name: MY-APP - stack: cflinuxfs3 + stack: cflinuxfs5 buildpack: java `, expected: &manifest.Manifest{ @@ -118,7 +118,7 @@ applications: Applications: []manifest.Application{ { Name: "MY-APP", - Stack: "cflinuxfs3", + Stack: "cflinuxfs5", LegacyBuildpack: "java", }, }, diff --git a/pkg/kf/testutil/integration/integration.go b/pkg/kf/testutil/integration/integration.go index 1494f1488..96270adfb 100644 --- a/pkg/kf/testutil/integration/integration.go +++ b/pkg/kf/testutil/integration/integration.go @@ -1081,14 +1081,14 @@ var sourceCache = newAppCache() // cached version. This is incompatible with additional arguments that might // change the semantics of push. It returns true if the cache was used. func (k *Kf) CachePushV2(ctx context.Context, appName, source string, args ...string) bool { - return k.cachePush(ctx, appName, source, "cflinuxfs3", args...) + return k.cachePush(ctx, appName, source, "cflinuxfs4", args...) } // CachePush pushes an App with V3 buildpack and caches the source or uses a // cached version. This is incompatible with additional arguments that might // change the semantics of push. It returns true if the cache was used. func (k *Kf) CachePush(ctx context.Context, appName, source string, args ...string) bool { - return k.cachePush(ctx, appName, source, "org.cloudfoundry.stacks.cflinuxfs3", args...) + return k.cachePush(ctx, appName, source, "org.cloudfoundry.stacks.cflinuxfs4", args...) } func (k *Kf) cachePush(ctx context.Context, appName, source, stack string, args ...string) bool { diff --git a/pkg/reconciler/build/resources/builtin_tasks.go b/pkg/reconciler/build/resources/builtin_tasks.go index 4c4885447..ea81f6aa5 100644 --- a/pkg/reconciler/build/resources/builtin_tasks.go +++ b/pkg/reconciler/build/resources/builtin_tasks.go @@ -350,6 +350,13 @@ func buildpackV3Build(cfg *config.DefaultsConfig, buildSpec v1alpha1.BuildSpec, platformEnvSet.Insert(v.Name) } + cbnPlatformApiEnv := []corev1.EnvVar{ + { + Name: "CNB_PLATFORM_API", + Value: "0.15", + }, + } + return &tektonv1beta1.TaskSpec{ Params: []tektonv1beta1.ParamSpec{ tektonutil.DefaultStringParam("SOURCE_IMAGE", "The image that contains the app's source code.", ""), @@ -415,40 +422,29 @@ if [[ -z "$(inputs.params.BUILDPACK)" ]]; then -app=/layers/source \ -group=/layers/group.toml \ -plan=/layers/plan.toml \ - -platform=/platform + -platform=/platform || \ + CNB_PLATFORM_API= /lifecycle/detector \ + -app=/layers/source \ + -group=/layers/group.toml \ + -plan=/layers/plan.toml \ + -platform=/platform else - touch /layers/plan.toml - echo -e "[[buildpacks]]\nid = \"$(inputs.params.BUILDPACK)\"\nversion = \"latest\"\n" > /layers/group.toml + cat < /tmp/custom-order.toml +[[order]] +[[order.group]] +id = "$(inputs.params.BUILDPACK)" +EOF + + /lifecycle/detector \ + -app=/layers/source \ + -platform=/platform \ + -order=/tmp/custom-order.toml fi `, }, + Env: cbnPlatformApiEnv, VolumeMounts: cacheAndLayers, }, - { - Name: "restore", - Image: "$(inputs.params.BUILDER_IMAGE)", - Command: []string{"/lifecycle/restorer"}, - Args: []string{ - "-group=/layers/group.toml", - "-layers=/layers", - "-cache-dir=/cache", - }, - VolumeMounts: cacheAndLayers, - }, - { - Name: "build", - Image: "$(inputs.params.BUILDER_IMAGE)", - Command: []string{"/lifecycle/builder"}, - Args: []string{ - "-app=/layers/source", - "-layers=/layers", - "-group=/layers/group.toml", - "-plan=/layers/plan.toml", - "-platform=/platform", - }, - VolumeMounts: cacheAndLayers, - Resources: resources, - }, { Name: "download-token", Image: cfg.BuildTokenDownloadImage, @@ -531,6 +527,56 @@ exit 1 }, VolumeMounts: cacheAndLayers, }, + { + Name: "analyze", + Image: "$(inputs.params.BUILDER_IMAGE)", + Command: []string{"bash"}, + Args: []string{ + "-euc", + ` +googleServiceAccount=$1 +if [ "$googleServiceAccount" != "" ] && [ -f /workspace/gcloud.token ]; then + export CNB_REGISTRY_AUTH=$(cat /workspace/gcloud.token) +fi + +/lifecycle/analyzer \ + -layers=/layers \ + -analyzed=/layers/analyzed.toml \ + "$(inputs.params.DESTINATION_IMAGE)" +`, + "_", + googleServiceAccount, + }, + Env: cbnPlatformApiEnv, + VolumeMounts: cacheAndLayers, + }, + { + Name: "restore", + Image: "$(inputs.params.BUILDER_IMAGE)", + Command: []string{"/lifecycle/restorer"}, + Args: []string{ + "-group=/layers/group.toml", + "-layers=/layers", + "-cache-dir=/cache", + }, + Env: cbnPlatformApiEnv, + VolumeMounts: cacheAndLayers, + }, + { + Name: "build", + Image: "$(inputs.params.BUILDER_IMAGE)", + Command: []string{"/lifecycle/builder"}, + Args: []string{ + "-app=/layers/source", + "-layers=/layers", + "-group=/layers/group.toml", + "-plan=/layers/plan.toml", + "-platform=/platform", + }, + Env: cbnPlatformApiEnv, + VolumeMounts: cacheAndLayers, + Resources: resources, + }, { Name: "export", Image: "$(inputs.params.BUILDER_IMAGE)", @@ -558,23 +604,37 @@ export_image () { -image=$(inputs.params.RUN_IMAGE) \ $(inputs.params.DESTINATION_IMAGE) } +export_image_new () { + chmod -R a+rx /layers/source + /lifecycle/exporter \ + -app=/layers/source \ + -layers=/layers \ + -group=/layers/group.toml \ + -analyzed=/layers/analyzed.toml \ + -run=$(inputs.params.RUN_IMAGE) \ + $(inputs.params.DESTINATION_IMAGE) +} # This will retry a few times (2 minutes) in case exporting failed (i.e., WI # token hasn't had time to propagate). for i in $$(seq 1 24); do if export_image; then - # Success - exit 0 - else - # Failure - echo "failed to export image. Retrying..." - sleep 5 - fi + # Success + exit 0 + elif export_image_new; then + # Success + exit 0 + else + # Failure + echo "failed to export image. Retrying..." + sleep 5 + fi done `, "_", googleServiceAccount, }, + Env: cbnPlatformApiEnv, VolumeMounts: cacheAndLayers, }, { diff --git a/samples/apps/multiple-ports/manifest.yaml b/samples/apps/multiple-ports/manifest.yaml index 800d29008..6065f5a2e 100644 --- a/samples/apps/multiple-ports/manifest.yaml +++ b/samples/apps/multiple-ports/manifest.yaml @@ -15,7 +15,7 @@ --- applications: - name: multiple-ports - stack: org.cloudfoundry.stacks.cflinuxfs3 + stack: org.cloudfoundry.stacks.cflinuxfs4 ports: - port: 8080 protocol: http