1function refresh_docker_images { 2 # Arguments: 3 # $1 - Path to top level Consul source 4 # $2 - Which make target to invoke (optional) 5 # 6 # Return: 7 # 0 - success 8 # * - failure 9 10 if ! test -d "$1" 11 then 12 err "ERROR: '$1' is not a directory. refresh_docker_images must be called with the path to the top level source as the first argument'" 13 return 1 14 fi 15 16 local sdir="$1" 17 local targets="$2" 18 19 test -n "${targets}" || targets="docker-images" 20 21 make -C "${sdir}" ${targets} 22 return $? 23} 24 25function build_ui { 26 # Arguments: 27 # $1 - Path to the top level Consul source 28 # $2 - The docker image to run the build within (optional) 29 # $3 - Version override 30 # 31 # Returns: 32 # 0 - success 33 # * - error 34 # 35 # Notes: 36 # Use the GIT_COMMIT environment variable to pass off to the build 37 # Use the GIT_COMMIT_YEAR environment variable to pass off to the build 38 39 if ! test -d "$1" 40 then 41 err "ERROR: '$1' is not a directory. build_ui must be called with the path to the top level source as the first argument'" 42 return 1 43 fi 44 45 local image_name=${UI_BUILD_CONTAINER_DEFAULT} 46 if test -n "$2" 47 then 48 image_name="$2" 49 fi 50 51 local sdir="$1" 52 local ui_dir="${1}/ui-v2" 53 54 # parse the version 55 version=$(parse_version "${sdir}") 56 57 if test -n "$3" 58 then 59 version="$3" 60 fi 61 62 local commit_hash="${GIT_COMMIT}" 63 if test -z "${commit_hash}" 64 then 65 commit_hash=$(git rev-parse --short HEAD) 66 fi 67 68 local commit_year="${GIT_COMMIT_YEAR}" 69 if test -z "${commit_year}" 70 then 71 commit_year=$(git show -s --format=%cd --date=format:%Y HEAD) 72 fi 73 74 local logo_type="${CONSUL_BINARY_TYPE}" 75 if test "$logo_type" != "oss" 76 then 77 logo_type="enterprise" 78 fi 79 80 # make sure we run within the ui dir 81 pushd ${ui_dir} > /dev/null 82 83 status "Creating the UI Build Container with image: ${image_name} and version '${version}'" 84 local container_id=$(docker create -it -e "CONSUL_GIT_SHA=${commit_hash}" -e "CONSUL_COPYRIGHT_YEAR=${commit_year}" -e "CONSUL_VERSION=${version}" -e "CONSUL_BINARY_TYPE=${CONSUL_BINARY_TYPE}" ${image_name}) 85 local ret=$? 86 if test $ret -eq 0 87 then 88 status "Copying the source from '${ui_dir}' to /consul-src within the container" 89 ( 90 tar -c $(ls -A | grep -v "^(node_modules\|dist\|tmp)") | docker cp - ${container_id}:/consul-src && 91 status "Running build in container" && docker start -i ${container_id} && 92 rm -rf ${1}/ui-v2/dist && 93 status "Copying back artifacts" && docker cp ${container_id}:/consul-src/dist ${1}/ui-v2/dist 94 ) 95 ret=$? 96 docker rm ${container_id} > /dev/null 97 fi 98 99 # Check the version is baked in correctly 100 if test ${ret} -eq 0 101 then 102 local ui_vers=$(ui_version "${1}/ui-v2/dist/index.html") 103 if test "${version}" != "${ui_vers}" 104 then 105 err "ERROR: UI version mismatch. Expecting: '${version}' found '${ui_vers}'" 106 ret=1 107 fi 108 fi 109 110 # Check the logo is baked in correctly 111 if test ${ret} -eq 0 112 then 113 local ui_logo_type=$(ui_logo_type "${1}/ui-v2/dist/index.html") 114 if test "${logo_type}" != "${ui_logo_type}" 115 then 116 err "ERROR: UI logo type mismatch. Expecting: '${logo_type}' found '${ui_logo_type}'" 117 ret=1 118 fi 119 fi 120 121 # Copy UI over ready to be packaged into the binary 122 if test ${ret} -eq 0 123 then 124 rm -rf ${1}/pkg/web_ui 125 mkdir -p ${1}/pkg 126 cp -r ${1}/ui-v2/dist ${1}/pkg/web_ui 127 fi 128 129 popd > /dev/null 130 return $ret 131} 132 133function build_assetfs { 134 # Arguments: 135 # $1 - Path to the top level Consul source 136 # $2 - The docker image to run the build within (optional) 137 # 138 # Returns: 139 # 0 - success 140 # * - error 141 # 142 # Note: 143 # The GIT_COMMIT and GIT_DIRTY environment variables will be used if present 144 145 if ! test -d "$1" 146 then 147 err "ERROR: '$1' is not a directory. build_assetfs must be called with the path to the top level source as the first argument'" 148 return 1 149 fi 150 151 local sdir="$1" 152 local image_name=${GO_BUILD_CONTAINER_DEFAULT} 153 if test -n "$2" 154 then 155 image_name="$2" 156 fi 157 158 pushd ${sdir} > /dev/null 159 status "Creating the Go Build Container with image: ${image_name}" 160 local container_id=$(docker create -it -e GIT_COMMIT=${GIT_COMMIT} -e GIT_DIRTY=${GIT_DIRTY} ${image_name} make static-assets ASSETFS_PATH=bindata_assetfs.go) 161 local ret=$? 162 if test $ret -eq 0 163 then 164 status "Copying the sources from '${sdir}/(pkg/web_ui|GNUmakefile)' to /consul/pkg" 165 ( 166 tar -c pkg/web_ui GNUmakefile | docker cp - ${container_id}:/consul && 167 status "Running build in container" && docker start -i ${container_id} && 168 status "Copying back artifacts" && docker cp ${container_id}:/consul/bindata_assetfs.go ${sdir}/agent/bindata_assetfs.go 169 ) 170 ret=$? 171 docker rm ${container_id} > /dev/null 172 fi 173 popd >/dev/null 174 return $ret 175} 176 177function build_consul_post { 178 # Arguments 179 # $1 - Path to the top level Consul source 180 # $2 - Subdirectory under pkg/bin (Optional) 181 # 182 # Returns: 183 # 0 - success 184 # * - error 185 # 186 # Notes: 187 # pkg/bin is where to place binary packages 188 # pkg.bin.new is where the just built binaries are located 189 # bin is where to place the local systems versions 190 191 if ! test -d "$1" 192 then 193 err "ERROR: '$1' is not a directory. build_consul_post must be called with the path to the top level source as the first argument'" 194 return 1 195 fi 196 197 local sdir="$1" 198 199 local extra_dir_name="$2" 200 local extra_dir="" 201 202 if test -n "${extra_dir_name}" 203 then 204 extra_dir="${extra_dir_name}/" 205 fi 206 207 pushd "${sdir}" > /dev/null 208 209 # recreate the pkg dir 210 rm -r pkg/bin/${extra_dir}* 2> /dev/null 211 mkdir -p pkg/bin/${extra_dir} 2> /dev/null 212 213 # move all files in pkg.new into pkg 214 cp -r pkg.bin.new/${extra_dir}* pkg/bin/${extra_dir} 215 rm -r pkg.bin.new 216 217 DEV_PLATFORM="./pkg/bin/${extra_dir}$(go env GOOS)_$(go env GOARCH)" 218 for F in $(find ${DEV_PLATFORM} -mindepth 1 -maxdepth 1 -type f 2>/dev/null) 219 do 220 # recreate the bin dir 221 rm -r bin/* 2> /dev/null 222 mkdir -p bin 2> /dev/null 223 224 cp ${F} bin/ 225 cp ${F} ${MAIN_GOPATH}/bin 226 done 227 228 popd > /dev/null 229 230 return 0 231} 232 233function build_consul { 234 # Arguments: 235 # $1 - Path to the top level Consul source 236 # $2 - Subdirectory to put binaries in under pkg/bin (optional - must specify if needing to specify the docker image) 237 # $3 - The docker image to run the build within (optional) 238 # 239 # Returns: 240 # 0 - success 241 # * - error 242 # 243 # Note: 244 # The GOLDFLAGS and GOTAGS environment variables will be used if set 245 # If the CONSUL_DEV environment var is truthy only the local platform/architecture is built. 246 # If the XC_OS or the XC_ARCH environment vars are present then only those platforms/architectures 247 # will be built. Otherwise all supported platform/architectures are built 248 249 if ! test -d "$1" 250 then 251 err "ERROR: '$1' is not a directory. build_consul must be called with the path to the top level source as the first argument'" 252 return 1 253 fi 254 255 local sdir="$1" 256 local extra_dir_name="$2" 257 local extra_dir="" 258 local image_name=${GO_BUILD_CONTAINER_DEFAULT} 259 if test -n "$3" 260 then 261 image_name="$3" 262 fi 263 264 pushd ${sdir} > /dev/null 265 if is_set "${CONSUL_DEV}" 266 then 267 if test -z "${XC_OS}" 268 then 269 XC_OS=$(go env GOOS) 270 fi 271 272 if test -z "${XC_ARCH}" 273 then 274 XC_ARCH=$(go env GOARCH) 275 fi 276 fi 277 XC_OS=${XC_OS:-"solaris darwin freebsd linux windows"} 278 XC_ARCH=${XC_ARCH:-"386 amd64 arm arm64"} 279 280 if test -n "${extra_dir_name}" 281 then 282 extra_dir="${extra_dir_name}/" 283 fi 284 285 # figure out if the compiler supports modules 286 local use_modules=0 287 if go help modules >/dev/null 2>&1 288 then 289 use_modules=1 290 elif test -n "${GO111MODULE}" 291 then 292 use_modules=1 293 fi 294 295 local volume_mount= 296 if is_set "${use_modules}" 297 then 298 status "Ensuring Go modules are up to date" 299 # ensure our go module cache is correct 300 go_mod_assert || return 1 301 # setup to bind mount our hosts module cache into the container 302 volume_mount="--mount=type=bind,source=${MAIN_GOPATH}/pkg/mod,target=/go/pkg/mod" 303 fi 304 305 status "Creating the Go Build Container with image: ${image_name}" 306 local container_id=$(docker create -it \ 307 ${volume_mount} \ 308 -e CGO_ENABLED=0 \ 309 -e GOLDFLAGS="${GOLDFLAGS}" \ 310 -e GOTAGS="${GOTAGS}" \ 311 ${image_name} \ 312 ./build-support/scripts/build-local.sh -o "${XC_OS}" -a "${XC_ARCH}") 313 ret=$? 314 315 if test $ret -eq 0 316 then 317 status "Copying the source from '${sdir}' to /consul" 318 ( 319 tar -c $(ls | grep -v "^(ui\|ui-v2\|website\|bin\|pkg\|.git)") | docker cp - ${container_id}:/consul && 320 status "Running build in container" && 321 docker start -i ${container_id} && 322 status "Copying back artifacts" && 323 docker cp ${container_id}:/consul/pkg/bin pkg.bin.new 324 ) 325 ret=$? 326 docker rm ${container_id} > /dev/null 327 328 if test $ret -eq 0 329 then 330 build_consul_post "${sdir}" "${extra_dir_name}" 331 ret=$? 332 else 333 rm -r pkg.bin.new 2> /dev/null 334 fi 335 fi 336 popd > /dev/null 337 return $ret 338} 339 340function build_consul_local { 341 # Arguments: 342 # $1 - Path to the top level Consul source 343 # $2 - Space separated string of OSes to build. If empty will use env vars for determination. 344 # $3 - Space separated string of architectures to build. If empty will use env vars for determination. 345 # $4 - Subdirectory to put binaries in under pkg/bin (optional) 346 # 347 # Returns: 348 # 0 - success 349 # * - error 350 # 351 # Note: 352 # The GOLDFLAGS and GOTAGS environment variables will be used if set 353 # If the CONSUL_DEV environment var is truthy only the local platform/architecture is built. 354 # If the XC_OS or the XC_ARCH environment vars are present then only those platforms/architectures 355 # will be built. Otherwise all supported platform/architectures are built 356 # The GOXPARALLEL environment variable is used if set 357 358 if ! test -d "$1" 359 then 360 err "ERROR: '$1' is not a directory. build_consul must be called with the path to the top level source as the first argument'" 361 return 1 362 fi 363 364 local sdir="$1" 365 local build_os="$2" 366 local build_arch="$3" 367 local extra_dir_name="$4" 368 local extra_dir="" 369 370 if test -n "${extra_dir_name}" 371 then 372 extra_dir="${extra_dir_name}/" 373 fi 374 375 pushd ${sdir} > /dev/null 376 if is_set "${CONSUL_DEV}" 377 then 378 if test -z "${XC_OS}" 379 then 380 XC_OS=$(go env GOOS) 381 fi 382 383 if test -z "${XC_ARCH}" 384 then 385 XC_ARCH=$(go env GOARCH) 386 fi 387 fi 388 XC_OS=${XC_OS:-"solaris darwin freebsd linux windows"} 389 XC_ARCH=${XC_ARCH:-"386 amd64 arm arm64"} 390 391 if test -z "${build_os}" 392 then 393 build_os="${XC_OS}" 394 fi 395 396 if test -z "${build_arch}" 397 then 398 build_arch="${XC_ARCH}" 399 fi 400 401 status_stage "==> Building Consul - OSes: ${build_os}, Architectures: ${build_arch}" 402 mkdir pkg.bin.new 2> /dev/null 403 404 status "Building sequentially with go install" 405 for os in ${build_os} 406 do 407 for arch in ${build_arch} 408 do 409 outdir="pkg.bin.new/${extra_dir}${os}_${arch}" 410 osarch="${os}/${arch}" 411 412 case "${os}" in 413 "darwin" ) 414 # Do not build ARM binaries for macOS 415 if test "${arch}" == "arm" -o "${arch}" == "arm64" 416 then 417 continue 418 fi 419 ;; 420 "windows" ) 421 # Do not build ARM binaries for Windows 422 if test "${arch}" == "arm" -o "${arch}" == "arm64" 423 then 424 continue 425 fi 426 ;; 427 "freebsd" ) 428 # Do not build ARM binaries for FreeBSD 429 if test "${arch}" == "arm" -o "${arch}" == "arm64" 430 then 431 continue 432 fi 433 ;; 434 "solaris" ) 435 # Only build amd64 for Solaris 436 if test "${arch}" != "amd64" 437 then 438 continue 439 fi 440 ;; 441 "linux" ) 442 # build all the binaries for Linux 443 ;; 444 *) 445 continue 446 ;; 447 esac 448 449 echo "---> ${osarch}" 450 451 mkdir -p "${outdir}" 452 GOBIN_EXTRA="" 453 if test "${os}" != "$(go env GOHOSTOS)" -o "${arch}" != "$(go env GOHOSTARCH)" 454 then 455 GOBIN_EXTRA="${os}_${arch}/" 456 fi 457 binname="consul" 458 if [ $os == "windows" ];then 459 binname="consul.exe" 460 fi 461 debug_run env CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go install -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}" && cp "${MAIN_GOPATH}/bin/${GOBIN_EXTRA}${binname}" "${outdir}/${binname}" 462 if test $? -ne 0 463 then 464 err "ERROR: Failed to build Consul for ${osarch}" 465 rm -r pkg.bin.new 466 return 1 467 fi 468 done 469 done 470 471 build_consul_post "${sdir}" "${extra_dir_name}" 472 if test $? -ne 0 473 then 474 err "ERROR: Failed postprocessing Consul binaries" 475 return 1 476 fi 477 return 0 478} 479