From b63a9c980383825d9dbe2e4e8184bd142f483fa7 Mon Sep 17 00:00:00 2001 From: Michele Degges Date: Fri, 25 Feb 2022 15:56:20 -0800 Subject: [PATCH] Onboard to CRT (#11564) Onboard Packer to CRT Co-authored-by: Wilken Rivera Co-authored-by: Claire Labry --- .circleci/config.yml | 236 ---------------- .github/workflows/acceptance-test.yml | 93 ++++++ .github/workflows/algolia-index.yml | 27 ++ .github/workflows/build.yml | 264 ++++++++++++++++++ .github/workflows/go-test.yml | 38 +++ .github/workflows/go-validate.yml | 50 ++++ .github/workflows/nightly-release-readme.md | 5 + .github/workflows/nightly-release.yml | 100 +++++++ .github/workflows/website-docker-publish.yml | 70 +++++ .go-version | 1 + .release/ci.hcl | 240 ++++++++++++++++ .release/docker/README.md | 99 +++++++ .../linux/package/etc/packer.d/packer.env | 0 .../usr/lib/systemd/system/packer.service | 23 ++ .release/linux/postrm | 8 + .release/linux/preinst | 13 + .release/security-scan.hcl | 13 + CODEOWNERS | 5 +- Dockerfile | 122 ++++++-- Makefile | 45 ++- README.md | 5 +- acctest/plugin/plugin_acc_test.go | 10 +- go.mod | 2 +- go.sum | 2 +- scripts/version.sh | 12 + version/version.go | 22 +- 26 files changed, 1225 insertions(+), 280 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/acceptance-test.yml create mode 100644 .github/workflows/algolia-index.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/go-test.yml create mode 100644 .github/workflows/go-validate.yml create mode 100644 .github/workflows/nightly-release-readme.md create mode 100644 .github/workflows/nightly-release.yml create mode 100644 .github/workflows/website-docker-publish.yml create mode 100644 .go-version create mode 100644 .release/ci.hcl create mode 100644 .release/docker/README.md create mode 100644 .release/linux/package/etc/packer.d/packer.env create mode 100644 .release/linux/package/usr/lib/systemd/system/packer.service create mode 100644 .release/linux/postrm create mode 100644 .release/linux/preinst create mode 100644 .release/security-scan.hcl create mode 100755 scripts/version.sh diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 4dbe181b0..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,236 +0,0 @@ -orbs: - win: circleci/windows@1.0.0 - -version: 2.1 - -executors: - golang: - docker: - - image: docker.mirror.hashicorp.services/circleci/golang:1.17 - resource_class: medium+ - darwin: - macos: - xcode: "12.0.0" - -commands: - install-go-run-tests-unix: - parameters: - GOOS: - type: string - GOVERSION: - type: string - HOME: - type: string - default: "~" - steps: - - checkout - - run: curl https://dl.google.com/go/go<< parameters.GOVERSION >>.<< parameters.GOOS >>-amd64.tar.gz | tar -C << parameters.HOME >>/ -xz - - run: << parameters.HOME >>/go/bin/go test ./... -coverprofile=coverage.txt -covermode=atomic - install-go-run-tests-windows: - parameters: - GOVERSION: - type: string - steps: - - checkout - - run: curl https://dl.google.com/go/go<< parameters.GOVERSION >>.windows-amd64.zip --output ~/go<< parameters.GOVERSION >>.windows-amd64.zip - - run: unzip ~/go<< parameters.GOVERSION >>.windows-amd64.zip -d ~/ - - run: ~/go/bin/go test ./... -coverprofile=coverage.txt -covermode=atomic - build-and-persist-packer-binary: - parameters: - GOOS: - type: string - GOARCH: - default: "amd64" - type: string - steps: - - checkout - - run: GOOS=<< parameters.GOOS >> GOARCH=<> go build -ldflags="-s -w -X github.com/hashicorp/packer/version.GitCommit=${CIRCLE_SHA1}" -o ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >> . - - run: zip ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >>.zip ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >> - - run: rm ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >> - - persist_to_workspace: - root: . - paths: - - ./pkg/ - -# Golang CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-go/ for more details -jobs: - test-linux: - executor: golang - resource_class: large - working_directory: /go/src/github.com/hashicorp/packer - steps: - - checkout - - run: TESTARGS="-coverprofile=coverage.txt -covermode=atomic" make ci - test-darwin: - executor: darwin - working_directory: ~/go/github.com/hashicorp/packer - steps: - - install-go-run-tests-unix: - GOOS: darwin - GOVERSION: "1.17" - test-windows: - executor: - name: win/vs2019 - shell: bash.exe - steps: - - install-go-run-tests-windows: - GOVERSION: "1.17" - check-mod-tidy: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - checkout - - run: go mod tidy -compat=1.17 - check-lint: - executor: golang - resource_class: xlarge - steps: - - checkout - - run: git fetch --all - - run: - command: make ci-lint - no_output_timeout: 30m - check-fmt: - executor: golang - steps: - - checkout - - run: make fmt-check - check-generate: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - checkout - - run: make generate-check - build_linux: - executor: golang - steps: - - build-and-persist-packer-binary: - GOOS: linux - build_windows: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - build-and-persist-packer-binary: - GOOS: windows - build_darwin: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - build-and-persist-packer-binary: - GOOS: darwin - build_darwin_arm64: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - build-and-persist-packer-binary: - GOOS: darwin - GOARCH: arm64 - build_freebsd: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - build-and-persist-packer-binary: - GOOS: freebsd - build_solaris: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - build-and-persist-packer-binary: - GOOS: solaris - build_openbsd: - executor: golang - working_directory: /go/src/github.com/hashicorp/packer - steps: - - build-and-persist-packer-binary: - GOOS: openbsd - store_artifacts: - executor: golang - steps: - - attach_workspace: - at: . - - store_artifacts: - path: ./pkg/ - destination: / - build-website-docker-image: - docker: - - image: docker.mirror.hashicorp.services/circleci/buildpack-deps - shell: /usr/bin/env bash -euo pipefail -c - steps: - - checkout - - setup_remote_docker - - run: - name: Build Docker Image if Necessary - command: | - IMAGE_TAG=$(cat website/Dockerfile website/package-lock.json | sha256sum | awk '{print $1;}') - echo "Using $IMAGE_TAG" - if curl https://hub.docker.com/v2/repositories/hashicorp/packer-website/tags/$IMAGE_TAG -fsL > /dev/null; then - echo "Dependencies have not changed, not building a new website docker image." - else - cd website/ - docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS - docker build -t hashicorp/packer-website:$IMAGE_TAG . - docker tag hashicorp/packer-website:$IMAGE_TAG hashicorp/packer-website:latest - docker push hashicorp/packer-website - fi - algolia-index: - docker: - - image: docker.mirror.hashicorp.services/node:14 - steps: - - checkout - - run: - name: Push content to Algolia Index - command: | - if [ "$CIRCLE_REPOSITORY_URL" != "git@github.com:hashicorp/packer.git" ]; then - echo "Not Packer OSS Repo, not indexing Algolia" - exit 0 - fi - cd website/ - npm install -g npm@latest - npm install - npx ts-node --skip-ignore -P ./scripts/tsconfig.json ./scripts/index_search_content.ts - -workflows: - version: 2 - test: - jobs: - - test-linux - - test-darwin - - test-windows - check-code: - jobs: - - check-lint - - check-fmt - - check-mod-tidy - - check-generate - build_packer_binaries: - jobs: - - build_linux - - build_darwin - - build_darwin_arm64 - - build_windows - - build_freebsd - - build_openbsd - - build_solaris - - store_artifacts: - requires: - - build_linux - - build_darwin - - build_darwin_arm64 - - build_windows - - build_freebsd - - build_openbsd - - build_solaris - website: - jobs: - - build-website-docker-image: - filters: - branches: - only: - - master - - algolia-index: - filters: - branches: - only: - - stable-website diff --git a/.github/workflows/acceptance-test.yml b/.github/workflows/acceptance-test.yml new file mode 100644 index 000000000..02ac4d959 --- /dev/null +++ b/.github/workflows/acceptance-test.yml @@ -0,0 +1,93 @@ +# +# This GitHub action runs Packer's acceptance tests every night. +# Failures are reported to slack. +# + +name: "Acceptance Test" + +on: + schedule: + # Runs against the default branch every day at midnight + - cron: "0 0 * * *" + +jobs: + get-go-version: + runs-on: ubuntu-latest + outputs: + go-version: ${{ steps.get-go-version.outputs.go-version }} + steps: + - uses: actions/checkout@v2 + - name: 'Determine Go version' + id: get-go-version + # We use .go-version as our source of truth for current Go + # version, because "goenv" can react to it automatically. + run: | + echo "Building with Go $(cat .go-version)" + echo "::set-output name=go-version::$(cat .go-version)" + acceptance-test: + runs-on: ubuntu-latest + name: Acceptance Test + needs: get-go-version + env: + # AWS Creds for Assume Role + AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }} + AWS_ACCESS_KEY_ID: ${{ secrets.TESTACC_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.TESTACC_AWS_SECRET_ACCESS_KEY }} + AWS_REGION: ${{ secrets.TESTACC_AWS_REGION }} + # HCP Creds for Acceptance Tests + HCP_CLIENT_ID: ${{ secrets.HCP_CLIENT_ID }} + HCP_CLIENT_SECRET: ${{ secrets.HCP_CLIENT_SECRET }} + HCP_ORG_ID: ${{ secrets.HCP_ORG_ID }} + HCP_PROJECT_ID: ${{ secrets.HCP_PROJECT_ID }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: ${{ needs.get-go-version.outputs.go-version }} + - name: IAM Assume Role + uses: aws-actions/configure-aws-credentials@v1 + with: + role-to-assume: ${{ env.AWS_ROLE_ARN }} + aws-region: ${{ env.AWS_REGION }} + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + role-duration-seconds: 3600 + - name: Install gotestsum + run: go install gotest.tools/gotestsum@latest + - name: Run acceptance tests per module + run: | + mkdir -p /tmp/test-results + make dev + PACKER_ACC=1 gotestsum --format=short-verbose --junitfile /tmp/test-results/gotestsum-report.xml -- -timeout=120m -p 2 $(go list ./... | grep -v inspec | grep -v profitbricks | grep -v oneandone) + # Send a slack notification if either job defined above fails + slack-notify: + needs: + - get-go-version + - acceptance-test + if: always() && (needs.get-go-version.result == 'failure' || needs.acceptance-test.result == 'failure') + runs-on: ubuntu-latest + steps: + - name: Send slack notification on failure + uses: slackapi/slack-github-action@v1.18.0 + with: + payload: | + { + "text": ":alert: Packer Nightly Acceptance Tests *FAILED* :alert:", + "attachments": [ + { + "color": "#C41E3A", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Branch: `${{ github.ref_name }}`\nRef: ${{ github.event.pull_request.html_url || github.event.head_commit.url }}\nWorkflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } + } + ] + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK \ No newline at end of file diff --git a/.github/workflows/algolia-index.yml b/.github/workflows/algolia-index.yml new file mode 100644 index 000000000..dc5bddbea --- /dev/null +++ b/.github/workflows/algolia-index.yml @@ -0,0 +1,27 @@ +# +# This GitHub action pushes content to the Algolia Index. +# + +name: "Algolia index" + +on: + push: + branches: + # Runs on push events to the stable-website branch + - 'stable-website' + +jobs: + algolia-index: + runs-on: ubuntu-latest + name: Push content to Algolia Index + if: github.repository == 'hashicorp/packer' && github.ref_name == 'stable-website' + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '14' + - run: | + cd website/ + npm install -g npm@latest + npm install + npx ts-node --skip-ignore -P ./scripts/tsconfig.json ./scripts/index_search_content.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..567c86f32 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,264 @@ +# +# This GitHub action builds Packer binaries, linux packages, +# and Docker images from source, and uploads them to GitHub artifacts. +# Note that artifacts available via GitHub Artifacts are not codesigned or notarized. +# + +name: build + +on: [ workflow_dispatch, push, workflow_call ] + +env: + PKG_NAME: "packer" + GO_TAGS: "" + +jobs: + get-go-version: + runs-on: ubuntu-latest + outputs: + go-version: ${{ steps.get-go-version.outputs.go-version }} + steps: + - uses: actions/checkout@v2 + - name: 'Determine Go version' + id: get-go-version + # We use .go-version as our source of truth for current Go + # version, because "goenv" can react to it automatically. + run: | + echo "Building with Go $(cat .go-version)" + echo "::set-output name=go-version::$(cat .go-version)" + + get-product-version: + needs: get-go-version + runs-on: ubuntu-latest + outputs: + product-version: ${{ steps.get-product-version.outputs.product-version }} + steps: + - uses: actions/checkout@v2 + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: "${{ needs.get-go-version.outputs.go-version }}" + - name: get product version + id: get-product-version + run: | + make version + echo "::set-output name=product-version::$(make version)" + + generate-metadata-file: + needs: + - get-product-version + runs-on: ubuntu-latest + outputs: + filepath: ${{ steps.generate-metadata-file.outputs.filepath }} + steps: + - name: 'Checkout directory' + uses: actions/checkout@v2 + - name: Generate metadata file + id: generate-metadata-file + uses: hashicorp/actions-generate-metadata@main + with: + version: ${{ needs.get-product-version.outputs.product-version }} + product: ${{ env.PKG_NAME }} + + - uses: actions/upload-artifact@v2 + with: + name: metadata.json + path: ${{ steps.generate-metadata-file.outputs.filepath }} + + set-ld-flags: + needs: get-product-version + runs-on: ubuntu-latest + outputs: + ldflags: ${{ steps.generate-ld-flags.outputs.ldflags }} + steps: + - uses: actions/checkout@v2 + - name: 'Generate ld flags' + id: generate-ld-flags + run: | + project="$(go list -m)" + sha="$(git rev-parse HEAD)" + echo "::set-output name=ldflags::"-s -w -X \'$project/version.GitCommit=$sha\'"" + + build-other: + needs: + - get-product-version + - get-go-version + - set-ld-flags + runs-on: ubuntu-latest + strategy: + matrix: + goos: [ freebsd, windows, netbsd, openbsd, solaris ] + goarch: [ "386", "amd64", "arm" ] + go: [ "${{ needs.get-go-version.outputs.go-version }}" ] + exclude: + - goos: solaris + goarch: 386 + - goos: solaris + goarch: arm + - goos: windows + goarch: arm + fail-fast: true + + name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build + env: + GOPRIVATE: "github.com/hashicorp" + GO111MODULE: on + LD_FLAGS: ${{ needs.set-ld-flags.outputs.ldflags }} + steps: + - uses: actions/checkout@v2 + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Go Build + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 0 + run: | + mkdir -p dist out + unset GOPATH; + go build -v -tags "${{ env.GO_TAGS }}" -ldflags "${{ env.LD_FLAGS }}" -o dist/ . + zip -r -j out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + path: out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + + build-linux: + needs: + - get-product-version + - get-go-version + - set-ld-flags + runs-on: ubuntu-latest + strategy: + matrix: + goos: [ linux ] + goarch: [ "arm", "arm64", "386", "amd64" ] + go: [ "${{ needs.get-go-version.outputs.go-version }}" ] + fail-fast: true + + name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build + + env: + GOPRIVATE: "github.com/hashicorp" + GO111MODULE: on + LD_FLAGS: ${{ needs.set-ld-flags.outputs.ldflags }} + + steps: + - uses: actions/checkout@v2 + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Go Build + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 0 + run: | + mkdir -p dist out + unset GOPATH; + go build -v -tags "${{ env.GO_TAGS }}" -ldflags "${{ env.LD_FLAGS }}" -o dist/ . + zip -r -j out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + path: out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + + - name: Linux Packaging + uses: hashicorp/actions-packaging-linux@v1 + with: + name: ${{ github.event.repository.name }} + description: "HashiCorp Packer - A tool for creating identical machine images for multiple platforms from a single source configuration" + arch: ${{ matrix.goarch }} + version: ${{ needs.get-product-version.outputs.product-version }} + maintainer: "HashiCorp" + homepage: "https://www.packer.io/docs" + license: "MPL-2.0" + binary: "dist/${{ env.PKG_NAME }}" + deb_depends: "openssl" + rpm_depends: "openssl" + config_dir: ".release/linux/package/" + preinstall: ".release/linux/preinst" + postremove: ".release/linux/postrm" + - name: Add Linux Package names to env + run: | + echo "RPM_PACKAGE=$(basename out/*.rpm)" >> $GITHUB_ENV + echo "DEB_PACKAGE=$(basename out/*.deb)" >> $GITHUB_ENV + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.RPM_PACKAGE }} + path: out/${{ env.RPM_PACKAGE }} + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.DEB_PACKAGE }} + path: out/${{ env.DEB_PACKAGE }} + + build-darwin: + needs: + - get-product-version + - get-go-version + - set-ld-flags + runs-on: macos-latest + strategy: + matrix: + goos: [ darwin ] + goarch: [ "amd64", "arm64" ] + go: [ "${{ needs.get-go-version.outputs.go-version }}" ] + fail-fast: true + name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build + + env: + GOPRIVATE: "github.com/hashicorp" + GO111MODULE: on + LD_FLAGS: ${{ needs.set-ld-flags.outputs.ldflags }} + + steps: + - uses: actions/checkout@v2 + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Go Build + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 0 + run: | + mkdir -p dist out + unset GOPATH; + go build -v -tags "${{ env.GO_TAGS }} netcgo" -ldflags "${{ env.LD_FLAGS }}" -o dist/ . + zip -r -j out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + path: out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + + build-docker: + name: Docker light ${{ matrix.arch }} build + needs: + - get-product-version + - build-linux + runs-on: ubuntu-latest + strategy: + matrix: + arch: ["arm", "arm64", "386", "amd64"] + env: + repo: ${{ github.event.repository.name }} + version: ${{ needs.get-product-version.outputs.product-version }} + steps: + - uses: actions/checkout@v2 + - name: Docker Build (Action) + uses: hashicorp/actions-docker-build@v1 + with: + version: ${{ env.version }} + target: release-light + arch: ${{ matrix.arch }} + tags: | + docker.io/hashicorp/${{env.repo}}:light + docker.io/hashicorp/${{env.repo}}:light-${{env.version}} + docker.io/hashicorp/${{env.repo}}:${{env.version}} + public.ecr.aws/hashicorp/${{env.repo}}:light + public.ecr.aws/hashicorp/${{env.repo}}:light-${{env.version}} + public.ecr.aws/hashicorp/${{env.repo}}:${{env.version}} diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml new file mode 100644 index 000000000..44e7fefa8 --- /dev/null +++ b/.github/workflows/go-test.yml @@ -0,0 +1,38 @@ +# +# This GitHub action runs Packer go tests across +# Windows, Linux, and MacOS runners. +# + +name: "Go Test" + +on: [ workflow_dispatch, push ] + +jobs: + linux-go-tests: + runs-on: ubuntu-latest + container: + image: ghcr.io/ghcri/golang:1.17 + name: Linux go tests + steps: + - uses: actions/checkout@v2 + - run: TESTARGS="-coverprofile=coverage.txt -covermode=atomic" make ci + darwin-go-tests: + runs-on: macos-latest + name: Darwin go tests + env: + PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' + - run: go test ./... -coverprofile=coverage.txt -covermode=atomic + windows-go-tests: + runs-on: windows-latest + name: Windows go tests + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' + - run: go test ./... -coverprofile=coverage.txt -covermode=atomic \ No newline at end of file diff --git a/.github/workflows/go-validate.yml b/.github/workflows/go-validate.yml new file mode 100644 index 000000000..c386cceaa --- /dev/null +++ b/.github/workflows/go-validate.yml @@ -0,0 +1,50 @@ +# +# This GitHub action runs basic linting checks for Packer. +# + +name: "Go Validate" + +on: [ workflow_dispatch, push ] + +jobs: + check-mod-tidy: + runs-on: ubuntu-latest + name: Go Mod Tidy + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' + - run: go mod tidy + check-lint: + runs-on: ubuntu-latest + name: Lint + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' + - run: echo "$GITHUB_SHA" + - run: git fetch --all + - run: echo $(git merge-base origin/master $GITHUB_SHA) + - run: make ci-lint + check-fmt: + runs-on: ubuntu-latest + name: Fmt check + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' + - run: make fmt-check + check-generate: + runs-on: ubuntu-latest + name: Generate check + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' + - run: make generate-check diff --git a/.github/workflows/nightly-release-readme.md b/.github/workflows/nightly-release-readme.md new file mode 100644 index 000000000..4f9251564 --- /dev/null +++ b/.github/workflows/nightly-release-readme.md @@ -0,0 +1,5 @@ +Nightly releases are snapshots of the development activity on the Packer project that may include new features and bug fixes scheduled for upcoming [releases](https://github.com/hashicorp/packer/milestones). These releases are made available to make it easier for users to test their existing build configurations against the latest Packer code base for potential issues or to experiment with new features, with a chance to provide feedback on ways to improve the changes before being released. + +As these releases are snapshots of the latest code, you may encounter an issue compared to the latest stable release. Users are encouraged to run nightly releases in a non production environment. If you encounter an issue, please check our [issue tracker](https://github.com/hashicorp/packer/issues) to see if the issue has already been reported; if a report hasn't been made, please report it so we can review the issue and make any needed fixes. + +**Note**: Nightly releases are only available via GitHub Releases, and artifacts are not codesigned or notarized. Distribution via other [Release Channels](https://www.hashicorp.com/official-release-channels) such as the Releases Site or Homebrew is not yet supported. diff --git a/.github/workflows/nightly-release.yml b/.github/workflows/nightly-release.yml new file mode 100644 index 000000000..3c4c54da7 --- /dev/null +++ b/.github/workflows/nightly-release.yml @@ -0,0 +1,100 @@ +# +# This GitHub action triggers a fresh set of Packer builds +# and publishes them to GitHub Releases under the `nightly` tag. +# Note that artifacts available via GitHub Releases are not codesigned or notarized. +# Failures are reported to slack. +# + +name: Nightly Release + +on: + schedule: + # Runs against the default branch every day at midnight + - cron: "0 0 * * *" + +jobs: + # Build a fresh set of artifacts + build-artifacts: + uses: hashicorp/packer/.github/workflows/build.yml@master + github-release: + needs: build-artifacts + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Download built artifacts + uses: actions/download-artifact@v2 + with: + path: out/ + # Set BUILD_OUTPUT_LIST to out\-.\*,out\... + # This is needed to attach the build artifacts to the GitHub Release + - name: Set BUILD_OUTPUT_LIST + run: | + echo "$(ls -xm1 out/)" > tmp.txt + cat tmp.txt | sed 's:.*:out/&/*:' > tmp2.txt + echo "BUILD_OUTPUT_LIST=$(cat tmp2.txt | tr '\n' ',' | perl -ple 'chop')" >> $GITHUB_ENV + rm -rf tmp.txt && rm -rf tmp2.txt + - name: Advance nightly tag + uses: actions/github-script@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + await github.git.deleteRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: "tags/nightly" + }) + } catch (e) { + console.log("Warning: The nightly tag doesn't exist yet, so there's nothing to do. Trace: " + e) + } + await github.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: "refs/tags/nightly", + sha: context.sha + }) + # This will create a new GitHub Release called `nightly` + # If a release with this name already exists, it will overwrite the existing data + - name: Create a nightly GitHub prerelease + uses: ncipollo/release-action@v1 + with: + name: nightly + artifacts: "${{ env.BUILD_OUTPUT_LIST }}" + tag: nightly + bodyFile: ".github/workflows/nightly-release-readme.md" + prerelease: true + allowUpdates: true + removeArtifacts: true + token: ${{ secrets.GITHUB_TOKEN }} + # Send a slack notification if either job defined above fails + slack-notify: + needs: + - build-artifacts + - github-release + if: always() && (needs.build-artifacts.result == 'failure' || needs.github-release.result == 'failure') + runs-on: ubuntu-latest + steps: + - name: Send slack notification on failure + uses: slackapi/slack-github-action@v1.18.0 + with: + payload: | + { + "text": ":alert: Packer Nightly Release *FAILED* :alert:", + "attachments": [ + { + "color": "#C41E3A", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Branch: `${{ github.ref_name }}`\nRef: ${{ github.event.pull_request.html_url || github.event.head_commit.url }}\nWorkflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } + } + ] + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK \ No newline at end of file diff --git a/.github/workflows/website-docker-publish.yml b/.github/workflows/website-docker-publish.yml new file mode 100644 index 000000000..34f60d9a1 --- /dev/null +++ b/.github/workflows/website-docker-publish.yml @@ -0,0 +1,70 @@ +# +# This GitHub action builds, tags, and publishes the Packer +# website docker image when dependencies have changed. +# Failures are reported to slack. +# + +name: "Website Docker Publish" + +on: + push: + # Sequence of patterns matched against refs/heads + branches: + # Push events on master branch + - 'master' + +jobs: + website-docker-publish: + runs-on: ubuntu-latest + name: Build Docker Image if Necessary + env: + DOCKER_USER: ${{ secrets.WEBSITE_DOCKER_USER }} + DOCKER_TOKEN: ${{ secrets.WEBSITE_DOCKER_TOKEN }} + steps: + - uses: actions/checkout@v2 + - uses: docker/login-action@v1 + with: + username: ${{ env.DOCKER_USER }} + password: ${{ env.DOCKER_TOKEN }} + - run: | + IMAGE_TAG=$(cat website/Dockerfile website/package-lock.json | sha256sum | awk '{print $1;}') + echo "Using $IMAGE_TAG" + if curl https://hub.docker.com/v2/repositories/hashicorp/packer-website/tags/$IMAGE_TAG -fsL > /dev/null; then + echo "Dependencies have not changed, not building a new website docker image." + else + cd website/ + docker build -t hashicorp/packer-website:$IMAGE_TAG . + docker tag hashicorp/packer-website:$IMAGE_TAG hashicorp/packer-website:latest + docker push hashicorp/packer-website + fi + # Send a slack notification if the job defined above fails + slack-notify: + needs: + - website-docker-publish + if: always() && (needs.website-docker-publish.result == 'failure') + runs-on: ubuntu-latest + steps: + - name: Send slack notification on failure + uses: slackapi/slack-github-action@v1.18.0 + with: + payload: | + { + "text": ":alert: Packer Website Docker Publish *FAILED* :alert:", + "attachments": [ + { + "color": "#C41E3A", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Branch: `${{ github.ref_name }}`\nRef: ${{ github.event.pull_request.html_url || github.event.head_commit.url }}\nWorkflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } + } + ] + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK \ No newline at end of file diff --git a/.go-version b/.go-version new file mode 100644 index 000000000..ff278344b --- /dev/null +++ b/.go-version @@ -0,0 +1 @@ +1.17.5 diff --git a/.release/ci.hcl b/.release/ci.hcl new file mode 100644 index 000000000..2c99b3cfb --- /dev/null +++ b/.release/ci.hcl @@ -0,0 +1,240 @@ +schema = "1" + +project "packer" { + team = "#proj-packer-releases" + slack { + notification_channel = "C032TD9KCMQ" + } + github { + organization = "hashicorp" + repository = "packer" + release_branches = [ + "master" + ] + } +} + +event "merge" { + // "entrypoint" to use if build is not run automatically + // i.e. send "merge" complete signal to orchestrator to trigger build +} + +event "build" { + depends = ["merge"] + action "build" { + organization = "hashicorp" + repository = "packer" + workflow = "build" + } +} + +event "upload-dev" { + depends = ["build"] + action "upload-dev" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "upload-dev" + depends = ["build"] + } + + notification { + on = "fail" + } +} + +event "quality-tests" { + depends = ["upload-dev"] + action "quality-tests" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "quality-tests" + } + + notification { + on = "fail" + } +} + +event "security-scan-binaries" { + depends = ["upload-dev"] + action "security-scan-binaries" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "security-scan-binaries" + config = "security-scan.hcl" + } + + notification { + on = "fail" + } +} + +event "security-scan-containers" { + depends = ["security-scan-binaries"] + action "security-scan-containers" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "security-scan-containers" + config = "security-scan.hcl" + } + + notification { + on = "fail" + } +} + +event "notarize-darwin-amd64" { + depends = ["security-scan-containers"] + action "notarize-darwin-amd64" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "notarize-darwin-amd64" + } + + notification { + on = "fail" + } +} + +event "notarize-windows-386" { + depends = ["notarize-darwin-amd64"] + action "notarize-windows-386" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "notarize-windows-386" + } + + notification { + on = "fail" + } +} + +event "notarize-windows-amd64" { + depends = ["notarize-windows-386"] + action "notarize-windows-amd64" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "notarize-windows-amd64" + } + + notification { + on = "fail" + } +} + +event "sign" { + depends = ["notarize-windows-amd64"] + action "sign" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "sign" + } + + notification { + on = "fail" + } +} + +event "sign-linux-rpms" { + depends = ["sign"] + action "sign-linux-rpms" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "sign-linux-rpms" + } + + notification { + on = "fail" + } +} + +event "verify" { + depends = ["sign-linux-rpms"] + action "verify" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "verify" + } + + notification { + on = "fail" + } +} + +## These are promotion and post-publish events +## they should be added to the end of the file after the verify event stanza. + +event "trigger-staging" { +// This event is dispatched by the bob trigger-promotion command +// and is required - do not delete. +} + +event "promote-staging" { + depends = ["trigger-staging"] + action "promote-staging" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "promote-staging" + } + + notification { + on = "always" + } +} + +event "promote-staging-docker" { + depends = ["promote-staging"] + action "promote-staging-docker" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "promote-staging-docker" + } + + notification { + on = "always" + } +} + +event "trigger-production" { +// This event is dispatched by the bob trigger-promotion command +// and is required - do not delete. +} + +event "promote-production" { + depends = ["trigger-production"] + action "promote-production" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "promote-production" + } + + notification { + on = "always" + } +} + +event "promote-production-docker" { + depends = ["promote-production"] + action "promote-production-docker" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "promote-production-docker" + } + + notification { + on = "always" + } +} + +event "promote-production-packaging" { + depends = ["promote-production-docker"] + action "promote-production-packaging" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "promote-production-packaging" + } + + notification { + on = "always" + } +} \ No newline at end of file diff --git a/.release/docker/README.md b/.release/docker/README.md new file mode 100644 index 000000000..4fdf92729 --- /dev/null +++ b/.release/docker/README.md @@ -0,0 +1,99 @@ +# Packer Docker Container + +The root of this repository contains the officially supported HashiCorp Dockerfile to build the hashicorp/packer docker image. The `dev` docker image should be built for local dev and testing, while the production docker image, `release`, is built in CI and makes use of CI-built binaries. The `official` docker image is built using the official binaries from releases.hashicorp.com. + +## Build + +See the Makefile targets in the root of this repository for building Packer images in either +development or release modes: + + - `make docker-dev` + - `make docker-official` + - `make docker-multiarch-official` + - `make docker` + +### Usage + +This repository automatically builds containers for using the +[`packer`](https://packer.io) command line program. It contains two distinct +varieties of build, an `official` version, aka `light`, which just contains the binary. +It also contains a `dev` version, aka `full`, which compiles the binary from source +inside the container before exposing it for use. + +##### `official` + +The `official` version of this container will copy the current stable version of +the binary, taken from releases.hashicorp.com, into the container. It will also +set it for use as the default entrypoint. This will be the best option for most uses, +especially if you are just looking to run the binary from a container. This image +is tagged as both `official` and `light`. +The `latest` tag on DockerHub also points to this version. + +You can use this version with the following: +```shell +docker run hashicorp/packer:official +``` + +##### `dev` + +The `dev` version of this container contains all of the source code found in +the current ref of this [repository](https://github.com/hashicorp/packer). Using [Google's +official `golang` image](https://hub.docker.com/_/golang/) as a base, this +container will copy the source from the current branch, build the binary, and +expose it for running. Because all build artifacts are included, it should be quite a bit larger than +the `official` image. This version of the container is most useful for development or +debugging. + +You can use this version with the following: +```shell +docker run hashicorp/packer:dev +``` + +#### Running a build: + +The easiest way to run a command that references a configuration with one or more template files, is to mount a volume for the local workspace. + +Running `packer init` +```shell +docker run \ + -v `pwd`:/workspace -w /workspace \ + -e PACKER_PLUGIN_PATH=/workspace/.packer.d/plugins \ + hashicorp/packer:latest \ + init . +``` + +~> **Note**: packer init is available from Packer v1.7.0 and later + +The command will mount the working directory (`pwd`) to `workspace`, which is the working directory (`-w`) inside the container. +Any plugin installed with `packer init` will be installed under the directory specified under the `PACKER_PLUGIN_PATH` environment variable. `PACKER_PLUGIN_PATH` must be set to a path inside the volume mount so that plugins can become available at `packer build`. + +Running `packer build` +```shell +docker run \ + -v `pwd`:/workspace -w /workspace \ + -e PACKER_PLUGIN_PATH=/workspace/.packer.d/plugins \ + hashicorp/packer:latest \ + build . +``` +##### Building old-legacy JSON templates + +For old-legacy JSON, the build command must specify the template file(s). + +```shell +docker run \ + -v `pwd`:/workspace -w /workspace \ + hashicorp/packer:latest \ + build template.json +``` + +For the [manual installation](https://www.packer.io/docs/plugins#installing-plugins) of third-party plugins, we recommended that plugin binaries are placed under a sub-directory under the working directory. Add `-e PACKER_PLUGIN_PATH=/workspace/` to the command above to tell Packer where the plugins are. + +To pass a var file (`var.json`) to the build command: + +```shell +docker run \ + -v `pwd`:/workspace -w /workspace \ + hashicorp/packer:latest \ + build --var-file var.json template.json +``` +`var.json` is expected to be inside the local working directory (`pwd`) and in the container's workspace mount. diff --git a/.release/linux/package/etc/packer.d/packer.env b/.release/linux/package/etc/packer.d/packer.env new file mode 100644 index 000000000..e69de29bb diff --git a/.release/linux/package/usr/lib/systemd/system/packer.service b/.release/linux/package/usr/lib/systemd/system/packer.service new file mode 100644 index 000000000..f97725ad5 --- /dev/null +++ b/.release/linux/package/usr/lib/systemd/system/packer.service @@ -0,0 +1,23 @@ +[Unit] +Description="HashiCorp Packer - A tool for creating identical machine images for multiple platforms from a single source configuration" +Documentation=https://www.packer.io/docs +StartLimitIntervalSec=60 +StartLimitBurst=3 + +[Service] +EnvironmentFile=-/etc/packer.d/packer.env +User=packer +Group=packer +ProtectSystem=full +ProtectHome=read-only +ExecStart=/usr/bin/packer server -config=/etc/packer.d +ExecReload=/bin/kill --signal HUP $MAINPID +KillMode=process +KillSignal=SIGINT +Restart=on-failure +RestartSec=5 +TimeoutStopSec=30 +LimitMEMLOCK=infinity + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/.release/linux/postrm b/.release/linux/postrm new file mode 100644 index 000000000..0f32404c5 --- /dev/null +++ b/.release/linux/postrm @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ "$1" = "purge" ] +then + userdel packer +fi + +exit 0 \ No newline at end of file diff --git a/.release/linux/preinst b/.release/linux/preinst new file mode 100644 index 000000000..d5068c896 --- /dev/null +++ b/.release/linux/preinst @@ -0,0 +1,13 @@ +#!/bin/bash + +set -eu + +USER="packer" + +if ! id -u $USER > /dev/null 2>&1; then + useradd \ + --system \ + --user-group \ + --shell /bin/false \ + $USER +fi \ No newline at end of file diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl new file mode 100644 index 000000000..4b0717c73 --- /dev/null +++ b/.release/security-scan.hcl @@ -0,0 +1,13 @@ +container { + dependencies = false + alpine_secdb = true + secrets = false +} + +binary { + secrets = true + go_modules = true + osv = true + oss_index = true + nvd = true +} \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS index c18279bee..0efb6b1ac 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,6 @@ * @hashicorp/packer -/post-processor/checksum/ v.tolstov@selfip.ru +# release configuration + +/.release/ @hashicorp/release-engineering +/.github/workflows/build.yml @hashicorp/release-engineering diff --git a/Dockerfile b/Dockerfile index 0b5f50a1b..5928e73d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,106 @@ -FROM docker.mirror.hashicorp.services/ubuntu:16.04 +# ======================================================================== +# +# This Dockerfile contains multiple targets. +# Use 'docker build --target= .' to build one. +# e.g. `docker build --target=release-light .` +# +# All non-dev targets have a VERSION argument that must be provided +# via --build-arg=VERSION= when building. +# e.g. --build-arg VERSION=1.11.2 +# +# For local dev and testing purposes, please build and use the `dev` docker image. +# +# ======================================================================== -ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update && apt-get install -y \ - locales \ - openssh-server \ - sudo +# Development docker image primarily used for development and debugging. +# This image builds from the locally generated binary in ./bin/. +# To generate the local binary, run `make dev`. +FROM docker.mirror.hashicorp.services/alpine:latest as dev -RUN locale-gen en_US.UTF-8 +RUN apk add --no-cache git bash openssl ca-certificates -RUN if ! getent passwd vagrant; then useradd -d /home/vagrant -m -s /bin/bash vagrant; fi \ - && echo 'vagrant ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ - && mkdir -p /etc/sudoers.d \ - && echo 'vagrant ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/vagrant \ - && chmod 0440 /etc/sudoers.d/vagrant +COPY bin/packer /bin/packer -RUN mkdir -p /home/vagrant/.ssh \ - && chmod 0700 /home/vagrant/.ssh \ - && wget --no-check-certificate \ - https://raw.github.com/hashicorp/vagrant/master/keys/vagrant.pub \ - -O /home/vagrant/.ssh/authorized_keys \ - && chmod 0600 /home/vagrant/.ssh/authorized_keys \ - && chown -R vagrant /home/vagrant/.ssh +ENTRYPOINT ["/bin/packer"] -RUN mkdir -p /run/sshd -CMD /usr/sbin/sshd -D \ - -o UseDNS=no \ - -o PidFile=/tmp/sshd.pid +# Official docker image that includes binaries from releases.hashicorp.com. +# This downloads the release from releases.hashicorp.com and therefore requires that +# the release is published before building the Docker image. +FROM docker.mirror.hashicorp.services/alpine:latest as official + +# This is the release of Packer to pull in. +ARG VERSION + +LABEL name="Packer" \ + maintainer="HashiCorp Packer Team " \ + vendor="HashiCorp" \ + version=$VERSION \ + release=$VERSION \ + summary="Packer is a tool for creating identical machine images for multiple platforms from a single source configuration." \ + description="Packer is a tool for creating identical machine images for multiple platforms from a single source configuration. Please submit issues to https://github.com/hashicorp/packer/issues" + +# This is the location of the releases. +ENV HASHICORP_RELEASES=https://releases.hashicorp.com + +RUN set -eux && \ + apk add --no-cache git bash wget openssl gnupg && \ + gpg --keyserver keyserver.ubuntu.com --recv-keys C874011F0AB405110D02105534365D9472D7468F && \ + mkdir -p /tmp/build && \ + cd /tmp/build && \ + apkArch="$(apk --print-arch)" && \ + case "${apkArch}" in \ + aarch64) packerArch='arm64' ;; \ + armhf) packerArch='arm' ;; \ + x86) packerArch='386' ;; \ + x86_64) packerArch='amd64' ;; \ + *) echo >&2 "error: unsupported architecture: ${apkArch} (see ${HASHICORP_RELEASES}/packer/${VERSION}/)" && exit 1 ;; \ + esac && \ + wget ${HASHICORP_RELEASES}/packer/${VERSION}/packer_${VERSION}_linux_${packerArch}.zip && \ + wget ${HASHICORP_RELEASES}/packer/${VERSION}/packer_${VERSION}_SHA256SUMS && \ + wget ${HASHICORP_RELEASES}/packer/${VERSION}/packer_${VERSION}_SHA256SUMS.sig && \ + gpg --batch --verify packer_${VERSION}_SHA256SUMS.sig packer_${VERSION}_SHA256SUMS && \ + grep packer_${VERSION}_linux_${packerArch}.zip packer_${VERSION}_SHA256SUMS | sha256sum -c && \ + unzip -d /tmp/build packer_${VERSION}_linux_${packerArch}.zip && \ + cp /tmp/build/packer /bin/packer && \ + cd /tmp && \ + rm -rf /tmp/build && \ + gpgconf --kill all && \ + apk del gnupg openssl && \ + rm -rf /root/.gnupg && \ + # Tiny smoke test to ensure the binary we downloaded runs + packer version + +ENTRYPOINT ["/bin/packer"] + + +# Light docker image which can be used to run the binary from a container. +# This image builds from the locally generated binary in ./bin/, and from CI-built binaries within CI. +# To generate the local binary, run `make dev`. +# This image is published to DockerHub under the `light`, `light-$VERSION`, and `latest` tags. +FROM docker.mirror.hashicorp.services/alpine:latest as release-light + +ARG VERSION +ARG BIN_NAME + +# TARGETARCH and TARGETOS are set automatically when --platform is provided. +ARG TARGETOS TARGETARCH + +LABEL name="Packer" \ + maintainer="HashiCorp Packer Team " \ + vendor="HashiCorp" \ + version=$VERSION \ + release=$VERSION \ + summary="Packer is a tool for creating identical machine images for multiple platforms from a single source configuration." \ + description="Packer is a tool for creating identical machine images for multiple platforms from a single source configuration. Please submit issues to https://github.com/hashicorp/packer/issues" + +RUN apk add --no-cache git bash wget openssl gnupg + +COPY dist/$TARGETOS/$TARGETARCH/$BIN_NAME /bin/ + +ENTRYPOINT ["/bin/packer"] + + +# Set default target to 'dev'. +FROM dev \ No newline at end of file diff --git a/Makefile b/Makefile index 71e3a33e5..88fe05783 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ GOLDFLAGS=-X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT)$(GIT_DIRTY) $(LDFLAGS) export GOLDFLAGS .PHONY: bin checkversion ci ci-lint default install-build-deps install-gen-deps fmt fmt-docs fmt-examples generate install-lint-deps lint \ - releasebin test testacc testrace + releasebin test testacc testrace version default: install-build-deps install-gen-deps generate dev @@ -75,6 +75,45 @@ dev: ## Build and install a development build @cp $(GOPATH)/bin/packer bin/packer @cp $(GOPATH)/bin/packer pkg/$(GOOS)_$(GOARCH) +# Docker build variables and targets +REGISTRY_NAME?=docker.io/hashicorp +IMAGE_NAME=packer +VERSION?=1.7.10 +IMAGE_TAG=$(REGISTRY_NAME)/$(IMAGE_NAME):$(VERSION) +IMAGE_TAG_DEV=$(REGISTRY_NAME)/$(IMAGE_NAME):latest-$(shell git rev-parse --short HEAD) + +docker: docker-official +docker-light: docker-official + +# Builds from the releases.hashicorp.com official binary +docker-official: + docker build \ + --tag $(IMAGE_TAG) \ + --tag hashicorp/packer:latest \ + --target=official \ + --build-arg VERSION=$(VERSION) \ + . + +# Builds multiarch from the releases.hashicorp.com official binary +docker-multiarch-official: + docker buildx build \ + --tag $(IMAGE_TAG) \ + --tag hashicorp/packer:latest \ + --target=official \ + --build-arg VERSION=$(VERSION) \ + --platform linux/amd64,linux/arm64 \ + . + +# Builds from the locally generated binary in ./bin/ +# To generate the local binary, run `make dev` +docker-dev: export GOOS=linux +docker-dev: export GOARCH=amd64 +docker-dev: dev + @docker build \ + --tag $(IMAGE_TAG_DEV) \ + --target=dev \ + . + lint: install-lint-deps ## Lint Go code @if [ ! -z $(PKG_NAME) ]; then \ echo "golangci-lint run ./$(PKG_NAME)/..."; \ @@ -161,3 +200,7 @@ vet: ## Vet Go code help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +# This is used for release builds by .github/workflows/build.yml +version: + @$(CURDIR)/scripts/version.sh version/version.go \ No newline at end of file diff --git a/README.md b/README.md index 9ead9ef01..3f0a09d68 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ # Packer -[![Build Status][circleci-badge]][circleci] +[![Build Status]][github-badge] [![Discuss](https://img.shields.io/badge/discuss-packer-3d89ff?style=flat)](https://discuss.hashicorp.com/c/packer) [![PkgGoDev](https://pkg.go.dev/badge/github.com/hashicorp/packer)](https://pkg.go.dev/github.com/hashicorp/packer) [![GoReportCard][report-badge]][report] -[circleci-badge]: https://circleci.com/gh/hashicorp/packer.svg?style=svg -[circleci]: https://app.circleci.com/pipelines/github/hashicorp/packer +[github-badge]: https://github.com/hashicorp/packer/actions/workflows/build.yml/badge.svg [appveyor-badge]: https://ci.appveyor.com/api/projects/status/miavlgnp989e5obc/branch/master?svg=true [godoc-badge]: https://godoc.org/github.com/hashicorp/packer?status.svg [godoc]: https://godoc.org/github.com/hashicorp/packer diff --git a/acctest/plugin/plugin_acc_test.go b/acctest/plugin/plugin_acc_test.go index b1d1f7d20..b0eb24be1 100644 --- a/acctest/plugin/plugin_acc_test.go +++ b/acctest/plugin/plugin_acc_test.go @@ -86,9 +86,8 @@ func cleanupPluginInstallation(plugin addrs.Plugin) error { plugin.Namespace, plugin.Type) - if _, ok := os.LookupEnv("CIRCLECI"); ok { - pluginPath = filepath.Join(home, - ".config", + if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { + pluginPath = filepath.Join(xdgConfigHome, "packer", "plugins", plugin.Hostname, @@ -118,9 +117,8 @@ func checkPluginInstallation(initOutput string, plugin addrs.Plugin) error { plugin.Namespace, plugin.Type) - if _, ok := os.LookupEnv("CIRCLECI"); ok { - pluginPath = filepath.Join(home, - ".config", + if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { + pluginPath = filepath.Join(xdgConfigHome, "packer", "plugins", plugin.Hostname, diff --git a/go.mod b/go.mod index 26cb44a6e..06b347568 100644 --- a/go.mod +++ b/go.mod @@ -264,4 +264,4 @@ require ( gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) -go 1.17 +go 1.17 \ No newline at end of file diff --git a/go.sum b/go.sum index f2fd2dabf..aa40c50d7 100644 --- a/go.sum +++ b/go.sum @@ -1768,4 +1768,4 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= \ No newline at end of file diff --git a/scripts/version.sh b/scripts/version.sh new file mode 100755 index 000000000..c854cab30 --- /dev/null +++ b/scripts/version.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +version_file=$1 +version=$(awk '$1 == "Version" && $2 == "=" { gsub(/"/, "", $3); print $3 }' < "${version_file}") +prerelease=$(awk '$1 == "VersionPrerelease" && $2 == "=" { gsub(/"/, "", $3); print $3 }' < "${version_file}") + +if [ -n "$prerelease" ]; then + echo "${version}-${prerelease}" +else + echo "${version}" +fi \ No newline at end of file diff --git a/version/version.go b/version/version.go index 9ca3115c1..5ec5b8751 100644 --- a/version/version.go +++ b/version/version.go @@ -5,16 +5,22 @@ import ( pluginVersion "github.com/hashicorp/packer-plugin-sdk/version" ) -// The git commit that was compiled. This will be filled in by the compiler. -var GitCommit string +var ( + // The git commit that was compiled. This will be filled in by the compiler. + GitCommit string + GitDescribe string -// The main version number that is being run at the moment. -const Version = "1.7.11" + // Whether cgo is enabled or not; set at build time + CgoEnabled bool -// A pre-release marker for the version. If this is "" (empty string) -// then it means that it is a final release. Otherwise, this is a pre-release -// such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" + // The main version number that is being run at the moment. + Version = "1.7.11" + // A pre-release marker for the version. If this is "" (empty string) + // then it means that it is a final release. Otherwise, this is a pre-release + // such as "dev" (in development), "beta", "rc1", etc. + VersionPrerelease = "dev" + VersionMetadata = "" +) var PackerVersion *pluginVersion.PluginVersion