diff --git a/.circleci/config.yml b/.circleci/config.yml index 5233bf9..3b79422 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,6 +7,7 @@ workflows: main: jobs: - pack/build: + executor-image: ubuntu-2204:2023.04.2 working-directory: apps/java-maven image-name: cnbs/circleci-sample builder: 'cnbs/sample-builder:jammy' @@ -27,4 +28,4 @@ jobs: docker load -i /tmp/workspace/images/image.tgz docker run -d -p 8080:8080 cnbs/circleci-sample sleep 40 - curl -k localhost:8080 \ No newline at end of file + curl -k localhost:8080 diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 6bf2c73..321c43d 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -22,10 +22,12 @@ jobs: with: github-token: ${{secrets.GITHUB_TOKEN}} result-encoding: string + # FIXME: Revert back to 'getLatestRelease' when pack v0.30.0 is released script: | - return github.rest.repos.getLatestRelease({ + return github.rest.repos.getReleaseByTag({ owner: "buildpacks", - repo: "pack" + repo: "pack", + tag: "v0.30.0-pre3" }).then(result => { return result.data.assets .filter(a => a.name.includes("-linux.tgz")) @@ -40,7 +42,7 @@ jobs: ./pack config experimental true ./pack config pull-policy always - name: Build - run: PACK_CMD=./pack make build-linux build-wine + run: PACK_CMD=./pack make build-linux - uses: azure/docker-login@v1 if: ${{ github.ref == 'refs/heads/main' }} with: @@ -48,9 +50,9 @@ jobs: password: ${{ secrets.REGISTRY_PASSWORD }} - name: Deploy if: ${{ github.ref == 'refs/heads/main' }} - run: make deploy-linux deploy-wine + run: make deploy-linux - name: Clean up - run: make clean-linux clean-wine + run: make clean-linux build-deploy-windows: strategy: matrix: diff --git a/Makefile b/Makefile index a9054c2..cc0ea1e 100644 --- a/Makefile +++ b/Makefile @@ -37,20 +37,26 @@ build-builder-jammy: build-linux-packages build-sample-root build-linux-buildpacks: build-buildpacks-alpine build-buildpacks-jammy build-buildpacks-alpine: build-sample-root + @echo "> Starting local registry to store alpine builder (when builder contains extensions it must exist in a registry so that builds can use --pull-policy=always and we don't want to override the locally built builder)" + docker run -d --rm -p 5000:5000 registry:2 + sleep 2 + docker tag cnbs/sample-builder:alpine localhost:5000/cnbs/sample-builder:alpine + docker push localhost:5000/cnbs/sample-builder:alpine + @echo "> Creating 'hello-moon' app using 'alpine' builder..." - $(PACK_CMD) build sample-hello-moon-app:alpine -v --builder cnbs/sample-builder:alpine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-world --buildpack $(SAMPLES_ROOT)/buildpacks/hello-moon $(PACK_BUILD_FLAGS) + $(PACK_CMD) build sample-hello-moon-app:alpine -v --builder localhost:5000/cnbs/sample-builder:alpine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-world --buildpack $(SAMPLES_ROOT)/buildpacks/hello-moon --network=host @echo "> Creating 'hello-processes' app using 'alpine' builder..." - $(PACK_CMD) build sample-hello-processes-app:alpine -v --builder cnbs/sample-builder:alpine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-processes $(PACK_BUILD_FLAGS) + $(PACK_CMD) build sample-hello-processes-app:alpine -v --builder localhost:5000/cnbs/sample-builder:alpine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-processes --network=host @echo "> Creating 'hello-world' app using 'alpine' builder..." - $(PACK_CMD) build sample-hello-world-app:alpine -v --builder cnbs/sample-builder:alpine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-world $(PACK_BUILD_FLAGS) + $(PACK_CMD) build sample-hello-world-app:alpine -v --builder localhost:5000/cnbs/sample-builder:alpine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-world --network=host @echo "> Creating 'java-maven' app using 'alpine' builder..." - $(PACK_CMD) build sample-java-maven-app:alpine -v --builder cnbs/sample-builder:alpine --path apps/java-maven $(PACK_BUILD_FLAGS) + $(PACK_CMD) build sample-java-maven-app:alpine -v --builder localhost:5000/cnbs/sample-builder:alpine --path apps/java-maven --network=host @echo "> Creating 'kotlin-gradle' app using 'alpine' builder..." - $(PACK_CMD) build sample-kotlin-gradle-app:alpine -v --builder cnbs/sample-builder:alpine --path apps/kotlin-gradle $(PACK_BUILD_FLAGS) + $(PACK_CMD) build sample-kotlin-gradle-app:alpine -v --builder localhost:5000/cnbs/sample-builder:alpine --path apps/kotlin-gradle --network=host build-buildpacks-jammy: build-sample-root @echo "> Creating 'hello-moon' app using 'jammy' builder..." @@ -145,59 +151,6 @@ set-experimental: @echo "> Setting experimental" $(PACK_CMD) config experimental true -#################### -## Wine -#################### - -build-wine: build-stack-wine build-builder-wine build-buildpacks-wine - -build-stack-wine: - @echo "> Building 'wine' stack..." - bash stacks/build-stack.sh stacks/wine - -build-builder-wine: build-sample-root - @echo "> Building 'wine' builder..." - $(PACK_CMD) create-builder cnbs/sample-builder:wine --config $(SAMPLES_ROOT)/builders/wine/builder.toml $(PULL_POLICY_NEVER) - -build-wine-apps: build-sample-root - @echo "> Creating 'batch-script' app using 'wine' builder..." - $(PACK_CMD) build sample-batch-script-app:wine -v --builder cnbs/sample-builder:wine --path apps/batch-script $(PULL_POLICY_NEVER) $(PACK_BUILD_FLAGS) - -build-buildpacks-wine: build-sample-root - @echo "> Creating 'hello-moon-windows' app using 'wine' builder..." - $(PACK_CMD) build sample-hello-moon-windows-app:wine -v --builder cnbs/sample-builder:wine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-world-windows --buildpack $(SAMPLES_ROOT)/buildpacks/hello-moon-windows $(PULL_POLICY_NEVER) $(PACK_BUILD_FLAGS) - - @echo "> Creating 'hello-world-windows' app using 'wine' builder..." - $(PACK_CMD) build sample-hello-world-windows-app:wine -v --builder cnbs/sample-builder:wine --buildpack $(SAMPLES_ROOT)/buildpacks/hello-world-windows $(PULL_POLICY_NEVER) $(PACK_BUILD_FLAGS) - -deploy-wine: deploy-wine-stacks deploy-wine-builders - -deploy-wine-stacks: - @echo "> Deploying 'wine' stack..." - docker push cnbs/sample-stack-run:wine - docker push cnbs/sample-stack-build:wine - -deploy-wine-builders: - @echo "> Deploying 'wine' builder..." - docker push cnbs/sample-builder:wine - -clean-wine: - @echo "> Removing 'wine' stack..." - docker rmi cnbs/sample-stack-base:wine || true - docker rmi cnbs/sample-stack-run:wine || true - docker rmi cnbs/sample-stack-build:wine || true - - @echo "> Removing builders..." - docker rmi cnbs/sample-builder:wine || true - - @echo "> Removing 'wine' apps..." - docker rmi sample-hello-moon-windows-app:wine || true - docker rmi sample-hello-world-windows-app:wine || true - docker rmi sample-batch-script-app:wine || true - - @echo "> Removing '.tmp'" - rm -rf .tmp - #################### ## Windows #################### diff --git a/apps/bash-script/bash-script-buildpack/buildpack.toml b/apps/bash-script/bash-script-buildpack/buildpack.toml index 9ff82a6..dc81cd4 100644 --- a/apps/bash-script/bash-script-buildpack/buildpack.toml +++ b/apps/bash-script/bash-script-buildpack/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] diff --git a/apps/batch-script/batch-script-buildpack/buildpack.toml b/apps/batch-script/batch-script-buildpack/buildpack.toml index 8a4af0b..5a6a452 100644 --- a/apps/batch-script/batch-script-buildpack/buildpack.toml +++ b/apps/batch-script/batch-script-buildpack/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] @@ -10,6 +10,3 @@ name = "Batch Script Buildpack" # Stacks that the buildpack will work with [[stacks]] id = "io.buildpacks.samples.stacks.nanoserver-1809" - -[[stacks]] -id = "io.buildpacks.samples.stacks.wine" diff --git a/builders/alpine/builder.toml b/builders/alpine/builder.toml index 58198d7..0875dc4 100644 --- a/builders/alpine/builder.toml +++ b/builders/alpine/builder.toml @@ -28,6 +28,11 @@ id = "samples/curl" version = "0.0.1" uri = "../../extensions/curl" +[[extensions]] +id = "samples/cowsay" +version = "0.0.1" +uri = "../../extensions/cowsay" + # Order used for detection (buildpacks) [[order]] [[order.group]] @@ -59,6 +64,10 @@ version = "0.0.1" id = "samples/curl" version = "0.0.1" +[[order-extensions.group]] +id = "samples/cowsay" +version = "0.0.1" + # Stack that will be used by the builder [stack] id = "io.buildpacks.samples.stacks.alpine" diff --git a/builders/wine/README.md b/builders/wine/README.md deleted file mode 100644 index 1d717ee..0000000 --- a/builders/wine/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Sample Wine Builder - -A Linux builder that runs a Windows lifecycle using the [Wine emulation layer](https://www.winehq.org/) within a Linux container. Provides an emulated Windows environment for detect/build phases but generates _**unrunnable**_ app images by default. - -Supported `pack build` cases: -* Test basic Windows buildpacks. -* Build and inspect minimal Windows app images. -* Test Windows lifecycle implementations ([example](#Test-Windows-lifecycle-implementations)). -* Build or rebase an app image with a runnable Windows run image ([example](#Build-and-publish-a-runnable-Windows-app-image-to-a-registry)). - -What is **not** supported: -* Creating runnable app images on a local daemon, due to Windows/Linux image formatting differences. -* Using buildpackages, due to Windows/Linux layer formatting differences. - -### Prerequisites -* [Pack](https://buildpacks.io/docs/install-pack/) -* Docker daemon with Linux container support - -### Usage - -#### Creating the builder - -```bash -pack create-builder cnbs/sample-builder:wine --config builder.toml -``` - -#### Build app with builder - -```bash -pack build sample-app --builder cnbs/sample-builder:wine --path ../../apps/batch-script/ -``` - -_Note: After building, app is not runnable but can be inspected with `docker` or `dive`._ - -#### Test Windows lifecycle implementations - ```bash - # Replace with locally built lifecycle tarball - sed -i.bak '$s!uri = .*!uri = "../../../lifecycle/out/lifecycle-v0.0.0+windows.x86-64.tgz"!' builder.toml - - pack create-builder cnbs/sample-builder:wine --config builder.toml - - pack build sample-app --builder cnbs/sample-builder:wine --trust-builder - ``` - -#### Build and publish a runnable Windows app image to a registry - -```bash -myrepo= - -crane copy mcr.microsoft.com/windows/nanoserver:1809-amd64 ${myrepo}/sample-stack-run:nanoserver-1809-wine - -crane mutate ${myrepo}/sample-stack-run:nanoserver-1809-wine --label io.buildpacks.stack.id=io.buildpacks.samples.stacks.wine - -pack build ${myrepo}/sample-app:wine \ - --publish \ - --run-image ${myrepo}/sample-stack-run:nanoserver-1809-wine \ - --builder cnbs/sample-builder:wine \ - --path ../../apps/batch-script/ \ - --trust-builder -``` - -After, with a WCOW daemon -```bash -docker run --rm ${myrepo}/sample-app:wine -## output: Buildpacks.io ASCII banner -``` - -### How it works -* Builder is a Linux image but with a Windows lifecycle. -* Linux build-phase container runs [`lifecycle-wrapper.sh`](../../stacks/wine/build/bin/lifecycle-wrapper.sh) instead of normal Linux `lifecycle` binary. -* Lifecycle wrapper does the following: - * Maps Linux container CNB dirs into Wine environment. - * Sets up Wine dependencies. - * Proxies `/var/run/docker.sock` to `127.0.0.1:2375` and sets `DOCKER_HOST`. - * Execs `wine lifecycle.exe`, using phase name and arguments. -* `lifecycle.exe` runs normally as if in a Windows runtime environment: - * Executes Windows-formatted buildpack executables (`.bat`,`.exe`), profile scripts, etc. - * Exports app images in Windows format to either a registry or local daemon (with `scratch`-based run-image, unless otherwise specified). diff --git a/builders/wine/builder.toml b/builders/wine/builder.toml deleted file mode 100644 index 0205aa5..0000000 --- a/builders/wine/builder.toml +++ /dev/null @@ -1,19 +0,0 @@ -# Buildpacks to include in builder -[[buildpacks]] -uri = "../../buildpacks/hello-world-windows" - -# Order used for detection -[[order]] -[[order.group]] -id = "samples/hello-world-windows" -version = "0.0.1" - -# Stack that will be used by the builder -[stack] -id = "io.buildpacks.samples.stacks.wine" -run-image = "cnbs/sample-stack-run:wine" -build-image = "cnbs/sample-stack-build:wine" - -# Requires explicit Windows lifecycle to override pack's Linux default -[lifecycle] -uri = "https://github.com/buildpacks/lifecycle/releases/download/v0.10.2/lifecycle-v0.10.2+windows.x86-64.tgz" diff --git a/buildpacks/dotnet-framework/bin/build.bat b/buildpacks/dotnet-framework/bin/build.bat index b7e605e..e6accbb 100644 --- a/buildpacks/dotnet-framework/bin/build.bat +++ b/buildpacks/dotnet-framework/bin/build.bat @@ -15,6 +15,7 @@ if not exist %layer_path% ( if not exist %layer_toml_path% ( ( + echo [types] echo launch = false echo build = true echo cache = true @@ -40,5 +41,5 @@ if %ERRORLEVEL% NEQ 0 ( ( echo [[processes]] echo type = "web" -echo command = "C:\\ServiceMonitor.exe w3svc" +echo command = ["C:\\ServiceMonitor.exe", "w3svc"] ) >> %launch_toml_path% diff --git a/buildpacks/dotnet-framework/buildpack.toml b/buildpacks/dotnet-framework/buildpack.toml index 50faa9f..5469e66 100755 --- a/buildpacks/dotnet-framework/buildpack.toml +++ b/buildpacks/dotnet-framework/buildpack.toml @@ -1,4 +1,4 @@ -api = "0.2" +api = "0.9" [buildpack] id = "samples/dotnet-framework" diff --git a/buildpacks/hello-extensions/bin/build b/buildpacks/hello-extensions/bin/build index 3795acb..0c9f764 100755 --- a/buildpacks/hello-extensions/bin/build +++ b/buildpacks/hello-extensions/bin/build @@ -13,4 +13,9 @@ type = "curl" command = ["curl"] args = ["--version"] default = true + +[[processes]] +type = "cowsay" +command = ["cowsay"] +args = ["MOOOO!"] EOL diff --git a/buildpacks/hello-extensions/bin/detect b/buildpacks/hello-extensions/bin/detect index bb79afb..a73888e 100755 --- a/buildpacks/hello-extensions/bin/detect +++ b/buildpacks/hello-extensions/bin/detect @@ -1,16 +1,32 @@ #!/usr/bin/env bash set -eo pipefail +if [[ -z "${BP_EXT_DEMO}" ]]; then + exit 100 +fi + # 1. GET ARGS plan_path=$2 # 2. DECLARE DEPENDENCIES (OPTIONAL) -cat >> "${plan_path}" <>"${plan_path}" <>"${plan_path}" <>"${plan_path}" < Hello processes buildpack" # INPUT ARGUMENTS -env_dir=$2/env layers_dir=$1 -plan_path=$3 +env_dir=$2/env # ADD SYS-INFO PROCESS echo "---> Adding sys-info process" @@ -14,6 +13,7 @@ sysinfo_layer_dir="${layers_dir}/sys-info" mkdir -p ${sysinfo_layer_dir} cat > "${sysinfo_layer_dir}.toml" << EOF +[types] launch = true EOF @@ -30,7 +30,7 @@ chmod +x ${sysinfo_script} cat >> "${layers_dir}/launch.toml" < Done" diff --git a/buildpacks/hello-processes/buildpack.toml b/buildpacks/hello-processes/buildpack.toml index 41aac1d..d467050 100644 --- a/buildpacks/hello-processes/buildpack.toml +++ b/buildpacks/hello-processes/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] diff --git a/buildpacks/hello-universe-windows/buildpack.toml b/buildpacks/hello-universe-windows/buildpack.toml index b52f12a..75cf44b 100644 --- a/buildpacks/hello-universe-windows/buildpack.toml +++ b/buildpacks/hello-universe-windows/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] diff --git a/buildpacks/hello-universe/buildpack.toml b/buildpacks/hello-universe/buildpack.toml index 777862b..0587c27 100644 --- a/buildpacks/hello-universe/buildpack.toml +++ b/buildpacks/hello-universe/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] diff --git a/buildpacks/hello-world-windows/buildpack.toml b/buildpacks/hello-world-windows/buildpack.toml index e77413e..51d30f0 100644 --- a/buildpacks/hello-world-windows/buildpack.toml +++ b/buildpacks/hello-world-windows/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] @@ -16,6 +16,3 @@ id = "io.buildpacks.samples.stacks.nanoserver-1809" [[stacks]] id = "io.buildpacks.samples.stacks.dotnet-framework-2022" - -[[stacks]] -id = "io.buildpacks.samples.stacks.wine" diff --git a/buildpacks/hello-world/buildpack.toml b/buildpacks/hello-world/buildpack.toml index a063eb0..0c7c40c 100644 --- a/buildpacks/hello-world/buildpack.toml +++ b/buildpacks/hello-world/buildpack.toml @@ -1,5 +1,5 @@ # Buildpack API version -api = "0.2" +api = "0.9" # Buildpack ID and metadata [buildpack] diff --git a/buildpacks/java-maven/bin/build b/buildpacks/java-maven/bin/build index 9ef9364..40793f2 100755 --- a/buildpacks/java-maven/bin/build +++ b/buildpacks/java-maven/bin/build @@ -42,6 +42,7 @@ if [[ ${jdk_url} != ${cached_jdk_url} ]] ; then wget -q -O - "$jdk_url" | tar pxz -C "${jdk_layer_dir}" --strip-components=1 cat > "${jdk_layer_dir}.toml" << EOF +[types] launch = true build = true cache = true @@ -80,7 +81,10 @@ export PATH=${jdk_layer_dir}/bin:$PATH m2_layer_dir="${layers_dir}/maven_m2" if [[ ! -d ${m2_layer_dir} ]]; then mkdir -p ${m2_layer_dir} - echo "cache = true" > ${m2_layer_dir}.toml + cat > ${m2_layer_dir}.toml << EOF +[types] +cache = true +EOF fi ln -s ${m2_layer_dir} $HOME/.m2 @@ -101,6 +105,7 @@ else mkdir -p "${maven_layer_dir}" wget -q -O - "${maven_url}" | tar pxz -C "${maven_layer_dir}" --strip-components=1 cat > "${maven_layer_dir}.toml" << EOF +[types] launch = true build = true cache = true @@ -122,7 +127,8 @@ for jar_file in $(find "$target_dir" -maxdepth 1 -name "*.jar" -type f); do cat >> "${layers_dir}/launch.toml" < "${jdk_layer_dir}.toml" << EOF +[types] launch = true build = true cache = true @@ -77,13 +78,16 @@ gradle_layer_dir="${layers_dir}/gradle" if [[ ! -d ${gradle_layer_dir} ]]; then mkdir -p ${gradle_layer_dir} - echo "cache = true" > ${gradle_layer_dir}.toml + cat >> ${gradle_layer_dir}.toml < Running Gradle Wrapper" -./gradlew clean build -x test --no-daemon +GRADLE_OPTS=-Dorg.gradle.daemon=false ./gradlew clean build -x test # 6. SET DEFAULT START COMMAND target_dir="build/libs" @@ -91,7 +95,7 @@ for jar_file in $(find "$target_dir" -maxdepth 1 -name "*.jar" -type f); do cat >> "${layers_dir}/launch.toml" < Downloading and extracting Ruby ${ruby_version}" ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-${ruby_version}.tgz @@ -20,6 +20,7 @@ wget -q -O - "${ruby_url}" | tar -xzf - -C "${ruby_layer_dir}" # 3. MAKE RUBY AVAILABLE DURING LAUNCH cat > "${ruby_layer_dir}.toml" < Installing gems" mkdir "${bundler_layer_dir}" cat > "${bundler_layer_dir}.toml" <> "${layers_dir}/launch.toml" <> "${plan_path}" <>"${output_dir}/run.Dockerfile" <> "${output_dir}/run.Dockerfile" <>"${output_dir}/run.Dockerfile" < /tmp/wine-build-init.log 2>&1; then - echo "Wine stack wrapper failed to initialize:" - cat /tmp/wine-build-init.log - exit 1 -fi - -exec wine64 $0.exe $* diff --git a/stacks/wine/run/Dockerfile b/stacks/wine/run/Dockerfile deleted file mode 100755 index 819f9da..0000000 --- a/stacks/wine/run/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -# Based on scratch since lifecycle will export Windows-formatted images that cannot run on Linux but can be inspected and rebased. -FROM scratch - -# Set required CNB information -ARG stack_id -LABEL io.buildpacks.stack.id="${stack_id}" - -# Add any file to create a minimal top layer, required for pack -COPY Dockerfile /top-layer-placeholder