diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73f5539e1..f15c31b34 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,62 +55,10 @@ jobs: run: | make format || true make test - test-windows: - runs-on: windows-2019 - steps: - - name: Set git to use LF and symlinks - run: | - git config --global core.autocrlf false - git config --global core.eol lf - git config --global core.symlinks true - - uses: actions/checkout@v4 - with: - fetch-depth: '0' - - name: Setup go - uses: actions/setup-go@v5 - with: - check-latest: true - go-version-file: 'go.mod' - - name: Add runner IP to daemon insecure-registries and firewall - shell: powershell - run: | - # Get IP from default gateway interface - $IPAddress=(Get-NetIPAddress -InterfaceAlias ((Get-NetRoute "0.0.0.0/0").InterfaceAlias) -AddressFamily IPv4)[0].IPAddress - - # Allow container-to-host registry traffic (from public interface, to the same interface) - New-NetfirewallRule -DisplayName test-registry -LocalAddress $IPAddress -RemoteAddress $IPAddress - - # create or update daemon config to allow host as insecure-registry - $config=@{} - if (Test-Path C:\ProgramData\docker\config\daemon.json) { - $config=(Get-Content C:\ProgramData\docker\config\daemon.json | ConvertFrom-json) - } - $config | Add-Member -Force -Name "insecure-registries" -value @("$IPAddress/32") -MemberType NoteProperty - $config | Add-Member -Force -Name "allow-nondistributable-artifacts" -value @("$IPAddress/32") -MemberType NoteProperty - ConvertTo-json $config | Out-File -Encoding ASCII C:\ProgramData\docker\config\daemon.json - - Restart-Service docker - - # dump docker info for auditing - docker version - docker info - - name: Test - env: - TEST_COVERAGE: 1 - run: | - make test - - name: Prepare Codecov - uses: crazy-max/ghaction-chocolatey@v3 - with: - args: install codecov -y - - name: Run Codecov - run: | - codecov.exe -f .\out\tests\coverage-unit.txt -v --flag os_windows build-and-publish: needs: - test-linux-amd64 - test-linux-arm64 - - test-windows runs-on: ubuntu-latest permissions: id-token: write @@ -176,14 +124,6 @@ jobs: with: name: lifecycle-linux-s390x-sha256 path: out/lifecycle-v*+linux.s390x.tgz.sha256 - - uses: actions/upload-artifact@v4 - with: - name: lifecycle-windows-x86-64 - path: out/lifecycle-v*+windows.x86-64.tgz - - uses: actions/upload-artifact@v4 - with: - name: lifecycle-windows-x86-64-sha256 - path: out/lifecycle-v*+windows.x86-64.tgz.sha256 - name: Generate SBOM JSON uses: CycloneDX/gh-gomod-generate-sbom@v2 with: @@ -229,15 +169,11 @@ jobs: LINUX_S390X_SHA=$(go run ./tools/image/main.go -lifecyclePath ./out/lifecycle-v*+linux.s390x.tgz -tag buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-linux-s390x -arch s390x | awk '{print $NF}') echo "LINUX_S390X_SHA: $LINUX_S390X_SHA" - WINDOWS_AMD64_SHA=$(go run ./tools/image/main.go -lifecyclePath ./out/lifecycle-v*+windows.x86-64.tgz -tag buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-windows -os windows | awk '{print $NF}') - echo "WINDOWS_AMD64_SHA: $WINDOWS_AMD64_SHA" - docker manifest create buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG} \ buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-linux-x86-64@${LINUX_AMD64_SHA} \ buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-linux-arm64@${LINUX_ARM64_SHA} \ buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-linux-ppc64le@${LINUX_PPC64LE_SHA} \ - buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-linux-s390x@${LINUX_S390X_SHA} \ - buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-windows@${WINDOWS_AMD64_SHA} + buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}-linux-s390x@${LINUX_S390X_SHA} MANIFEST_SHA=$(docker manifest push buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}) echo "MANIFEST_SHA: $MANIFEST_SHA" diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index b95a28ff2..43f3d5602 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -24,7 +24,7 @@ jobs: exit 1 fi echo "LIFECYCLE_VERSION=$version" >> $GITHUB_ENV - - name: Determine download urls for linux-x86-64, linux-arm64, linux-ppc64le, linux-s390x, and windows + - name: Determine download urls for linux-x86-64, linux-arm64, linux-ppc64le, linux-s390x id: artifact-urls # FIXME: this script should be updated to work with actions/github-script@v6 uses: actions/github-script@v3 diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml index 5112a21ec..6fb02595f 100644 --- a/.github/workflows/post-release.yml +++ b/.github/workflows/post-release.yml @@ -48,9 +48,6 @@ jobs: echo "LINUX_S390X_SHA: $LINUX_S390X_SHA" echo "LINUX_S390X_SHA=$LINUX_S390X_SHA" >> $GITHUB_ENV - WINDOWS_AMD64_SHA=$(cosign verify --certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/build.yml" --certificate-oidc-issuer https://token.actions.githubusercontent.com buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-windows | jq -r .[0].critical.image.\"docker-manifest-digest\") - echo "WINDOWS_AMD64_SHA: $WINDOWS_AMD64_SHA" - echo "WINDOWS_AMD64_SHA=$WINDOWS_AMD64_SHA" >> $GITHUB_ENV - name: Download SBOM run: | gh release download --pattern '*-bom.cdx.json' ${{ github.event.release.tag_name }} @@ -64,14 +61,12 @@ jobs: crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-arm64@${{ env.LINUX_ARM64_SHA }} ${{ env.LIFECYCLE_VERSION }}-linux-arm64 crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-ppc64le@${{ env.LINUX_PPC64LE_SHA }} ${{ env.LIFECYCLE_VERSION }}-linux-ppc64le crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-s390x@${{ env.LINUX_S390X_SHA }} ${{ env.LIFECYCLE_VERSION }}-linux-s390x - crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-windows@${{ env.WINDOWS_AMD64_SHA }} ${{ env.LIFECYCLE_VERSION }}-windows docker manifest create buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }} \ buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}-linux-x86-64@${{ env.LINUX_AMD64_SHA }} \ buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}-linux-arm64@${{ env.LINUX_ARM64_SHA }} \ buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}-linux-ppc64le@${{ env.LINUX_PPC64LE_SHA }} \ - buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}-linux-s390x@${{ env.LINUX_S390X_SHA }} \ - buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}-windows@${{ env.WINDOWS_AMD64_SHA }} + buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}-linux-s390x@${{ env.LINUX_S390X_SHA }} MANIFEST_SHA=$(docker manifest push buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}) echo "MANIFEST_SHA: $MANIFEST_SHA" @@ -103,14 +98,12 @@ jobs: crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-arm64@${{ env.LINUX_ARM64_SHA }} latest-linux-arm64 crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-ppc64le@${{ env.LINUX_PPC64LE_SHA }} latest-linux-ppc64le crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-s390x@${{ env.LINUX_S390X_SHA }} latest-linux-s390x - crane tag buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-windows@${{ env.WINDOWS_AMD64_SHA }} latest-windows docker manifest create buildpacksio/lifecycle:latest \ buildpacksio/lifecycle:latest-linux-x86-64@${{ env.LINUX_AMD64_SHA }} \ buildpacksio/lifecycle:latest-linux-arm64@${{ env.LINUX_ARM64_SHA }} \ buildpacksio/lifecycle:latest-linux-ppc64le@${{ env.LINUX_PPC64LE_SHA }} \ - buildpacksio/lifecycle:latest-linux-s390x@${{ env.LINUX_S390X_SHA }} \ - buildpacksio/lifecycle:latest-windows@${{ env.WINDOWS_AMD64_SHA }} + buildpacksio/lifecycle:latest-linux-s390x@${{ env.LINUX_S390X_SHA }} MANIFEST_SHA=$(docker manifest push buildpacksio/lifecycle:latest) echo "MANIFEST_SHA: $MANIFEST_SHA" diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 3dffd06ea..46fbdd4be 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -21,7 +21,7 @@ * Windows: * `choco install cygwin make -y` * `[Environment]::SetEnvironmentVariable("PATH", "C:\tools\cygwin\bin;$ENV:PATH", "MACHINE")` - + ### Caveats * The acceptance tests require the docker daemon to be able to communicate with a local containerized insecure registry. On Docker Desktop 3.3.x, this may result in failures such as: `Expected nil: push response: : Get http://localhost:/v2/: dial tcp [::1]:: connect: connection refused`. To fix these failures, it may be necessary to add the following to the Docker Desktop Engine config: @@ -32,17 +32,6 @@ ] ``` -* Some of the Windows acceptance tests use license restricted base images. By default, the docker deamon will not publish layers from these images when pushing to a registry which can result in test failures with error messages such as: `Ignoring image "X" because it was corrupt`. To fix these failures you must [enable pushing nondistributable artifacts](https://docs.docker.com/engine/reference/commandline/dockerd/#allow-push-of-nondistributable-artifacts) to the test registry by adding the following to your Docker Desktop Engine config: - * `%programdata%\docker\config\daemon.json`: - -``` -{ - "allow-nondistributable-artifacts": [ - "/32" - ] -} -``` - ### Testing GitHub actions on forks The lifecycle release process involves chaining a series of GitHub actions together such that: @@ -57,7 +46,7 @@ For the fork, it is necessary to add the following secrets: * DOCKER_PASSWORD (if not using ghcr.io) * DOCKER_USERNAME (if not using ghcr.io) -The tools/test-fork.sh script can be used to update the source code to reflect the state of the fork. +The tools/test-fork.sh script can be used to update the source code to reflect the state of the fork. It can be invoked like so: `./tools/test-fork.sh ` ## Tasks diff --git a/IMAGE.md b/IMAGE.md index 83a810fdd..4c31a9c32 100644 --- a/IMAGE.md +++ b/IMAGE.md @@ -7,7 +7,6 @@ This image is maintained by the [Cloud Native Buildpacks project](https://buildp Supported tags are semver-versioned manifest lists - e.g., `0.12.0` or `0.12.0-rc.1`, pointing to one of the following os/architectures: * `linux/amd64` * `linux/arm64` -* `windows/amd64` # About this image @@ -42,4 +41,4 @@ With [tekton](https://github.com/tektoncd/catalog/tree/main/task/buildpacks-phas * Provide as param `LIFECYCLE_IMAGE` in taskrun *** -[Source](https://github.com/buildpacks/lifecycle/blob/main/IMAGE.md) for this page \ No newline at end of file +[Source](https://github.com/buildpacks/lifecycle/blob/main/IMAGE.md) for this page diff --git a/Makefile b/Makefile index 3e00c2473..c9e124f2b 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,6 @@ LDFLAGS+=-X 'github.com/buildpacks/lifecycle/cmd.Version=$(LIFECYCLE_VERSION)' GOBUILD:=go build $(GOFLAGS) -ldflags "$(LDFLAGS)" GOTEST=$(GOCMD) test $(GOFLAGS) BUILD_DIR?=$(PWD)$/out -WINDOWS_COMPILATION_IMAGE?=golang:1.23-windowsservercore-1809 SOURCE_COMPILATION_IMAGE?=lifecycle-img BUILD_CTR?=lifecycle-ctr DOCKER_CMD?=make test @@ -39,11 +38,10 @@ GOFILES := $(shell $(GOCMD) run tools$/lister$/main.go) all: test build package -build: build-linux-amd64 build-linux-arm64 build-windows-amd64 build-linux-ppc64le build-linux-s390x +build: build-linux-amd64 build-linux-arm64 build-linux-ppc64le build-linux-s390x build-linux-amd64: build-linux-amd64-lifecycle build-linux-amd64-symlinks build-linux-amd64-launcher build-linux-arm64: build-linux-arm64-lifecycle build-linux-arm64-symlinks build-linux-arm64-launcher -build-windows-amd64: build-windows-amd64-lifecycle build-windows-amd64-symlinks build-windows-amd64-launcher build-linux-ppc64le: build-linux-ppc64le-lifecycle build-linux-ppc64le-symlinks build-linux-ppc64le-launcher build-linux-s390x: build-linux-s390x-lifecycle build-linux-s390x-symlinks build-linux-s390x-launcher @@ -57,11 +55,6 @@ build-image-linux-arm64: ARCHIVE_PATH=$(BUILD_DIR)/lifecycle-v$(LIFECYCLE_VERSIO build-image-linux-arm64: $(GOCMD) run ./tools/image/main.go -daemon -lifecyclePath $(ARCHIVE_PATH) -os linux -arch arm64 -tag lifecycle:$(LIFECYCLE_IMAGE_TAG) -build-image-windows-amd64: build-windows-amd64 package-windows-amd64 -build-image-windows-amd64: ARCHIVE_PATH=$(BUILD_DIR)/lifecycle-v$(LIFECYCLE_VERSION)+windows.x86-64.tgz -build-image-windows-amd64: - $(GOCMD) run ./tools/image/main.go -daemon -lifecyclePath $(ARCHIVE_PATH) -os windows -arch amd64 -tag lifecycle:$(LIFECYCLE_IMAGE_TAG) - build-image-linux-ppc64le: build-linux-ppc64le package-linux-ppc64le build-image-linux-ppc64le: ARCHIVE_PATH=$(BUILD_DIR)/lifecycle-v$(LIFECYCLE_VERSION)+linux.ppc64le.tgz build-image-linux-ppc64le: @@ -220,56 +213,6 @@ build-linux-s390x-symlinks: ln -sf lifecycle $(OUT_DIR)/creator ln -sf lifecycle $(OUT_DIR)/extender -build-windows-amd64-lifecycle: $(BUILD_DIR)/windows-amd64/lifecycle/lifecycle.exe - -$(BUILD_DIR)/windows-amd64/lifecycle/lifecycle.exe: export GOOS:=windows -$(BUILD_DIR)/windows-amd64/lifecycle/lifecycle.exe: export GOARCH:=amd64 -$(BUILD_DIR)/windows-amd64/lifecycle/lifecycle.exe: OUT_DIR?=$(BUILD_DIR)$/$(GOOS)-$(GOARCH)$/lifecycle -$(BUILD_DIR)/windows-amd64/lifecycle/lifecycle.exe: $(GOFILES) -$(BUILD_DIR)/windows-amd64/lifecycle/lifecycle.exe: - @echo "> Building lifecycle/lifecycle for $(GOOS)/$(GOARCH)..." - $(GOBUILD) -o $(OUT_DIR)$/lifecycle.exe -a .$/cmd$/lifecycle - -build-windows-amd64-launcher: $(BUILD_DIR)/windows-amd64/lifecycle/launcher.exe - -$(BUILD_DIR)/windows-amd64/lifecycle/launcher.exe: export GOOS:=windows -$(BUILD_DIR)/windows-amd64/lifecycle/launcher.exe: export GOARCH:=amd64 -$(BUILD_DIR)/windows-amd64/lifecycle/launcher.exe: OUT_DIR?=$(BUILD_DIR)$/$(GOOS)-$(GOARCH)$/lifecycle -$(BUILD_DIR)/windows-amd64/lifecycle/launcher.exe: $(GOFILES) -$(BUILD_DIR)/windows-amd64/lifecycle/launcher.exe: - @echo "> Building lifecycle/launcher for $(GOOS)/$(GOARCH)..." - $(GOBUILD) -o $(OUT_DIR)$/launcher.exe -a .$/cmd$/launcher - -build-windows-amd64-symlinks: export GOOS:=windows -build-windows-amd64-symlinks: export GOARCH:=amd64 -build-windows-amd64-symlinks: OUT_DIR?=$(BUILD_DIR)$/$(GOOS)-$(GOARCH)$/lifecycle -build-windows-amd64-symlinks: - @echo "> Creating phase symlinks for Windows..." -ifeq ($(OS),Windows_NT) - call del $(OUT_DIR)$/detector.exe - call del $(OUT_DIR)$/analyzer.exe - call del $(OUT_DIR)$/restorer.exe - call del $(OUT_DIR)$/builder.exe - call del $(OUT_DIR)$/exporter.exe - call del $(OUT_DIR)$/rebaser.exe - call del $(OUT_DIR)$/creator.exe - call mklink $(OUT_DIR)$/detector.exe lifecycle.exe - call mklink $(OUT_DIR)$/analyzer.exe lifecycle.exe - call mklink $(OUT_DIR)$/restorer.exe lifecycle.exe - call mklink $(OUT_DIR)$/builder.exe lifecycle.exe - call mklink $(OUT_DIR)$/exporter.exe lifecycle.exe - call mklink $(OUT_DIR)$/rebaser.exe lifecycle.exe - call mklink $(OUT_DIR)$/creator.exe lifecycle.exe -else - ln -sf lifecycle.exe $(OUT_DIR)$/detector.exe - ln -sf lifecycle.exe $(OUT_DIR)$/analyzer.exe - ln -sf lifecycle.exe $(OUT_DIR)$/restorer.exe - ln -sf lifecycle.exe $(OUT_DIR)$/builder.exe - ln -sf lifecycle.exe $(OUT_DIR)$/exporter.exe - ln -sf lifecycle.exe $(OUT_DIR)$/rebaser.exe - ln -sf lifecycle.exe $(OUT_DIR)$/creator.exe -endif - ## DARWIN ARM64/AMD64 include lifecycle.mk include launcher.mk @@ -297,15 +240,7 @@ build-darwin-amd64-launcher: $(eval OUT_DIR := $(BUILD_DIR)/$(TARGET)/lifecycle) $(call build_launcher) -generate-sbom: run-syft-windows run-syft-linux-amd64 run-syft-linux-arm64 run-syft-linux-ppc64le run-syft-linux-s390x - -run-syft-windows: install-syft -run-syft-windows: export GOOS:=windows -run-syft-windows: export GOARCH:=amd64 -run-syft-windows: - @echo "> Running syft..." - syft $(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/lifecycle.exe -o json=$(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/lifecycle.sbom.syft.json -o spdx-json=$(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/lifecycle.sbom.spdx.json -o cyclonedx-json=$(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/lifecycle.sbom.cdx.json - syft $(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/launcher.exe -o json=$(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/launcher.sbom.syft.json -o spdx-json=$(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/launcher.sbom.spdx.json -o cyclonedx-json=$(BUILD_DIR)/$(GOOS)-$(GOARCH)/lifecycle/launcher.sbom.cdx.json +generate-sbom: run-syft-linux-amd64 run-syft-linux-arm64 run-syft-linux-ppc64le run-syft-linux-s390x run-syft-linux-amd64: install-syft run-syft-linux-amd64: export GOOS:=linux @@ -400,7 +335,7 @@ clean: @echo "> Cleaning workspace..." rm -rf $(BUILD_DIR) -package: generate-sbom package-linux-amd64 package-linux-arm64 package-windows-amd64 package-linux-ppc64le package-linux-s390x +package: generate-sbom package-linux-amd64 package-linux-arm64 package-linux-ppc64le package-linux-s390x package-linux-amd64: GOOS:=linux package-linux-amd64: GOARCH:=amd64 @@ -437,26 +372,3 @@ package-linux-s390x: PACKAGER=./tools/packager/main.go package-linux-s390x: @echo "> Packaging lifecycle for $(GOOS)/$(GOARCH)..." $(GOCMD) run $(PACKAGER) --inputDir $(INPUT_DIR) -archivePath $(ARCHIVE_PATH) -descriptorPath $(LIFECYCLE_DESCRIPTOR_PATH) -version $(LIFECYCLE_VERSION) - -package-windows-amd64: GOOS:=windows -package-windows-amd64: GOARCH:=amd64 -package-windows-amd64: INPUT_DIR:=$(BUILD_DIR)$/$(GOOS)-$(GOARCH)$/lifecycle -package-windows-amd64: ARCHIVE_PATH=$(BUILD_DIR)$/lifecycle-v$(LIFECYCLE_VERSION)+$(GOOS).x86-64.tgz -package-windows-amd64: PACKAGER=.$/tools$/packager$/main.go -package-windows-amd64: - @echo "> Packaging lifecycle for $(GOOS)/$(GOARCH)..." - $(GOCMD) run $(PACKAGER) --inputDir $(INPUT_DIR) -archivePath $(ARCHIVE_PATH) -descriptorPath $(LIFECYCLE_DESCRIPTOR_PATH) -version $(LIFECYCLE_VERSION) - -# Ensure workdir is clean and build image from .git -docker-build-source-image-windows: $(GOFILES) -docker-build-source-image-windows: - $(if $(shell git status --short), @echo Uncommitted changes. Refusing to run. && exit 1) - docker build .git -f tools/Dockerfile.windows --tag $(SOURCE_COMPILATION_IMAGE) --build-arg image_tag=$(WINDOWS_COMPILATION_IMAGE) --cache-from=$(SOURCE_COMPILATION_IMAGE) --isolation=process --compress - -docker-run-windows: docker-build-source-image-windows -docker-run-windows: - @echo "> Running '$(DOCKER_CMD)' in docker windows..." - @docker volume rm -f lifecycle-out - docker run -v lifecycle-out:c:/lifecycle/out -e LIFECYCLE_VERSION -e PLATFORM_API -e BUILDPACK_API -v gopathcache:c:/gopath -v '\\.\pipe\docker_engine:\\.\pipe\docker_engine' --isolation=process --interactive --tty --rm $(SOURCE_COMPILATION_IMAGE) $(DOCKER_CMD) - docker run -v lifecycle-out:c:/lifecycle/out --rm $(SOURCE_COMPILATION_IMAGE) tar -cf- out | tar -xf- - @docker volume rm -f lifecycle-out diff --git a/acceptance/analyzer_test.go b/acceptance/analyzer_test.go index 23abb9e45..6103e80cc 100644 --- a/acceptance/analyzer_test.go +++ b/acceptance/analyzer_test.go @@ -5,7 +5,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "testing" @@ -128,8 +127,6 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe when("the provided layers directory isn't writeable", func() { it("recursively chowns the directory", func() { - h.SkipIf(t, runtime.GOOS == "windows", "Not relevant on Windows") - analyzeFlags := []string{"-run-image", analyzeRegFixtures.ReadOnlyRunImage} output := h.DockerRun(t, @@ -202,8 +199,6 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe }) it("drops privileges", func() { - h.SkipIf(t, runtime.GOOS == "windows", "Not relevant on Windows") - analyzeArgs := []string{ "-analyzed", "/some-dir/some-analyzed.toml", "-run-image", analyzeRegFixtures.ReadOnlyRunImage, diff --git a/acceptance/builder_test.go b/acceptance/builder_test.go index eae152686..16075da34 100644 --- a/acceptance/builder_test.go +++ b/acceptance/builder_test.go @@ -6,7 +6,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "testing" "github.com/sclevine/spec" @@ -25,8 +24,6 @@ var ( ) func TestBuilder(t *testing.T) { - h.SkipIf(t, runtime.GOOS == "windows", "Builder acceptance tests are not yet supported on Windows") - info, err := h.DockerCli(t).Info(context.TODO()) h.AssertNil(t, err) diff --git a/acceptance/creator_test.go b/acceptance/creator_test.go index 30580bc77..0a74c5f4c 100644 --- a/acceptance/creator_test.go +++ b/acceptance/creator_test.go @@ -6,7 +6,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "testing" "time" @@ -30,8 +29,6 @@ var ( ) func TestCreator(t *testing.T) { - h.SkipIf(t, runtime.GOOS == "windows", "Creator acceptance tests are not yet supported on Windows") - testImageDockerContext := filepath.Join("testdata", "creator") createTest = NewPhaseTest(t, "creator", testImageDockerContext) createTest.Start(t) diff --git a/acceptance/detector_test.go b/acceptance/detector_test.go index b29e84ef5..4f24f6cd5 100644 --- a/acceptance/detector_test.go +++ b/acceptance/detector_test.go @@ -8,7 +8,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "testing" "github.com/sclevine/spec" @@ -29,8 +28,6 @@ var ( ) func TestDetector(t *testing.T) { - h.SkipIf(t, runtime.GOOS == "windows", "Detector acceptance tests are not yet supported on Windows") - info, err := h.DockerCli(t).Info(context.TODO()) h.AssertNil(t, err) diff --git a/acceptance/exporter_test.go b/acceptance/exporter_test.go index 90e9ce700..bc13ee525 100644 --- a/acceptance/exporter_test.go +++ b/acceptance/exporter_test.go @@ -12,7 +12,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "testing" "time" @@ -45,8 +44,6 @@ var ( ) func TestExporter(t *testing.T) { - h.SkipIf(t, runtime.GOOS == "windows", "Exporter acceptance tests are not yet supported on Windows") - testImageDockerContext := filepath.Join("testdata", "exporter") exportTest = NewPhaseTest(t, "exporter", testImageDockerContext) diff --git a/acceptance/extender_test.go b/acceptance/extender_test.go index 973ef524f..645abed88 100644 --- a/acceptance/extender_test.go +++ b/acceptance/extender_test.go @@ -7,7 +7,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "testing" "github.com/buildpacks/imgutil/layout/sparse" @@ -45,8 +44,6 @@ const ( ) func TestExtender(t *testing.T) { - h.SkipIf(t, runtime.GOOS == "windows", "Extender is not supported on Windows") - testImageDockerContext := filepath.Join("testdata", "extender") extendTest = NewPhaseTest(t, "extender", testImageDockerContext) extendTest.Start(t) diff --git a/acceptance/launcher_test.go b/acceptance/launcher_test.go index 844183e37..51d2d5d58 100644 --- a/acceptance/launcher_test.go +++ b/acceptance/launcher_test.go @@ -4,7 +4,6 @@ import ( "fmt" "os/exec" "path/filepath" - "runtime" "strings" "testing" @@ -25,9 +24,6 @@ func TestLauncher(t *testing.T) { launchTest = NewPhaseTest(t, "launcher", testImageDockerContext, withoutDaemonFixtures, withoutRegistry) containerBinaryDir := filepath.Join("testdata", "launcher", "linux", "container", "cnb", "lifecycle") - if launchTest.targetDaemon.os == "windows" { - containerBinaryDir = filepath.Join("testdata", "launcher", "windows", "container", "cnb", "lifecycle") - } withCustomContainerBinaryDir := func(_ *testing.T, phaseTest *PhaseTest) { phaseTest.containerBinaryDir = containerBinaryDir } @@ -92,11 +88,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { "--env=CNB_PLATFORM_API="+latestPlatformAPI, launchImage, "with user provided args", ) - if runtime.GOOS == "windows" { - assertOutput(t, cmd, `Executing web process-type "with user provided args"`) - } else { - assertOutput(t, cmd, "Executing web process-type with user provided args") - } + assertOutput(t, cmd, "Executing web process-type with user provided args") }) }) @@ -109,15 +101,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { launchImage, "--", "env", ) - if runtime.GOOS == "windows" { - cmd = exec.Command( //nolint - "docker", "run", "--rm", - `--entrypoint=launcher`, - "--env=CNB_PLATFORM_API=0.7", - launchImage, "--", - "cmd", "/c", "set", - ) - } assertOutput(t, cmd, "SOME_VAR=some-bp-val", @@ -160,22 +143,11 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { launchImage, "echo", "$SOME_VAR", "$OTHER_VAR", "$WORKER_VAR", ) - if runtime.GOOS == "windows" { - cmd = exec.Command( //nolint - "docker", "run", "--rm", - "--env=CNB_PLATFORM_API="+latestPlatformAPI, - launchImage, - "echo", "%SOME_VAR%", "%OTHER_VAR%", "%WORKER_VAR%", - ) - } assertOutput(t, cmd, "sourced bp profile\nsourced app profile\nsome-bp-val other-bp-val worker-no-process-val") }) it("passes through env vars from user, excluding excluded vars", func() { args := []string{"echo", "$SOME_USER_VAR, $CNB_APP_DIR, $OTHER_VAR"} - if runtime.GOOS == "windows" { - args = []string{"echo", "%SOME_USER_VAR%, %CNB_APP_DIR%, %OTHER_VAR%"} - } cmd := exec.Command("docker", append( []string{ @@ -189,13 +161,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { args...)..., ) // #nosec G204 - if runtime.GOOS == "windows" { - // windows values with spaces will contain quotes - // empty values on windows preserve variable names instead of interpolating to empty strings - assertOutput(t, cmd, "sourced bp profile\nsourced app profile\n\"some-user-val, %CNB_APP_DIR%, other-user-val**other-bp-val\"") - } else { - assertOutput(t, cmd, "sourced bp profile\nsourced app profile\nsome-user-val, , other-user-val**other-bp-val") - } + assertOutput(t, cmd, "sourced bp profile\nsourced app profile\nsome-user-val, , other-user-val**other-bp-val") }) it("adds buildpack bin dirs to the path", func() { @@ -211,23 +177,13 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { when("CMD provided starts with --", func() { it("launches command directly", func() { - if runtime.GOOS == "windows" { - cmd := exec.Command( //nolint - "docker", "run", "--rm", - "--env=CNB_PLATFORM_API="+latestPlatformAPI, - launchImage, "--", - "ping", "/?", - ) - assertOutput(t, cmd, "Usage: ping") - } else { - cmd := exec.Command( //nolint - "docker", "run", "--rm", - "--env=CNB_PLATFORM_API="+latestPlatformAPI, - launchImage, "--", - "echo", "something", - ) - assertOutput(t, cmd, "something") - } + cmd := exec.Command( //nolint + "docker", "run", "--rm", + "--env=CNB_PLATFORM_API="+latestPlatformAPI, + launchImage, "--", + "echo", "something", + ) + assertOutput(t, cmd, "something") }) it("sets env vars from layers", func() { @@ -237,14 +193,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { launchImage, "--", "env", ) - if runtime.GOOS == "windows" { - cmd = exec.Command( //nolint - "docker", "run", "--rm", - "--env=CNB_PLATFORM_API="+latestPlatformAPI, - launchImage, "--", - "cmd", "/c", "set", - ) - } assertOutput(t, cmd, "SOME_VAR=some-bp-val", @@ -261,16 +209,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { launchImage, "--", "env", ) - if runtime.GOOS == "windows" { - cmd = exec.Command( //nolint - "docker", "run", "--rm", - "--env", "CNB_APP_DIR=/workspace", - "--env=CNB_PLATFORM_API="+latestPlatformAPI, - "--env", "SOME_USER_VAR=some-user-val", - launchImage, "--", - "cmd", "/c", "set", - ) - } output, err := cmd.CombinedOutput() if err != nil { diff --git a/acceptance/restorer_test.go b/acceptance/restorer_test.go index 2e12f146f..41561457b 100644 --- a/acceptance/restorer_test.go +++ b/acceptance/restorer_test.go @@ -6,7 +6,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "testing" "github.com/google/go-containerregistry/pkg/name" @@ -32,8 +31,6 @@ var ( ) func TestRestorer(t *testing.T) { - h.SkipIf(t, runtime.GOOS == "windows", "Restorer acceptance tests are not yet supported on Windows") - testImageDockerContext := filepath.Join("testdata", "restorer") restoreTest = NewPhaseTest(t, "restorer", testImageDockerContext) restoreTest.Start(t, updateTOMLFixturesWithTestRegistry) diff --git a/acceptance/testdata/analyzer/Dockerfile.windows b/acceptance/testdata/analyzer/Dockerfile.windows deleted file mode 100644 index 44f9d8339..000000000 --- a/acceptance/testdata/analyzer/Dockerfile.windows +++ /dev/null @@ -1,12 +0,0 @@ -FROM mcr.microsoft.com/windows/nanoserver:1809 -USER ContainerAdministrator - -COPY container / - -WORKDIR /layers - -ENV CNB_USER_ID=1 - -ENV CNB_GROUP_ID=1 - -ENV CNB_PLATFORM_API=${cnb_platform_api} diff --git a/acceptance/testdata/builder/Dockerfile.windows b/acceptance/testdata/builder/Dockerfile.windows deleted file mode 100644 index 611442193..000000000 --- a/acceptance/testdata/builder/Dockerfile.windows +++ /dev/null @@ -1,14 +0,0 @@ -FROM mcr.microsoft.com/windows/nanoserver:1809 -USER ContainerAdministrator - -COPY container / - -ENTRYPOINT ["/cnb/lifecycle/builder"] - -WORKDIR /layers - -ENV CNB_USER_ID=1 - -ENV CNB_GROUP_ID=1 - -ENV CNB_PLATFORM_API=${cnb_platform_api} diff --git a/acceptance/testdata/launcher/Dockerfile.windows b/acceptance/testdata/launcher/Dockerfile.windows deleted file mode 100644 index eccc18ef9..000000000 --- a/acceptance/testdata/launcher/Dockerfile.windows +++ /dev/null @@ -1,16 +0,0 @@ -FROM golang:1.23-nanoserver-1809 - -COPY exec.d/ /go/src/exec.d -WORKDIR /go/src -ENV GO111MODULE=off -RUN go build -o helper.exe exec.d - -COPY windows/container / - -RUN mkdir c:\layers\0.9_buildpack\some_layer\exec.d\exec.d-checker -RUN copy helper.exe c:\layers\0.9_buildpack\some_layer\exec.d\helper.exe -RUN copy helper.exe c:\layers\0.9_buildpack\some_layer\exec.d\exec.d-checker\helper.exe - -ENV PATH="c:\cnb\process;c:\cnb\lifecycle;C:\Windows\system32;C:\Windows;" - -ENTRYPOINT ["c:\\cnb\\lifecycle\\launcher"] diff --git a/acceptance/testdata/rebaser/Dockerfile.windows b/acceptance/testdata/rebaser/Dockerfile.windows deleted file mode 100644 index 2e0762721..000000000 --- a/acceptance/testdata/rebaser/Dockerfile.windows +++ /dev/null @@ -1,10 +0,0 @@ -FROM mcr.microsoft.com/windows/nanoserver:1809 -USER ContainerAdministrator - -COPY container / - -ENV CNB_USER_ID=1 - -ENV CNB_GROUP_ID=1 - -ENV CNB_PLATFORM_API=${cnb_platform_api} diff --git a/acceptance/variables_windows.go b/acceptance/variables_windows.go deleted file mode 100644 index cb7a5ece1..000000000 --- a/acceptance/variables_windows.go +++ /dev/null @@ -1,30 +0,0 @@ -package acceptance - -import ( - "path" - "path/filepath" - "strings" -) - -const ( - containerBaseImage = "mcr.microsoft.com/windows/nanoserver:1809" - containerBaseImageFull = "mcr.microsoft.com/windows/nanoserver:1809" - dockerfileName = "Dockerfile.windows" - exe = ".exe" - execDBpDir = "0.9_buildpack" -) - -var dockerSocketMount = []string{ - "--mount", `type=npipe,source=\\.\pipe\docker_engine,target=\\.\pipe\docker_engine`, - "--user", "ContainerAdministrator", -} - -// ctrPath equivalent to path.Join but converts to Windows slashes and drive prefix when needed -func ctrPath(unixPathParts ...string) string { - unixPath := path.Join(unixPathParts...) - windowsPath := filepath.FromSlash(unixPath) - if strings.HasPrefix(windowsPath, `\`) { - return "c:" + windowsPath - } - return windowsPath -} diff --git a/archive/extract_test.go b/archive/extract_test.go index 81836ffc9..f996b23bb 100644 --- a/archive/extract_test.go +++ b/archive/extract_test.go @@ -4,7 +4,6 @@ import ( "archive/tar" "os" "path/filepath" - "runtime" "testing" "github.com/sclevine/spec" @@ -31,31 +30,16 @@ func testExtract(t *testing.T, when spec.G, it spec.S) { it.Before(func() { tr, tmpDir = newFakeTarReader(t) - // Golang for Windows only implements owner permissions - if runtime.GOOS == "windows" { - pathModes = []archive.PathMode{ - {`root`, os.ModeDir + 0777}, - {`root\readonly`, os.ModeDir + 0555}, - {`root\readonly\readonlysub`, os.ModeDir + 0555}, - {`root\readonly\readonlysub\somefile`, 0444}, - {`root\standarddir`, os.ModeDir + 0777}, - {`root\standarddir\somefile`, 0666}, - {`root\nonexistdirnotintar`, os.ModeDir + 0777}, - {`root\symlinkdir`, os.ModeSymlink + 0666}, - {`root\symlinkfile`, os.ModeSymlink + 0666}, - } - } else { - pathModes = []archive.PathMode{ - {"root", os.ModeDir + 0755}, - {"root/readonly", os.ModeDir + 0500}, - {"root/readonly/readonlysub", os.ModeDir + 0500}, - {"root/readonly/readonlysub/somefile", 0444}, - {"root/standarddir", os.ModeDir + 0755}, - {"root/standarddir/somefile", 0644}, - {"root/nonexistdirnotintar", os.ModeDir + os.FileMode(int(os.ModePerm)&^originalUmask)}, - {"root/symlinkdir", os.ModeSymlink + 0777}, // symlink permissions are not preserved from archive - {"root/symlinkfile", os.ModeSymlink + 0777}, // symlink permissions are not preserved from archive - } + pathModes = []archive.PathMode{ + {"root", os.ModeDir + 0755}, + {"root/readonly", os.ModeDir + 0500}, + {"root/readonly/readonlysub", os.ModeDir + 0500}, + {"root/readonly/readonlysub/somefile", 0444}, + {"root/standarddir", os.ModeDir + 0755}, + {"root/standarddir/somefile", 0644}, + {"root/nonexistdirnotintar", os.ModeDir + os.FileMode(int(os.ModePerm)&^originalUmask)}, //nolint + {"root/symlinkdir", os.ModeSymlink + 0777}, // symlink permissions are not preserved from archive + {"root/symlinkfile", os.ModeSymlink + 0777}, // symlink permissions are not preserved from archive } }) @@ -110,12 +94,7 @@ func testExtract(t *testing.T, when spec.G, it spec.S) { fileInfo, err := os.Stat(filepath.Join(tmpDir, "root")) h.AssertNil(t, err) - if runtime.GOOS != "windows" { - h.AssertEq(t, fileInfo.Mode(), os.ModeDir+0744) - } else { - // Golang for Windows only implements owner permissions - h.AssertEq(t, fileInfo.Mode(), os.ModeDir+0777) - } + h.AssertEq(t, fileInfo.Mode(), os.ModeDir+0744) }) }) } diff --git a/archive/reader_test.go b/archive/reader_test.go index 255e68534..83871b799 100644 --- a/archive/reader_test.go +++ b/archive/reader_test.go @@ -3,7 +3,6 @@ package archive_test import ( "archive/tar" "io" - "runtime" "testing" "github.com/sclevine/spec" @@ -33,11 +32,7 @@ func testNormalizingTarReader(t *testing.T, when spec.G, it spec.S) { it("converts path separators", func() { hdr, err := ntr.Next() h.AssertNil(t, err) - if runtime.GOOS == "windows" { - h.AssertEq(t, hdr.Name, `\some\path`) - } else { - h.AssertEq(t, hdr.Name, `/some/path`) - } + h.AssertEq(t, hdr.Name, `/some/path`) }) when("#Strip", func() { @@ -45,11 +40,7 @@ func testNormalizingTarReader(t *testing.T, when spec.G, it spec.S) { ntr.Strip("/some") hdr, err := ntr.Next() h.AssertNil(t, err) - if runtime.GOOS == "windows" { - h.AssertEq(t, hdr.Name, `\path`) - } else { - h.AssertEq(t, hdr.Name, `/path`) - } + h.AssertEq(t, hdr.Name, `/path`) }) }) @@ -58,11 +49,7 @@ func testNormalizingTarReader(t *testing.T, when spec.G, it spec.S) { ntr.PrependDir("/super-dir") hdr, err := ntr.Next() h.AssertNil(t, err) - if runtime.GOOS == "windows" { - h.AssertEq(t, hdr.Name, `\super-dir\some\path`) - } else { - h.AssertEq(t, hdr.Name, `/super-dir/some/path`) - } + h.AssertEq(t, hdr.Name, `/super-dir/some/path`) }) }) @@ -73,11 +60,7 @@ func testNormalizingTarReader(t *testing.T, when spec.G, it spec.S) { ntr.ExcludePaths([]string{"excluded-dir"}) hdr, err := ntr.Next() h.AssertNil(t, err) - if runtime.GOOS == "windows" { - h.AssertEq(t, hdr.Name, `\some\path`) - } else { - h.AssertEq(t, hdr.Name, `/some/path`) - } + h.AssertEq(t, hdr.Name, `/some/path`) }) }) }) diff --git a/archive/tar_windows.go b/archive/tar_windows.go deleted file mode 100644 index a1a4621c5..000000000 --- a/archive/tar_windows.go +++ /dev/null @@ -1,57 +0,0 @@ -package archive - -import ( - "archive/tar" - "os" - "strconv" - "syscall" - - "github.com/pkg/errors" -) - -const ( - symbolicLinkFlagAllowUnprivilegedCreate = 0x2 - - // MSWINDOWS pax vendor extensions - hdrMSWindowsPrefix = "MSWINDOWS." - hdrFileAttributes = hdrMSWindowsPrefix + "fileattr" -) - -func setUmask(newMask int) (oldMask int) { - // Not implemented on Windows - return 0 -} - -// createSymlink uses the file attributes in the PAX records to decide whether to make a directory or file type symlink. -// We must use the syscall because we often create symlinks when the target does not exist and os.Symlink uses the mode -// -// of the target to create the appropriate type of symlink on windows https://github.com/golang/go/issues/39183 -func createSymlink(hdr *tar.Header) error { - var flags uint32 = symbolicLinkFlagAllowUnprivilegedCreate - if attrStr, ok := hdr.PAXRecords[hdrFileAttributes]; ok { - attr, err := strconv.ParseUint(attrStr, 10, 32) - if err != nil { - return errors.Wrapf(err, "failed to parse file attributes for header %q", hdr.Name) - } - if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { - flags |= syscall.SYMBOLIC_LINK_FLAG_DIRECTORY - } - } - - name, err := syscall.UTF16PtrFromString(hdr.Name) - if err != nil { - return err - } - target, err := syscall.UTF16PtrFromString(hdr.Linkname) - if err != nil { - return err - } - return syscall.CreateSymbolicLink(name, target, flags) -} - -// addSysAttributes adds PAXRecords containing file attributes -func addSysAttributes(hdr *tar.Header, fi os.FileInfo) { - attrs := fi.Sys().(*syscall.Win32FileAttributeData).FileAttributes - hdr.PAXRecords = map[string]string{} - hdr.PAXRecords[hdrFileAttributes] = strconv.FormatUint(uint64(attrs), 10) -} diff --git a/archive/tar_windows_test.go b/archive/tar_windows_test.go deleted file mode 100644 index 9a0c5766c..000000000 --- a/archive/tar_windows_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package archive_test - -import ( - "archive/tar" - "os" - "path/filepath" - "strconv" - "syscall" - "testing" - - "github.com/sclevine/spec" - "github.com/sclevine/spec/report" - - "github.com/buildpacks/lifecycle/archive" - h "github.com/buildpacks/lifecycle/testhelpers" -) - -func TestTarWindows(t *testing.T) { - spec.Run(t, "tarWindows", testTarWindows, spec.Report(report.Terminal{})) -} - -func testTarWindows(t *testing.T, when spec.G, it spec.S) { - var ( - tmpDir string - tr *archive.NormalizingTarReader - ftr *fakeTarReader - ) - - it.Before(func() { - var err error - tmpDir, err = os.MkdirTemp("", "archive-extract-test") - h.AssertNil(t, err) - ftr = &fakeTarReader{} - tr = archive.NewNormalizingTarReader(ftr) - tr.PrependDir(tmpDir) - }) - - it.After(func() { - h.AssertNil(t, os.RemoveAll(tmpDir)) - }) - - when("#Extract", func() { - it.Before(func() { - ftr.pushHeader(&tar.Header{ - Name: "root/symlinkdir", - Typeflag: tar.TypeSymlink, - Linkname: filepath.Join("..", "not-in-archive-dir"), - Mode: int64(os.ModeSymlink | 0755), - PAXRecords: map[string]string{ - "MSWINDOWS.fileattr": strconv.FormatUint(uint64(syscall.FILE_ATTRIBUTE_DIRECTORY), 10), - }, - }) - ftr.pushHeader(&tar.Header{ - Name: "root", - Typeflag: tar.TypeDir, - Mode: int64(os.ModeDir | 0755), - }) - }) - - it("sets dir attribute on windows directory symlinks", func() { - h.AssertNil(t, archive.Extract(tr)) - - extractedFile := filepath.Join(tmpDir, "root", "symlinkdir") - t.Log("asserting on", extractedFile) - fileInfo, err := os.Lstat(extractedFile) - h.AssertNil(t, err) - if fileInfo.Sys().(*syscall.Win32FileAttributeData).FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 { - t.Fatalf("expected directory file attribute to be set on %s", extractedFile) - } - }) - }) - - when("#Compress", func() { - var ( - tw archive.TarWriter - file *os.File - ) - it.Before(func() { - var err error - file, err = os.Create(filepath.Join(tmpDir, "tar_test-go.tar")) - h.AssertNil(t, err) - tw = &archive.NormalizingTarWriter{TarWriter: tar.NewWriter(file)} - }) - - it.After(func() { - file.Close() - }) - - it("Add PAX headers to symlink directories", func() { - h.AssertNil(t, archive.AddDirToArchive(tw, "testdata/dir-to-tar")) - h.AssertNil(t, file.Close()) - - file, err := os.Open(file.Name()) - h.AssertNil(t, err) - defer file.Close() - tr := tar.NewReader(file) - - _, err = tr.Next() // skip testdata/dir-to-tar - h.AssertNil(t, err) - - tarContains(t, "directory symlinks", func() { - header, err := tr.Next() - h.AssertNil(t, err) - - h.AssertEq(t, header.Name, "testdata/dir-to-tar/dir-link") - attrStr, ok := header.PAXRecords["MSWINDOWS.fileattr"] - if !ok { - t.Fatalf("Missing expected fileattr PAX record") - } - attr, err := strconv.ParseUint(attrStr, 10, 32) - h.AssertNil(t, err) - if attr&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 { - t.Fatalf("PAX records missing directory file attribute") - } - }) - }) - }) -} diff --git a/archive/writer_test.go b/archive/writer_test.go index 1f087a7fe..33a974460 100644 --- a/archive/writer_test.go +++ b/archive/writer_test.go @@ -2,7 +2,6 @@ package archive_test import ( "archive/tar" - "runtime" "testing" "time" @@ -38,21 +37,6 @@ func testNormalizingTarWriter(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, ftw.getLastHeader().Gname, "") }) - when("windows", func() { - it.Before(func() { - if runtime.GOOS != "windows" { - t.Skip("windows specific test") - } - }) - - it("converts path separators", func() { - h.AssertNil(t, ntw.WriteHeader(&tar.Header{ - Name: `c:\some\file\path`, - })) - h.AssertEq(t, ftw.getLastHeader().Name, "/some/file/path") - }) - }) - when("#WithUID", func() { it("sets the uid", func() { ntw.WithUID(999) diff --git a/buildpack/bp_descriptor.go b/buildpack/bp_descriptor.go index 57c582588..4fc4e0d03 100644 --- a/buildpack/bp_descriptor.go +++ b/buildpack/bp_descriptor.go @@ -87,11 +87,8 @@ func ReadBpDescriptor(path string) (*BpDescriptor, error) { return &BpDescriptor{}, err } for i := 0; i < len(binFiles); i++ { - bf := binFiles[len(binFiles)-i-1] // we're iterating backwards b/c os.ReadDir sorts "build.exe" after "build" but we want to preferentially detect windows first. + bf := binFiles[len(binFiles)-i-1] fname := bf.Name() - if fname == "build.exe" || fname == "build.bat" { - descriptor.Targets = append(descriptor.Targets, TargetMetadata{OS: "windows"}) - } if fname == "build" { descriptor.Targets = append(descriptor.Targets, TargetMetadata{OS: "linux"}) } diff --git a/buildpack/bp_descriptor_test.go b/buildpack/bp_descriptor_test.go index cd438709c..4bdc57d4e 100644 --- a/buildpack/bp_descriptor_test.go +++ b/buildpack/bp_descriptor_test.go @@ -252,24 +252,5 @@ func testBpDescriptor(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, descriptor.Targets[0].OS, "linux") h.AssertEq(t, len(descriptor.Targets[0].Distros), 0) }) - - it("detects windows/* if batch files are present and ignores linux", func() { - path := filepath.Join("testdata", "buildpack", "by-id", "A", "v1", "buildpack.toml") - descriptor, err := buildpack.ReadBpDescriptor(path) - h.AssertNil(t, err) - // common sanity assertions - h.AssertEq(t, descriptor.WithAPI, "0.7") - h.AssertEq(t, descriptor.Buildpack.ID, "A") - h.AssertEq(t, descriptor.Buildpack.Name, "Buildpack A") - h.AssertEq(t, descriptor.Buildpack.Version, "v1") - h.AssertEq(t, descriptor.Buildpack.Homepage, "Buildpack A Homepage") - h.AssertEq(t, descriptor.Buildpack.SBOM, []string{"application/vnd.cyclonedx+json"}) - // specific behaviors for this test - h.AssertEq(t, len(descriptor.Targets), 2) - h.AssertEq(t, descriptor.Targets[0].Arch, "") - h.AssertEq(t, descriptor.Targets[0].OS, "windows") - h.AssertEq(t, descriptor.Targets[1].Arch, "") - h.AssertEq(t, descriptor.Targets[1].OS, "linux") - }) }) } diff --git a/buildpack/build.go b/buildpack/build.go index 2d10cac5f..aff074570 100644 --- a/buildpack/build.go +++ b/buildpack/build.go @@ -14,7 +14,6 @@ import ( "github.com/buildpacks/lifecycle/api" "github.com/buildpacks/lifecycle/env" "github.com/buildpacks/lifecycle/internal/encoding" - "github.com/buildpacks/lifecycle/internal/fsutil" "github.com/buildpacks/lifecycle/launch" "github.com/buildpacks/lifecycle/layers" "github.com/buildpacks/lifecycle/log" @@ -202,7 +201,7 @@ func eachLayer(bpLayersDir string, fn func(layerPath string) error) error { func renameLayerDirIfNeeded(layerMetadataFile LayerMetadataFile, layerDir string) error { // rename / to /.ignore if all the types flags are set to false if !layerMetadataFile.Launch && !layerMetadataFile.Cache && !layerMetadataFile.Build { - if err := fsutil.RenameWithWindowsFallback(layerDir, layerDir+".ignore"); err != nil && !os.IsNotExist(err) { + if err := os.Rename(layerDir, layerDir+".ignore"); err != nil && !os.IsNotExist(err) { return err } } diff --git a/buildpack/detect_test.go b/buildpack/detect_test.go index 4a4db65f0..c81657dcf 100644 --- a/buildpack/detect_test.go +++ b/buildpack/detect_test.go @@ -4,7 +4,6 @@ import ( "errors" "os" "path/filepath" - "runtime" "testing" "github.com/apex/log" @@ -295,8 +294,6 @@ func testDetect(t *testing.T, when spec.G, it spec.S) { ) it.Before(func() { - h.SkipIf(t, runtime.GOOS == "windows", "Image extensions are not supported for Windows builds") - descriptorPath = filepath.Join("testdata", "extension", "by-id", "A", "v1", "extension.toml") var err error descriptor, err = buildpack.ReadExtDescriptor(descriptorPath) diff --git a/buildpack/ext_descriptor.go b/buildpack/ext_descriptor.go index 74f4ab693..5f78fb3c2 100644 --- a/buildpack/ext_descriptor.go +++ b/buildpack/ext_descriptor.go @@ -43,14 +43,10 @@ func (d *ExtDescriptor) inferTargets() error { if err != nil { return err } - var windowsDetected, linuxDetected bool + var linuxDetected bool for i := 0; i < len(binFiles); i++ { // detect and generate files are optional - bf := binFiles[len(binFiles)-i-1] // we're iterating backwards b/c os.ReadDir sorts "foo.exe" after "foo" but we want to preferentially detect windows first. + bf := binFiles[len(binFiles)-i-1] fname := bf.Name() - if !windowsDetected && (fname == "detect.exe" || fname == "detect.bat" || fname == "generate.exe" || fname == "generate.bat") { - d.Targets = append(d.Targets, TargetMetadata{OS: "windows"}) - windowsDetected = true - } if !linuxDetected && (fname == "detect" || fname == "generate") { d.Targets = append(d.Targets, TargetMetadata{OS: "linux"}) linuxDetected = true diff --git a/buildpack/ext_descriptor_test.go b/buildpack/ext_descriptor_test.go index 6a57130e6..4d31eb775 100644 --- a/buildpack/ext_descriptor_test.go +++ b/buildpack/ext_descriptor_test.go @@ -39,13 +39,5 @@ func testExtDescriptor(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, descriptor.Targets[0].OS, "") h.AssertEq(t, descriptor.Targets[0].Arch, "") }) - it("slices, it dices, it even does windows", func() { - path := filepath.Join("testdata", "extension", "by-id", "D", "v1", "extension.toml") - descriptor, err := buildpack.ReadExtDescriptor(path) - h.AssertNil(t, err) - h.AssertEq(t, len(descriptor.Targets), 1) - h.AssertEq(t, descriptor.Targets[0].OS, "windows") - h.AssertEq(t, descriptor.Targets[0].Arch, "") - }) }) } diff --git a/buildpack/generate_test.go b/buildpack/generate_test.go index b8539ccdd..d744777bd 100644 --- a/buildpack/generate_test.go +++ b/buildpack/generate_test.go @@ -5,7 +5,6 @@ import ( "errors" "os" "path/filepath" - "runtime" "strings" "testing" @@ -24,9 +23,7 @@ import ( ) func TestGenerate(t *testing.T) { - if runtime.GOOS != "windows" { - spec.Run(t, "unit-generate", testGenerate, spec.Report(report.Terminal{})) - } + spec.Run(t, "unit-generate", testGenerate, spec.Report(report.Terminal{})) } func testGenerate(t *testing.T, when spec.G, it spec.S) { diff --git a/cache/caching_image_test.go b/cache/caching_image_test.go index 31ebf3748..afdcb82a2 100644 --- a/cache/caching_image_test.go +++ b/cache/caching_image_test.go @@ -4,8 +4,6 @@ import ( "io" "os" "path/filepath" - "runtime" - "strings" "testing" "github.com/buildpacks/imgutil" @@ -70,9 +68,6 @@ func testCachingImage(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, err) defer from.Close() - if runtime.GOOS == "windows" { - layerSHA = strings.TrimPrefix(layerSHA, "sha256:") - } to, err := os.Create(filepath.Join(tmpDir, "committed", layerSHA+".tar")) h.AssertNil(t, err) defer to.Close() diff --git a/cache/volume_cache.go b/cache/volume_cache.go index 22ef827d2..afa4662b0 100644 --- a/cache/volume_cache.go +++ b/cache/volume_cache.go @@ -7,8 +7,6 @@ import ( "io" "os" "path/filepath" - "runtime" - "strings" "github.com/pkg/errors" @@ -197,13 +195,13 @@ func (c *VolumeCache) Commit() error { return errCacheCommitted } c.committed = true - if err := fsutil.RenameWithWindowsFallback(c.committedDir, c.backupDir); err != nil { + if err := os.Rename(c.committedDir, c.backupDir); err != nil { return errors.Wrap(err, "backing up cache") } defer os.RemoveAll(c.backupDir) - if err1 := fsutil.RenameWithWindowsFallback(c.stagingDir, c.committedDir); err1 != nil { - if err2 := fsutil.RenameWithWindowsFallback(c.backupDir, c.committedDir); err2 != nil { + if err1 := os.Rename(c.stagingDir, c.committedDir); err1 != nil { + if err2 := os.Rename(c.backupDir, c.committedDir); err2 != nil { return errors.Wrap(err2, "rolling back cache") } return errors.Wrap(err1, "committing cache") @@ -213,10 +211,6 @@ func (c *VolumeCache) Commit() error { } func diffIDPath(basePath, diffID string) string { - if runtime.GOOS == "windows" { - // Avoid colons in Windows file paths - diffID = strings.TrimPrefix(diffID, "sha256:") - } return filepath.Join(basePath, diffID+".tar") } diff --git a/env/build.go b/env/build.go index ee2e7f25a..7692f5faa 100644 --- a/env/build.go +++ b/env/build.go @@ -1,7 +1,6 @@ package env import ( - "runtime" "strings" ) @@ -18,7 +17,7 @@ var BuildEnvIncludelist = []string{ "no_proxy", } -var ignoreEnvVarCase = runtime.GOOS == "windows" +var ignoreEnvVarCase = false // NewBuildEnv returns a build-time Env from the given environment. // diff --git a/env/build_test.go b/env/build_test.go index 07db7e6cd..5df711588 100644 --- a/env/build_test.go +++ b/env/build_test.go @@ -1,7 +1,6 @@ package env_test import ( - "runtime" "sort" "testing" @@ -11,7 +10,6 @@ import ( "github.com/sclevine/spec/report" "github.com/buildpacks/lifecycle/env" - h "github.com/buildpacks/lifecycle/testhelpers" ) func TestBuildEnv(t *testing.T) { @@ -64,15 +62,9 @@ func testBuildEnv(t *testing.T, when spec.G, it spec.S) { "NO_PROXY=some-no-proxy", "PATH=some-path", "PKG_CONFIG_PATH=some-pkg-config-path", - } - // Environment variables in Windows are case insensitive, and are added by the lifecycle in uppercase. - if runtime.GOOS != "windows" { - expectedVars = append( - expectedVars, - "http_proxy=some-http-proxy", - "https_proxy=some-https-proxy", - "no_proxy=some-no-proxy", - ) + "http_proxy=some-http-proxy", + "https_proxy=some-https-proxy", + "no_proxy=some-no-proxy", } if s := cmp.Diff(out, expectedVars); s != "" { t.Fatalf("Unexpected env\n%s\n", s) @@ -96,22 +88,5 @@ func testBuildEnv(t *testing.T, when spec.G, it spec.S) { t.Fatalf("Unexpected root dir map\n%s\n", s) } }) - - when("building in Windows", func() { - it.Before(func() { - if runtime.GOOS != "windows" { - t.Skip("This test only applies to Windows builds") - } - }) - - it("ignores case when initializing", func() { - benv := env.NewBuildEnv([]string{ - "Path=some-path", - }) - out := benv.List() - h.AssertEq(t, len(out), 1) - h.AssertEq(t, out[0], "PATH=some-path") - }) - }) }) } diff --git a/env/env_test.go b/env/env_test.go index f9ee73281..b3f7dacc0 100644 --- a/env/env_test.go +++ b/env/env_test.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "sort" "strings" "testing" @@ -42,7 +41,7 @@ func testEnv(t *testing.T, when spec.G, it spec.S) { "LIBRARY_PATH", }, }, - Vars: env.NewVars(map[string]string{}, runtime.GOOS == "windows"), + Vars: env.NewVars(map[string]string{}, false), } }) diff --git a/env/launch_test.go b/env/launch_test.go index 681c8e920..ace158f62 100644 --- a/env/launch_test.go +++ b/env/launch_test.go @@ -2,7 +2,6 @@ package env_test import ( "os" - "runtime" "strings" "testing" @@ -11,7 +10,6 @@ import ( "github.com/sclevine/spec/report" "github.com/buildpacks/lifecycle/env" - h "github.com/buildpacks/lifecycle/testhelpers" ) func TestLaunchEnv(t *testing.T) { @@ -69,22 +67,5 @@ func testLaunchEnv(t *testing.T, when spec.G, it spec.S) { t.Fatalf("Unexpected root dir map\n%s\n", s) } }) - - when("launching in Windows", func() { - it.Before(func() { - if runtime.GOOS != "windows" { - t.Skip("This test only applies to Windows launches") - } - }) - - it("ignores case when initializing", func() { - benv := env.NewLaunchEnv([]string{ - "Path=some-path", - }, "", "") - out := benv.List() - h.AssertEq(t, len(out), 1) - h.AssertEq(t, out[0], "PATH=some-path") - }) - }) }) } diff --git a/internal/extend/kaniko/dockerfile_applier_windows.go b/internal/extend/kaniko/dockerfile_applier_windows.go deleted file mode 100644 index b3346d118..000000000 --- a/internal/extend/kaniko/dockerfile_applier_windows.go +++ /dev/null @@ -1,14 +0,0 @@ -//go:build windows - -package kaniko - -import ( - v1 "github.com/google/go-containerregistry/pkg/v1" - - "github.com/buildpacks/lifecycle/internal/extend" - "github.com/buildpacks/lifecycle/log" -) - -func (a *DockerfileApplier) Apply(dockerfile extend.Dockerfile, toBaseImage v1.Image, withBuildOptions extend.Options, logger log.Logger) (v1.Image, error) { - return nil, nil -} diff --git a/internal/fsutil/os_detection_notlinux_test.go b/internal/fsutil/os_detection_notlinux_test.go index 6da50f009..72e51bd6c 100644 --- a/internal/fsutil/os_detection_notlinux_test.go +++ b/internal/fsutil/os_detection_notlinux_test.go @@ -1,4 +1,4 @@ -//go:build windows || darwin +//go:build darwin package fsutil_test diff --git a/internal/fsutil/utils.go b/internal/fsutil/utils.go index 37aaaf665..ba315b708 100644 --- a/internal/fsutil/utils.go +++ b/internal/fsutil/utils.go @@ -4,7 +4,6 @@ import ( "io" "os" "path/filepath" - "runtime" "strings" ) @@ -97,20 +96,3 @@ func copySymlink(src, dst string) error { } return os.Symlink(target, dst) } - -func RenameWithWindowsFallback(src, dst string) error { - if err := os.Rename(src, dst); err != nil { - switch { - case runtime.GOOS == "windows": - // On Windows, when using process isolation, we could encounter https://github.com/moby/moby/issues/38256 - // which causes renames inside mounted volumes to fail for an unknown reason. - if err = copyDir(src, dst); err != nil { - return err - } - return os.RemoveAll(src) - default: - return err - } - } - return nil -} diff --git a/internal/fsutil/utils_test.go b/internal/fsutil/utils_test.go index 66e682aae..736e5b4fc 100644 --- a/internal/fsutil/utils_test.go +++ b/internal/fsutil/utils_test.go @@ -70,16 +70,6 @@ func testIO(t *testing.T, when spec.G, it spec.S) { }) }) - when("#RenameWithWindowsFallback", func() { - when("directory does not exist", func() { - it("returns not exist error", func() { - err := fsutil.RenameWithWindowsFallback("some-not-exist-dir", "dest-dir") - h.AssertNotNil(t, err) - h.AssertEq(t, os.IsNotExist(err), true) - }) - }) - }) - when("#FilesWithExtensions", func() { when("called with directory and extensions", func() { it("filters the files", func() { diff --git a/internal/layer/sbom_restorer.go b/internal/layer/sbom_restorer.go index 0af736c76..00126b098 100644 --- a/internal/layer/sbom_restorer.go +++ b/internal/layer/sbom_restorer.go @@ -7,7 +7,6 @@ import ( "os" "path/filepath" "regexp" - "runtime" "github.com/buildpacks/imgutil" "github.com/pkg/errors" @@ -111,11 +110,7 @@ func (r *DefaultSBOMRestorer) RestoreToBuildpackLayers(detectedBps []buildpack.G func (r *DefaultSBOMRestorer) restoreSBOMFunc(detectedBps []buildpack.GroupElement, bomType string) func(path string, info fs.FileInfo, err error) error { var bomRegex *regexp.Regexp - if runtime.GOOS == "windows" { - bomRegex = regexp.MustCompile(fmt.Sprintf(`%s\\(.+)\\(.+)\\(sbom.+json)`, bomType)) - } else { - bomRegex = regexp.MustCompile(fmt.Sprintf(`%s/(.+)/(.+)/(sbom.+json)`, bomType)) - } + bomRegex = regexp.MustCompile(fmt.Sprintf(`%s/(.+)/(.+)/(sbom.+json)`, bomType)) return func(path string, info fs.FileInfo, err error) error { if info == nil || !info.Mode().IsRegular() { diff --git a/launch/bash_test.go b/launch/bash_test.go index 9a92df66a..21767cf87 100644 --- a/launch/bash_test.go +++ b/launch/bash_test.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "testing" "github.com/sclevine/spec" @@ -26,7 +25,6 @@ func testBash(t *testing.T, when spec.G, it spec.S) { ) it.Before(func() { - h.SkipIf(t, runtime.GOOS == "windows", "skip bash tests on windows") var err error tmpDir, err = os.MkdirTemp("", "shell-test") h.AssertNil(t, err) diff --git a/launch/cmd_test.go b/launch/cmd_test.go deleted file mode 100644 index 32af03b71..000000000 --- a/launch/cmd_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package launch_test - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - "testing" - - "github.com/sclevine/spec" - "github.com/sclevine/spec/report" - - "github.com/buildpacks/lifecycle/launch" - hl "github.com/buildpacks/lifecycle/launch/testhelpers" - h "github.com/buildpacks/lifecycle/testhelpers" -) - -func TestCmd(t *testing.T) { - spec.Run(t, "Cmd", testCmd, spec.Report(report.Terminal{})) -} - -func testCmd(t *testing.T, when spec.G, it spec.S) { - var ( - shell launch.Shell - tmpDir string - defaultDir string - err error - ) - - it.Before(func() { - defaultDir, err = os.Getwd() - h.AssertNil(t, err) - h.SkipIf(t, runtime.GOOS != "windows", "skip cmd tests on unix") - tmpDir, err = os.MkdirTemp("", "shell-test") - h.AssertNil(t, err) - shell = &launch.CmdShell{Exec: hl.SyscallExecWithStdout(t, tmpDir)} - }) - - it.After(func() { - h.AssertNil(t, os.RemoveAll(tmpDir)) - }) - - when("#Launch", func() { - var process launch.ShellProcess - - when("is not script", func() { - when("there are profiles", func() { - it.Before(func() { - h.AssertNil(t, err) - process = launch.ShellProcess{ - Script: false, - Command: "echo", - Args: []string{"profile env: '!PROFILE_VAR!'"}, - Env: []string{ - "SOME_VAR=some-val", - }, - WorkingDirectory: defaultDir, - } - process.Profiles = []string{ - filepath.Join("testdata", "profiles", "print_argv0.bat"), - filepath.Join("testdata", "profiles", "print_env.bat"), - filepath.Join("testdata", "profiles", "set_env.bat"), - } - }) - - it("runs the profiles from the default directory", func() { - process.Profiles = []string{ - filepath.Join("testdata", "profiles", "pwd.bat"), - } - err = shell.Launch(process) - h.AssertNil(t, err) - stdout := rdfile(t, filepath.Join(tmpDir, "stdout")) - h.AssertStringContains(t, stdout, fmt.Sprintf("profile directory: %s\r\n", defaultDir)) - }) - - it("runs the command from the working directory", func() { - process.WorkingDirectory = tmpDir - process.Command = "echo" - process.Args = []string{ - "process", - "working", - "directory:", - "&&", - "cd", - } - err = shell.Launch(process) - h.AssertNil(t, err) - stdout := rdfile(t, filepath.Join(tmpDir, "stdout")) - h.AssertStringContains(t, stdout, fmt.Sprintf("process working directory: \r\n%s\r\n", tmpDir)) - }) - - it("sets argv0 for profile scripts to profile script path", func() { - err := shell.Launch(process) - h.AssertNil(t, err) - stdout := rdfile(t, filepath.Join(tmpDir, "stdout")) - if len(stdout) == 0 { - stderr := rdfile(t, filepath.Join(tmpDir, "stderr")) - t.Fatalf("stdout was empty: stderr: %s\n", stderr) - } - h.AssertStringContains(t, stdout, fmt.Sprintf("profile argv0: '%s'", filepath.Join("testdata", "profiles", "print_argv0.bat"))) - }) - - it("sets env for profile scripts", func() { - err := shell.Launch(process) - h.AssertNil(t, err) - stdout := rdfile(t, filepath.Join(tmpDir, "stdout")) - if len(stdout) == 0 { - stderr := rdfile(t, filepath.Join(tmpDir, "stderr")) - t.Fatalf("stdout was empty: stderr: %s\n", stderr) - } - h.AssertStringContains(t, stdout, "SOME_VAR: 'some-val'") - }) - - it("env vars set in profile scripts are available to the command", func() { - err := shell.Launch(process) - h.AssertNil(t, err) - stdout := rdfile(t, filepath.Join(tmpDir, "stdout")) - if len(stdout) == 0 { - stderr := rdfile(t, filepath.Join(tmpDir, "stderr")) - t.Fatalf("stdout was empty: stderr: %s\n", stderr) - } - h.AssertStringContains(t, stdout, "profile env: 'some-profile-var'") - }) - }) - - it("sets env", func() { - process = launch.ShellProcess{ - Script: false, - Command: `echo`, - Args: []string{"SOME_VAR: '%SOME_VAR%'"}, - Env: []string{ - "SOME_VAR=some-val", - }, - WorkingDirectory: defaultDir, - } - err := shell.Launch(process) - h.AssertNil(t, err) - stdout := rdfile(t, filepath.Join(tmpDir, "stdout")) - if len(stdout) == 0 { - stderr := rdfile(t, filepath.Join(tmpDir, "stderr")) - t.Fatalf("stdout was empty: stderr: %s\n", stderr) - } - h.AssertStringContains(t, stdout, "SOME_VAR: 'some-val'") - }) - }) - }) -} diff --git a/launch/exec_d_test.go b/launch/exec_d_test.go index 910de4f59..5118e5b4e 100644 --- a/launch/exec_d_test.go +++ b/launch/exec_d_test.go @@ -5,7 +5,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "testing" "github.com/golang/mock/gomock" @@ -42,11 +41,7 @@ func testExecD(t *testing.T, when spec.G, it spec.S) { wd, err := os.Getwd() h.AssertNil(t, err) - exe := "" - if runtime.GOOS == "windows" { - exe = ".exe" - } - path = filepath.Join(tmpDir, "execd"+exe) + path = filepath.Join(tmpDir, "execd") //#nosec G204 cmd := exec.Command("go", "build", diff --git a/launch/exec_d_windows.go b/launch/exec_d_windows.go deleted file mode 100644 index 3de54d385..000000000 --- a/launch/exec_d_windows.go +++ /dev/null @@ -1,25 +0,0 @@ -package launch - -import ( - "fmt" - "os" - "os/exec" - "syscall" - - "golang.org/x/sys/windows" -) - -const EnvExecDHandle = "CNB_EXEC_D_HANDLE" - -func setHandle(cmd *exec.Cmd, f *os.File) error { - handle := f.Fd() - if err := windows.SetHandleInformation(windows.Handle(handle), windows.HANDLE_FLAG_INHERIT, windows.HANDLE_FLAG_INHERIT); err != nil { - return err - } - cmd.SysProcAttr = &syscall.SysProcAttr{ - AdditionalInheritedHandles: []syscall.Handle{syscall.Handle(handle)}, - } - - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%#x", EnvExecDHandle, handle)) - return nil -} diff --git a/launch/launcher_test.go b/launch/launcher_test.go index 802ddd415..229c81cea 100644 --- a/launch/launcher_test.go +++ b/launch/launcher_test.go @@ -3,8 +3,6 @@ package launch_test import ( "os" "path/filepath" - "runtime" - "strings" "testing" "github.com/golang/mock/gomock" @@ -124,11 +122,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { process.Direct = true // set command to something on the real path so exec.LookPath succeeds - if runtime.GOOS == "windows" { - process.Command = launch.NewRawCommand([]string{"notepad"}) - } else { - process.Command = launch.NewRawCommand([]string{"sh"}) - } + process.Command = launch.NewRawCommand([]string{"sh"}) mockEnv.EXPECT().Get("PATH").Return("some-path").AnyTimes() launcher.Setenv = func(k string, v string) error { @@ -154,11 +148,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { if len(syscallExecArgsColl) != 1 { t.Fatalf("expected syscall.Exec to be called once: actual %v\n", syscallExecArgsColl) } - if runtime.GOOS == "windows" { - h.AssertEq(t, strings.ToLower(syscallExecArgsColl[0].argv0), `c:\windows\system32\notepad.exe`) - } else { - h.AssertMatch(t, syscallExecArgsColl[0].argv0, ".*/bin/sh$") - } + h.AssertMatch(t, syscallExecArgsColl[0].argv0, ".*/bin/sh$") }) it("should set argv to command+args", func() { @@ -166,11 +156,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { if len(syscallExecArgsColl) != 1 { t.Fatalf("expected syscall.Exec to be called once: actual %v\n", syscallExecArgsColl) } - if runtime.GOOS == "windows" { - h.AssertEq(t, syscallExecArgsColl[0].argv, []string{"notepad", "arg1", "arg2"}) - } else { - h.AssertEq(t, syscallExecArgsColl[0].argv, []string{"sh", "arg1", "arg2"}) - } + h.AssertEq(t, syscallExecArgsColl[0].argv, []string{"sh", "arg1", "arg2"}) }) it("should set envv", func() { @@ -439,17 +425,10 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type"), ) - if runtime.GOOS == "windows" { - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1.bat")) - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "some-process-type", "prof1.bat")) - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2.bat")) - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type", "prof2.bat")) - } else { - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1")) - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "some-process-type", "prof1")) - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2")) - mkfile(t, "", filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type", "prof2")) - } + mkfile(t, "", filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1")) + mkfile(t, "", filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "some-process-type", "prof1")) + mkfile(t, "", filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2")) + mkfile(t, "", filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type", "prof2")) mockEnv.EXPECT().AddRootDir(gomock.Any()).AnyTimes() mockEnv.EXPECT().AddEnvDir(gomock.Any(), gomock.Any()).AnyTimes() @@ -458,17 +437,10 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { it("sets the profiles", func() { h.AssertNil(t, launcher.LaunchProcess("/path/to/launcher", process)) h.AssertEq(t, shell.nCalls, 1) - if runtime.GOOS == "windows" { - h.AssertEq(t, shell.process.Profiles, []string{ - filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1.bat"), - filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2.bat"), - }) - } else { - h.AssertEq(t, shell.process.Profiles, []string{ - filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1"), - filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2"), - }) - } + h.AssertEq(t, shell.process.Profiles, []string{ + filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1"), + filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2"), + }) }) when("process has a type", func() { @@ -479,21 +451,12 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { it("includes type-specifc profiles", func() { h.AssertNil(t, launcher.LaunchProcess("/path/to/launcher", process)) h.AssertEq(t, shell.nCalls, 1) - if runtime.GOOS == "windows" { - h.AssertEq(t, shell.process.Profiles, []string{ - filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1.bat"), - filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "some-process-type", "prof1.bat"), - filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2.bat"), - filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type", "prof2.bat"), - }) - } else { - h.AssertEq(t, shell.process.Profiles, []string{ - filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1"), - filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "some-process-type", "prof1"), - filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2"), - filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type", "prof2"), - }) - } + h.AssertEq(t, shell.process.Profiles, []string{ + filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "prof1"), + filepath.Join(tmpDir, "launch", "0.7_buildpack", "layer", "profile.d", "some-process-type", "prof1"), + filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "prof2"), + filepath.Join(tmpDir, "launch", "0.8_buildpack", "layer", "profile.d", "some-process-type", "prof2"), + }) }) }) }) @@ -591,10 +554,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { }) when("linux", func() { - it.Before(func() { - h.SkipIf(t, runtime.GOOS == "windows", "linux test") - }) - it("is script", func() { h.AssertNil(t, launcher.LaunchProcess("/path/to/launcher", process)) h.AssertEq(t, shell.nCalls, 1) @@ -604,21 +563,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { } }) }) - - when("windows", func() { - it.Before(func() { - h.SkipIf(t, runtime.GOOS != "windows", "windows test") - }) - - it("is not script", func() { - h.AssertNil(t, launcher.LaunchProcess("/path/to/launcher", process)) - h.AssertEq(t, shell.nCalls, 1) - - if shell.process.Script { - t.Fatalf("did not expect script process") - } - }) - }) }) }) @@ -640,10 +584,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { }) when("linux", func() { - it.Before(func() { - h.SkipIf(t, runtime.GOOS == "windows", "linux test") - }) - it("is script", func() { h.AssertNil(t, launcher.LaunchProcess("/path/to/launcher", process)) h.AssertEq(t, shell.nCalls, 1) @@ -653,21 +593,6 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) { } }) }) - - when("windows", func() { - it.Before(func() { - h.SkipIf(t, runtime.GOOS != "windows", "windows test") - }) - - it("is not script", func() { - h.AssertNil(t, launcher.LaunchProcess("/path/to/launcher", process)) - h.AssertEq(t, shell.nCalls, 1) - - if shell.process.Script { - t.Fatalf("did not expect script process") - } - }) - }) }) }) }) diff --git a/launch/shell.go b/launch/shell.go index aa414d452..74eee5ca1 100644 --- a/launch/shell.go +++ b/launch/shell.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "strings" "github.com/pkg/errors" @@ -90,10 +89,6 @@ func (l *Launcher) populateLayerProfiles(procType string, profiles *[]string) di } func (l *Launcher) isScript(proc Process) (bool, error) { - if runtime.GOOS == "windows" { - // Windows does not support script commands - return false, nil - } if len(proc.Args) == 0 { return true, nil } diff --git a/launch/testhelpers/syscall_windows.go b/launch/testhelpers/syscall_windows.go deleted file mode 100644 index 01ad0e372..000000000 --- a/launch/testhelpers/syscall_windows.go +++ /dev/null @@ -1,43 +0,0 @@ -//go:build windows - -package testhelpers - -import ( - "os" - "os/exec" - "path/filepath" - "testing" - - "github.com/buildpacks/lifecycle/launch" -) - -func SyscallExecWithStdout(t *testing.T, tmpDir string) launch.ExecFunc { - t.Helper() - fstdin, err := os.Create(filepath.Join(tmpDir, "stdin")) - if err != nil { - t.Fatal(err) - } - fstdout, err := os.Create(filepath.Join(tmpDir, "stdout")) - if err != nil { - _ = fstdin.Close() - t.Fatal(err) - } - fstderr, err := os.Create(filepath.Join(tmpDir, "stderr")) - if err != nil { - _ = fstdin.Close() - _ = fstdout.Close() - t.Fatal(err) - } - - return func(argv0 string, argv []string, envv []string) error { - defer fstdin.Close() - defer fstdout.Close() - defer fstderr.Close() - c := exec.Command(argv[0], argv[1:]...) // #nosec G204 - c.Env = envv - c.Stdin = fstdin - c.Stdout = fstdout - c.Stderr = fstderr - return c.Run() - } -} diff --git a/layers/extract.go b/layers/extract.go index 7d0e9f4b8..619070641 100644 --- a/layers/extract.go +++ b/layers/extract.go @@ -3,14 +3,13 @@ package layers import ( "archive/tar" "io" - "runtime" "github.com/buildpacks/lifecycle/archive" ) // Extract extracts entries from r to the dest directory // Contents of r should be an OCI layer. -// If dest is an empty string files with be extracted to `/` or `c:\` on unix and windows filesystems respectively. +// If dest is an empty string files with be extracted to `/` on unix filesystems. func Extract(r io.Reader, dest string) error { tr := tarReader(r, dest) return archive.Extract(tr) @@ -18,13 +17,6 @@ func Extract(r io.Reader, dest string) error { func tarReader(r io.Reader, dest string) archive.TarReader { tr := archive.NewNormalizingTarReader(tar.NewReader(r)) - if runtime.GOOS == "windows" { - tr.ExcludePaths([]string{"Hives"}) - tr.Strip(`Files/`) - if dest == "" { - dest = `c:\` - } - } if dest == "" { dest = `/` } diff --git a/layers/launcher.go b/layers/launcher.go index 0ccc27246..f65725da7 100644 --- a/layers/launcher.go +++ b/layers/launcher.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "os" - "runtime" "strings" "github.com/pkg/errors" @@ -31,11 +30,7 @@ func (f *Factory) LauncherLayer(path string) (layer Layer, err error) { hdr.Name = launch.LauncherPath hdr.Uid = 0 hdr.Gid = 0 - if runtime.GOOS == "windows" { - hdr.Mode = 0777 - } else { - hdr.Mode = 0755 - } + hdr.Mode = 0755 return f.writeLayer("buildpacksio/lifecycle:launcher", LauncherLayerName, func(tw *archive.NormalizingTarWriter) error { for _, dir := range parents { @@ -97,11 +92,7 @@ func validateProcessType(pType string) error { func rootOwnedDir(path string) *tar.Header { var modePerm int64 - if runtime.GOOS == "windows" { - modePerm = 0777 - } else { - modePerm = 0755 - } + modePerm = 0755 return &tar.Header{ Typeflag: tar.TypeDir, Name: path, @@ -111,11 +102,7 @@ func rootOwnedDir(path string) *tar.Header { func typeSymlink(path string) *tar.Header { var modePerm int64 - if runtime.GOOS == "windows" { - modePerm = 0777 - } else { - modePerm = 0755 - } + modePerm = 0755 return &tar.Header{ Typeflag: tar.TypeSymlink, Name: path, diff --git a/layers/launcher_test.go b/layers/launcher_test.go index 766eb82a2..1f0f28a9a 100644 --- a/layers/launcher_test.go +++ b/layers/launcher_test.go @@ -5,7 +5,6 @@ import ( "io" "os" "path/filepath" - "runtime" "testing" "github.com/apex/log" @@ -54,9 +53,6 @@ func testLauncherLayers(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, err) h.AssertEq(t, configLayer.ID, "buildpacksio/lifecycle:process-types") var mode int64 = 0755 - if runtime.GOOS == "windows" { - mode = 0777 - } assertTarEntries(t, configLayer.TarPath, []*tar.Header{ { Name: tarPath("/cnb"), @@ -118,9 +114,6 @@ func testLauncherLayers(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, err) h.AssertEq(t, launcherLayer.ID, "buildpacksio/lifecycle:launcher") var mode int64 = 0755 - if runtime.GOOS == "windows" { - mode = 0777 - } assertTarEntries(t, launcherLayer.TarPath, []*tar.Header{ { Name: tarPath("/cnb"), diff --git a/layers/layers_windows_test.go b/layers/layers_windows_test.go index 6846e28d5..c0ccc1c97 100644 --- a/layers/layers_windows_test.go +++ b/layers/layers_windows_test.go @@ -2,7 +2,6 @@ package layers_test import ( "archive/tar" - "io" "os" "path" "path/filepath" @@ -31,16 +30,3 @@ func assertOSSpecificFields(t *testing.T, expected *tar.Header, hdr *tar.Header) t.Helper() h.AssertEq(t, hdr.Format, tar.FormatPAX) } - -func assertOSSpecificEntries(t *testing.T, tr *tar.Reader) { - for _, windowsEntry := range []string{"Files", "Hives"} { - header, err := tr.Next() - if err == io.EOF { - t.Fatalf("missing expected archive entry '%s'", windowsEntry) - } - h.AssertEq(t, header.Name, windowsEntry) - if header.Typeflag != tar.TypeDir { - t.Fatalf("expected entry '%s' to have type %q, got %q", windowsEntry, header.Typeflag, tar.TypeDir) - } - } -} diff --git a/layers/slices_test.go b/layers/slices_test.go index b768cbe5c..43e9a7528 100644 --- a/layers/slices_test.go +++ b/layers/slices_test.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "testing" "github.com/sclevine/spec" @@ -191,21 +190,12 @@ func testSlices(t *testing.T, when spec.G, it spec.S) { it.Before(func() { var err error - if runtime.GOOS == "windows" { - sliceLayers, err = factory.SliceLayers(dirToSlice, []layers.Slice{ - {Paths: []string{"*.txt", "**\\*.txt"}}, - {Paths: []string{"other-dir"}}, - {Paths: []string{"dir-link\\*"}}, - {Paths: []string{"..\\**\\dir-to-exclude"}}, - }) - } else { - sliceLayers, err = factory.SliceLayers(dirToSlice, []layers.Slice{ - {Paths: []string{"*.txt", "**/*.txt"}}, - {Paths: []string{"other-dir"}}, - {Paths: []string{"dir-link/*"}}, - {Paths: []string{"../**/dir-to-exclude"}}, - }) - } + sliceLayers, err = factory.SliceLayers(dirToSlice, []layers.Slice{ + {Paths: []string{"*.txt", "**/*.txt"}}, + {Paths: []string{"other-dir"}}, + {Paths: []string{"dir-link/*"}}, + {Paths: []string{"../**/dir-to-exclude"}}, + }) h.AssertNil(t, err) }) diff --git a/layers/tar_test.go b/layers/tar_test.go index 301fdb904..e434ca9ff 100644 --- a/layers/tar_test.go +++ b/layers/tar_test.go @@ -1,13 +1,9 @@ package layers_test import ( - "archive/tar" - "io" "os" "path/filepath" - "runtime" "testing" - "time" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/sclevine/spec" @@ -45,12 +41,6 @@ func testTarLayer(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, layer.ID, "some-extension-id:some-layer-name") h.AssertEq(t, layer.TarPath, filepath.Join(factory.ArtifactsDir, "some-extension-id:some-layer-name.tar")) h.AssertEq(t, layer.History, v1.History{CreatedBy: "some-created-by"}) - if runtime.GOOS != "windows" { - // windows reports zeroed timestamps as `1970-01-01 00:00:00 +0000 UTC` - assertTimestamps(t, layer.TarPath, time.Date(1980, time.January, 1, 0, 0, 1, 0, time.UTC)) - // normalizing tar writer mutates the filepath separator - h.AssertEq(t, layer.Digest, "sha256:fb54d2566824d6630d94db0b008d9a544a94d3547a424f52e2fd282b648c0601") // from fixture - } }) }) @@ -64,34 +54,7 @@ func testTarLayer(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, layer.ID, "some-extension-id:some-layer-name") h.AssertEq(t, layer.TarPath, filepath.Join(factory.ArtifactsDir, "some-extension-id:some-layer-name.tar")) h.AssertEq(t, layer.History, v1.History{CreatedBy: "some-created-by"}) - if runtime.GOOS != "windows" { - // windows reports zeroed timestamps as `1970-01-01 00:00:00 +0000 UTC` - assertTimestamps(t, layer.TarPath, time.Date(1980, time.January, 1, 0, 0, 1, 0, time.UTC)) - // normalizing tar writer mutates the filepath separator - h.AssertEq(t, layer.Digest, "sha256:fb54d2566824d6630d94db0b008d9a544a94d3547a424f52e2fd282b648c0601") // from fixture - } }) }) }) } - -func assertTimestamps(t *testing.T, tarPath string, expected time.Time) { - t.Helper() - - f, err := os.Open(tarPath) // #nosec G304 - h.AssertNil(t, err) - defer f.Close() // nolint - - tr := tar.NewReader(f) - var found int - for { - header, err := tr.Next() - if err == io.EOF { - break - } - h.AssertNil(t, err) - found++ - h.AssertEq(t, header.ModTime, expected) - } - h.AssertEq(t, found > 0, true) -} diff --git a/layers/writer.go b/layers/writer.go index cc6df8dab..40e1d1b4f 100644 --- a/layers/writer.go +++ b/layers/writer.go @@ -6,9 +6,6 @@ import ( "fmt" "io" "os" - "runtime" - - "github.com/buildpacks/imgutil/layer" "github.com/buildpacks/lifecycle/archive" ) @@ -35,12 +32,7 @@ func (lw *layerWriter) Digest() string { } func tarWriter(lw *layerWriter) *archive.NormalizingTarWriter { - var tw *archive.NormalizingTarWriter - if runtime.GOOS == "windows" { - tw = archive.NewNormalizingTarWriter(layer.NewWindowsWriter(lw)) - } else { - tw = archive.NewNormalizingTarWriter(tar.NewWriter(lw)) - } + tw := archive.NewNormalizingTarWriter(tar.NewWriter(lw)) tw.WithModTime(archive.NormalizedModTime) return tw } diff --git a/phase/analyzer_test.go b/phase/analyzer_test.go index b9224bce0..03173b395 100644 --- a/phase/analyzer_test.go +++ b/phase/analyzer_test.go @@ -486,7 +486,7 @@ func testAnalyzer(platformAPI string) func(t *testing.T, when spec.G, it spec.S) it("populates target metadata from the run image", func() { h.AssertNil(t, previousImage.SetLabel("io.buildpacks.base.id", "id software")) - h.AssertNil(t, previousImage.SetOS("windows")) + h.AssertNil(t, previousImage.SetOS("zindows")) h.AssertNil(t, previousImage.SetOSVersion("95")) h.AssertNil(t, previousImage.SetArchitecture("Pentium")) h.AssertNil(t, previousImage.SetVariant("MMX")) @@ -501,7 +501,7 @@ func testAnalyzer(platformAPI string) func(t *testing.T, when spec.G, it spec.S) h.AssertNotNil(t, md.RunImage.TargetMetadata) h.AssertEq(t, md.RunImage.TargetMetadata.Arch, "Pentium") h.AssertEq(t, md.RunImage.TargetMetadata.ArchVariant, "MMX") - h.AssertEq(t, md.RunImage.TargetMetadata.OS, "windows") + h.AssertEq(t, md.RunImage.TargetMetadata.OS, "zindows") h.AssertEq(t, md.RunImage.TargetMetadata.ID, "id software") h.AssertNotNil(t, md.RunImage.TargetMetadata.Distro) h.AssertEq(t, md.RunImage.TargetMetadata.Distro.Name, "moobuntu") diff --git a/phase/detector_test.go b/phase/detector_test.go index ff429cd5e..cb76599f0 100644 --- a/phase/detector_test.go +++ b/phase/detector_test.go @@ -744,7 +744,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) { Targets: []buildpack.TargetMetadata{ {Arch: "P6", ArchVariant: "Pentium Pro", OS: "Win95", Distros: []buildpack.OSDistro{ - {Name: "Windows 95", Version: "OSR1"}, {Name: "Windows 95", Version: "OSR2.5"}}}, + {Name: "Sceens 95", Version: "OSR1"}, {Name: "Sceens 95", Version: "OSR2.5"}}}, {Arch: "ARM64", OS: "MacOS", Distros: []buildpack.OSDistro{{Name: "MacOS", Version: "snow cheetah"}}}}, } dirStore.EXPECT().LookupBp("A", "v1").Return(bpA1, nil).AnyTimes() @@ -821,7 +821,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) { Targets: []buildpack.TargetMetadata{ {Arch: "P6", ArchVariant: "Pentium Pro", OS: "Win95", Distros: []buildpack.OSDistro{ - {Name: "Windows 95", Version: "OSR1"}, {Name: "Windows 95", Version: "OSR2.5"}}}, + {Name: "Sceens 95", Version: "OSR1"}, {Name: "Sceens 95", Version: "OSR2.5"}}}, {Arch: "ARM64", OS: "MacOS", Distros: []buildpack.OSDistro{{Name: "MacOS", Version: "snow cheetah"}}}}, } dirStore.EXPECT().LookupBp("A", "v1").Return(bpA1, nil).AnyTimes() @@ -860,9 +860,9 @@ func testDetector(t *testing.T, when spec.G, it spec.S) { Targets: []buildpack.TargetMetadata{ {Arch: "P6", ArchVariant: "Pentium Pro", OS: "Win95", Distros: []buildpack.OSDistro{ - {Name: "Windows 95", Version: "OSR1"}, {Name: "Windows 95", Version: "OSR2.5"}}}, + {Name: "Sceens 95", Version: "OSR1"}, {Name: "Sceens 95", Version: "OSR2.5"}}}, {Arch: "Pentium M", OS: "Win98", - Distros: []buildpack.OSDistro{{Name: "Windows 2000", Version: "Server"}}}, + Distros: []buildpack.OSDistro{{Name: "Screens 2000", Version: "Server"}}}, }, } dirStore.EXPECT().LookupBp("A", "v1").Return(bpA1, nil).AnyTimes() @@ -874,7 +874,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, ok, true) outs := val.(buildpack.DetectOutputs) h.AssertEq(t, outs.Code, -1) - h.AssertStringContains(t, outs.Err.Error(), `unable to satisfy target os/arch constraints; run image: {"os":"MacOS","arch":"ARM64","distro":{"name":"MacOS","version":"some kind of big cat"}}, buildpack: [{"os":"Win95","arch":"P6","arch-variant":"Pentium Pro","distros":[{"name":"Windows 95","version":"OSR1"},{"name":"Windows 95","version":"OSR2.5"}]},{"os":"Win98","arch":"Pentium M","distros":[{"name":"Windows 2000","version":"Server"}]}]`) + h.AssertStringContains(t, outs.Err.Error(), `unable to satisfy target os/arch constraints; run image: {"os":"MacOS","arch":"ARM64","distro":{"name":"MacOS","version":"some kind of big cat"}}, buildpack: [{"os":"Win95","arch":"P6","arch-variant":"Pentium Pro","distros":[{"name":"Sceens 95","version":"OSR1"},{"name":"Sceens 95","version":"OSR2.5"}]},{"os":"Win98","arch":"Pentium M","distros":[{"name":"Screens 2000","version":"Server"}]}]`) return []buildpack.GroupElement{}, []files.BuildPlanEntry{}, nil }) diff --git a/phase/exporter_test.go b/phase/exporter_test.go index 63267503e..2e2b73f9e 100644 --- a/phase/exporter_test.go +++ b/phase/exporter_test.go @@ -6,7 +6,6 @@ import ( "io" "os" "path/filepath" - "runtime" "strings" "testing" @@ -708,11 +707,7 @@ version = "4.5.6" val, err := opts.WorkingImage.Env("PATH") h.AssertNil(t, err) - if runtime.GOOS == "windows" { - h.AssertEq(t, val, `c:\cnb\process;c:\cnb\lifecycle;some-path`) - } else { - h.AssertEq(t, val, `/cnb/process:/cnb/lifecycle:some-path`) - } + h.AssertEq(t, val, `/cnb/process:/cnb/lifecycle:some-path`) }) }) diff --git a/phase/extender_test.go b/phase/extender_test.go index 186e04eea..7d85d2f1e 100644 --- a/phase/extender_test.go +++ b/phase/extender_test.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "testing" "time" @@ -31,10 +30,8 @@ import ( ) func TestExtender(t *testing.T) { - if runtime.GOOS != "windows" { - spec.Run(t, "unit-new-extender", testExtenderFactory, spec.Report(report.Terminal{})) - spec.Run(t, "unit-extender", testExtender, spec.Sequential(), spec.Report(report.Terminal{})) - } + spec.Run(t, "unit-new-extender", testExtenderFactory, spec.Report(report.Terminal{})) + spec.Run(t, "unit-extender", testExtender, spec.Sequential(), spec.Report(report.Terminal{})) } func testExtenderFactory(t *testing.T, when spec.G, it spec.S) { diff --git a/phase/generator.go b/phase/generator.go index 6fb06dd76..4a421fb05 100644 --- a/phase/generator.go +++ b/phase/generator.go @@ -163,7 +163,7 @@ func (g *Generator) copyDockerfiles(dockerfiles []buildpack.DockerfileInfo) erro if g.PlatformAPI.AtLeast("0.13") { if ignoreDockerfile { - if err := fsutil.RenameWithWindowsFallback(dockerfile.Path, dockerfile.Path+".ignore"); err != nil { + if err := os.Rename(dockerfile.Path, dockerfile.Path+".ignore"); err != nil { return fmt.Errorf("failed to rename Dockerfile at %s: %w", dockerfile.Path, err) } } diff --git a/phase/generator_test.go b/phase/generator_test.go index e01bb24bb..36cc9f286 100644 --- a/phase/generator_test.go +++ b/phase/generator_test.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "strings" "testing" @@ -28,10 +27,8 @@ import ( ) func TestGenerator(t *testing.T) { - if runtime.GOOS != "windows" { - spec.Run(t, "unit-new-generator", testGeneratorFactory, spec.Report(report.Terminal{})) - spec.Run(t, "unit-generator", testGenerator, spec.Report(report.Terminal{})) - } + spec.Run(t, "unit-new-generator", testGeneratorFactory, spec.Report(report.Terminal{})) + spec.Run(t, "unit-generator", testGenerator, spec.Report(report.Terminal{})) } func testGeneratorFactory(t *testing.T, when spec.G, it spec.S) { diff --git a/priv/sock_windows.go b/priv/sock_windows.go deleted file mode 100644 index cdebdd182..000000000 --- a/priv/sock_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -package priv - -import "net/url" - -// shouldConnectSock is always false on windows -func shouldConnectSock(host *url.URL) bool { - return false -} diff --git a/testhelpers/docker.go b/testhelpers/docker.go index 0daed3495..252122df1 100644 --- a/testhelpers/docker.go +++ b/testhelpers/docker.go @@ -123,7 +123,7 @@ func PushImage(dockerCli dockercli.CommonAPIClient, ref string, auth string) err return nil } -// SeedDockerVolume only works with Linux daemons as Windows only mounts volumes for started containers +// SeedDockerVolume only works with Linux daemons func SeedDockerVolume(t *testing.T, srcPath string) string { volumeName := "test-volume-" + RandString(10) containerName := "test-volume-helper-" + RandString(10) diff --git a/testhelpers/vars_windows.go b/testhelpers/vars_windows.go deleted file mode 100644 index eb80bd5aa..000000000 --- a/testhelpers/vars_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -package testhelpers - -import "testing" - -func GetUmask(t *testing.T) int { - // Not implemented on Windows - return 0 -} diff --git a/tools/Dockerfile.windows b/tools/Dockerfile.windows deleted file mode 100644 index 3f930ebdb..000000000 --- a/tools/Dockerfile.windows +++ /dev/null @@ -1,44 +0,0 @@ -ARG image_tag -FROM ${image_tag} as builder - -SHELL ["cmd.exe", "/c"] - -RUN mkdir c:\tools\bin && \ - \ - git clone --branch=v20.10.5 --depth=1 https://github.com/docker/cli c:\gopath\src\github.com\docker\cli && \ - go get github.com/docker/cli/cmd/docker && \ - go build -o c:\tools\bin\docker.exe github.com/docker/cli/cmd/docker && \ - \ - git clone --branch=v0.3.6 --depth=1 https://github.com/kyoh86/richgo c:\gopath\src\github.com\kyoh86\richgo && \ - go get github.com/kyoh86/richgo && \ - go build -o c:\tools\bin\richgo.exe github.com/kyoh86/richgo && \ - \ - curl.exe -o make-installer.exe -L "https://sourceforge.net/projects/gnuwin32/files/make/3.81/make-3.81.exe" && \ - make-installer.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /DIR=C:\tools && \ - del make-installer.exe && \ - \ - curl.exe -o c:\tools\bin\jq.exe -L "https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win64.exe" && \ - \ - setx /M PATH "%PATH%;c:\tools\bin" && \ - \ - mklink C:\git\usr\bin\bash.exe sh.exe && \ - \ - git config --global core.autocrlf false && \ - git config --global core.eol lf && \ - git config --global core.symlinks true && \ - \ - rmdir /q /s c:\gopath\src - - -# For reusing dependencies `-v gopathcache:c:/gopath` -ENV GOCMD=richgo -ENV GOPATH=c:\\gopath -ENV GOBIN=c:\\gopath\\bin -VOLUME ["c:/gopath"] - -WORKDIR /lifecycle - -# Copy git directory for consistent filesystem duplication of source (docker build, cp, volumes are inconsistent with symlinks/hardlinks on Windows) -COPY . /lifecycle/.git - -RUN git reset --hard HEAD diff --git a/tools/image/main.go b/tools/image/main.go index f80c1d4b2..d4083b564 100644 --- a/tools/image/main.go +++ b/tools/image/main.go @@ -18,7 +18,6 @@ import ( "github.com/BurntSushi/toml" "github.com/buildpacks/imgutil" - "github.com/buildpacks/imgutil/layer" "github.com/buildpacks/imgutil/local" "github.com/buildpacks/imgutil/remote" dockercli "github.com/docker/docker/client" @@ -28,8 +27,7 @@ import ( ) const ( - linuxBaseImage = "gcr.io/distroless/static" - windowsBaseImage = "mcr.microsoft.com/windows/nanoserver:1809-amd64" + linuxBaseImage = "gcr.io/distroless/static" ) // commandline flags @@ -66,9 +64,6 @@ func main() { } baseImage := linuxBaseImage - if targetOS == "windows" { - baseImage = windowsBaseImage - } var img imgutil.Image if useDaemon { @@ -140,9 +135,6 @@ func main() { return } workDir := "/layers" - if targetOS == "windows" { - workDir = `c:\layers` - } if err := img.SetWorkingDir(workDir); err != nil { log.Print("Failed to set working directory:", err) return @@ -277,22 +269,12 @@ func lifecycleLayer() (string, error) { var ntw *archive.NormalizingTarWriter var mode int64 - if targetOS == "windows" { - ntw = archive.NewNormalizingTarWriter(layer.NewWindowsWriter(lf)) - mode = 0777 - } else { - ntw = archive.NewNormalizingTarWriter(tar.NewWriter(lf)) - mode = 0755 - } + ntw = archive.NewNormalizingTarWriter(tar.NewWriter(lf)) + mode = 0755 ntw.WithModTime(archive.NormalizedModTime) - if targetOS == "windows" { - ntw.WithUID(1) // gets translated to user permissions in windows writer - ntw.WithGID(1) // gets translated to user permissions in windows writer - } else { - ntw.WithUID(0) - ntw.WithGID(0) - } + ntw.WithUID(0) + ntw.WithGID(0) if err := ntw.WriteHeader(&tar.Header{ Typeflag: tar.TypeDir, Name: "/cnb",