packer-cn/scripts/build.sh

157 lines
3.9 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# This script builds the application from source for multiple platforms.
# Determine the arch/os combos we're building for
ALL_XC_ARCH="386 amd64 arm arm64 ppc64le mips mips64 mipsle mipsle64 s390x"
ALL_XC_OS="linux darwin windows freebsd openbsd solaris"
SKIPPED_OSARCH="!darwin/arm !freebsd/arm !freebsd/arm64"
# Exit immediately if a command fails
set -e
# Validates that a necessary tool is on the PATH
function validateToolPresence
{
local TOOLNAME=$1
if ! which ${TOOLNAME} >/dev/null; then
echo "${TOOLNAME} is not on the path. Exiting..."
exit 1
fi
}
# Validates that all used tools are present; exits when any is not found
function validatePreconditions
{
echo "==> Checking for necessary tools..."
validateToolPresence realpath
validateToolPresence dirname
validateToolPresence tr
validateToolPresence find
}
# Get the parent directory of where this script is.
# NOTE: I'm unsure why you don't just use realpath like below
function enterPackerSourceDir
{
echo "==> Entering Packer source dir..."
local BUILD_SCRIPT_PATH="${BASH_SOURCE[0]}"
SOURCEDIR=$(dirname $(dirname $(realpath "${BUILD_SCRIPT_PATH}")))
cd ${SOURCEDIR}
}
function ensureOutputStructure {
echo "==> Ensuring output directories are present..."
mkdir -p bin/
mkdir -p pkg/
}
function cleanOutputDirs {
echo "==> Removing old builds..."
rm -f bin/*
rm -fr pkg/*
}
function lowerCaseOSType {
local OS_TYPE=${OSTYPE:=`uname`}
echo "${OS_TYPE}" | tr "[:upper:]" "[:lower:]"
}
# Returns the OS appropriate path separator
function getPathSeparator {
# helpers for Cygwin-hosted builds
case "$(lowerCaseOSType)" in
mingw*|msys*|cygwin*)
# cygwin only translates ';' to ':' on select environment variables
echo ';'
;;
*) echo ':'
esac
}
function convertPathOnCygwin() {
local flag
local somePath
if [ "${1:0:1}" = '-' ]; then
flag=$1
somePath=$2
else
somePath=$1
fi
[ -n "${somePath}" ] || return 0
case "$(lowerCaseOSType)" in
cygwin*)
cygpath ${flag} -- "${somePath}"
;;
*) echo "${somePath}"
esac
}
validatePreconditions
enterPackerSourceDir
ensureOutputStructure
cleanOutputDirs
PATHSEP=$(getPathSeparator)
# XXX works in MINGW?
# FIXME: What if go is not in the PATH and GOROOT isn't set?
which go &>/dev/null || PATH+=":`convertPathOnCygwin "${GOROOT:?}"`/bin"
OLDIFS="${IFS}"
# make sure GOPATH is consistent - Windows binaries can't handle Cygwin-style paths
IFS="${PATHSEP}"
for d in ${GOPATH:-$(go env GOPATH)}; do
_GOPATH+="${_GOPATH:+${PATHSEP}}$(convertPathOnCygwin --windows "${d}")"
done
GOPATH="$_GOPATH"
# locate 'gox' and traverse GOPATH if needed
which "${GOX:=gox}" &>/dev/null || {
for d in ${GOPATH}; do
GOX="$(convertPathOnCygwin --unix "${d}")/bin/gox"
[ -x "${GOX}" ] && break || unset GOX
done
}
IFS="$OLDIFS"
# Build!
echo "==> Building..."
# If in dev mode, only build for ourself
if [ -n "${PACKER_DEV+x}" ]; then
XC_OS=$(go env GOOS)
XC_ARCH=$(go env GOARCH)
fi
fix builds on linux (#9031) * fix builds on linux * Build: Move to CGO_ENABLED=0 (#9057) After further investigation on cross-compiling Go bins on Linux. I found that statically linking against GCC (for libc) failed to build for ARM and introduced a possible licensing issue as our bins would essentially be bundling libc into the bin. Diving further into cross compiling on Linux I found that the defacto solution is to compile with CGO disabled - this was also found to be the case for other HashiCorp products. Disabling CGO has the limitation of not allowing the use of any pkg that calls out to C (net, os), but in looking into the Packer code base and the relevant Go code base it appears that the latest versions of Go have pure Go implementations of the said packages so I believe we are good to go. I should also point out that CGO is disabled by default when cross compiling via `go build`. However, the GOX tool will enable it if it is not explicitly disabled. Below are three test cases executed to validate the compile bins work as expected. Build results after change ``` ⇶ make bin WARN: 'make bin' is for debug / test builds only. Use 'make release' for release builds. ==> Checking for necessary tools... ==> Entering Packer source dir... ==> Ensuring output directories are present... ==> Removing old builds... ==> Building... Number of parallel builds: 7 --> windows/amd64: github.com/hashicorp/packer --> linux/arm64: github.com/hashicorp/packer --> linux/386: github.com/hashicorp/packer --> linux/arm: github.com/hashicorp/packer --> darwin/amd64: github.com/hashicorp/packer --> windows/386: github.com/hashicorp/packer --> linux/amd64: github.com/hashicorp/packer --> darwin/386: github.com/hashicorp/packer ==> Copying binaries for this platform... './pkg/linux_amd64/packer' -> 'bin/packer' './pkg/linux_amd64/packer' -> '/home/wilken/Development/go/bin/packer' ==> Results: total 111M -rwxr-xr-x 1 wilken wilken 111M Apr 13 12:29 packer ``` Packer executed on ARM based machine ``` ubuntu@ip-172-31-10-18:~$ ./packer version Packer v1.5.6-dev (314ac5b65+CHANGES ubuntu@ip-172-31-10-18:~$ uname -a Linux ip-172-31-10-18 4.15.0-1054-aws #56-Ubuntu SMP Thu Nov 7 16:18:50 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux ubuntu@ip-172-31-10-18:~$ ./packer build build.json null: output will be in this color. ==> null: Running local shell script: /tmp/packer-shell170248556 null: UUID from Packer: 79cc8532-6114-925d-2a79-33ef6ce281cd Build 'null' finished. ==> Builds finished. The artifacts of successful builds are: --> null: Did not export anything. This is the null builder ``` Custom Docker image with updated bin ``` ⇶ docker run packertest:latest version Packer v1.5.6-dev (314ac5b65+CHANGES) ⇶ docker run packertest:latest build build.json null: output will be in this color. ==> null: Running local shell script: /tmp/packer-shell065599452 null: UUID from Packer: 852f0604-2be4-9e16-99af-6d7df972ac2e Build 'null' finished. ==> Builds finished. The artifacts of successful builds are: --> null: Did not export anything. This is the null builder ``` Windows AMI ``` [...] ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Adding tags to source instance amazon-ebs: Adding tag: "Name": "Packer Builder" amazon-ebs: Instance ID: i-04387545cf3e2acd3 ==> amazon-ebs: Waiting for instance (i-04387545cf3e2acd3) to become ready... ==> amazon-ebs: Skipping waiting for password since WinRM password set... ==> amazon-ebs: Using winrm communicator to connect: 18.206.100.104 ==> amazon-ebs: Waiting for WinRM to become available... amazon-ebs: WinRM connected. ==> amazon-ebs: Connected to WinRM! ==> amazon-ebs: Uploading packertest => c:/Windows/Temp ==> amazon-ebs: Provisioning with Powershell... ==> amazon-ebs: Provisioning with powershell script: /tmp/powershell-provisioner173180945 amazon-ebs: Packer v1.5.6-dev (314ac5b65+CHANGES) amazon-ebs: null: output will be in this color. amazon-ebs: ``` Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2020-04-14 14:48:50 -04:00
export CGO_ENABLED=0
${GOX:?command not found} \
-os="${XC_OS:-$ALL_XC_OS}" \
-arch="${XC_ARCH:-$ALL_XC_ARCH}" \
scripts/build: Remove unsupported Freebsd/arm builds from build chain Builds before change ``` ⇶ make bin WARN: 'make bin' is for debug / test builds only. Use 'make release' for release builds. ==> Checking for necessary tools... ==> Entering Packer source dir... ==> Ensuring output directories are present... ==> Removing old builds... ==> Building... Number of parallel builds: 3 --> linux/s390x: github.com/hashicorp/packer --> linux/amd64: github.com/hashicorp/packer --> linux/arm: github.com/hashicorp/packer --> solaris/amd64: github.com/hashicorp/packer --> linux/mips: github.com/hashicorp/packer --> freebsd/386: github.com/hashicorp/packer --> linux/arm64: github.com/hashicorp/packer --> linux/mips64: github.com/hashicorp/packer --> linux/mipsle: github.com/hashicorp/packer --> darwin/amd64: github.com/hashicorp/packer --> linux/386: github.com/hashicorp/packer --> darwin/386: github.com/hashicorp/packer --> windows/386: github.com/hashicorp/packer --> windows/amd64: github.com/hashicorp/packer --> linux/ppc64le: github.com/hashicorp/packer --> openbsd/386: github.com/hashicorp/packer --> freebsd/arm: github.com/hashicorp/packer --> openbsd/amd64: github.com/hashicorp/packer --> freebsd/amd64: github.com/hashicorp/packer 1 errors occurred: --> freebsd/arm error: exit status 2 Stderr: # github.com/shirou/gopsutil/cpu ../go/pkg/mod/github.com/shirou/gopsutil@v2.18.12+incompatible/cpu/cpu_freebsd.go:25:16: undefined: cpuTimes ../go/pkg/mod/github.com/shirou/gopsutil@v2.18.12+incompatible/cpu/cpu_freebsd.go:42:31: undefined: cpuTimes ../go/pkg/mod/github.com/shirou/gopsutil@v2.18.12+incompatible/cpu/cpu_freebsd.go:66:38: undefined: cpuTimes ../go/pkg/mod/github.com/shirou/gopsutil@v2.18.12+incompatible/cpu/cpu_freebsd.go:72:15: undefined: cpuTimes ../go/pkg/mod/github.com/shirou/gopsutil@v2.18.12+incompatible/cpu/cpu_freebsd.go:87:13: undefined: cpuTimes ==> Copying binaries for this platform... './pkg/linux_amd64/packer' -> 'bin/packer' './pkg/linux_amd64/packer' -> '/home/wilken/Development/go/bin/packer' ==> Results: total 111M -rwxr-xr-x 1 wilken wilken 111M Apr 14 22:02 packer ``` Builds after change ``` ⇶ make bin WARN: 'make bin' is for debug / test builds only. Use 'make release' for release builds. ==> Checking for necessary tools... ==> Entering Packer source dir... ==> Ensuring output directories are present... ==> Removing old builds... ==> Building... Number of parallel builds: 3 --> solaris/amd64: github.com/hashicorp/packer --> windows/amd64: github.com/hashicorp/packer --> linux/s390x: github.com/hashicorp/packer --> darwin/amd64: github.com/hashicorp/packer --> darwin/386: github.com/hashicorp/packer --> windows/386: github.com/hashicorp/packer --> freebsd/amd64: github.com/hashicorp/packer --> freebsd/386: github.com/hashicorp/packer --> openbsd/386: github.com/hashicorp/packer --> openbsd/amd64: github.com/hashicorp/packer --> linux/arm64: github.com/hashicorp/packer --> linux/386: github.com/hashicorp/packer --> linux/amd64: github.com/hashicorp/packer --> linux/arm: github.com/hashicorp/packer --> linux/mips: github.com/hashicorp/packer --> linux/ppc64le: github.com/hashicorp/packer --> linux/mips64: github.com/hashicorp/packer --> linux/mipsle: github.com/hashicorp/packer ==> Copying binaries for this platform... './pkg/linux_amd64/packer' -> 'bin/packer' './pkg/linux_amd64/packer' -> '/home/wilken/Development/golang/bin/packer' ==> Results: total 111M -rwxr-xr-x 1 wilken wilken 111M Apr 15 20:52 packer ```
2020-04-16 05:28:52 -04:00
-osarch="${SKIPPED_OSARCH}" \
-ldflags "${GOLDFLAGS}" \
-output "pkg/{{.OS}}_{{.Arch}}/packer" \
.
# trim GOPATH to first element
IFS="${PATHSEP}"
# FIXME: How do you know that the first path of GOPATH is the main GOPATH? Or is the main GOPATH meant to be the first path in GOPATH?
MAIN_GOPATH=(${GOPATH})
MAIN_GOPATH="$(convertPathOnCygwin --unix "${MAIN_GOPATH[0]}")"
IFS="${OLDIFS}"
# Copy our OS/Arch to the bin/ directory
echo "==> Copying binaries for this platform..."
DEV_PLATFORM="./pkg/$(go env GOOS)_$(go env GOARCH)"
for F in $(find ${DEV_PLATFORM} -mindepth 1 -maxdepth 1 -type f); do
cp -v ${F} bin/
cp -v ${F} "${MAIN_GOPATH}/bin/"
done
# Done!
echo
echo "==> Results:"
ls -hl bin/