From fe6882b92d503d5e28cd58d0ce8ede33230a1b99 Mon Sep 17 00:00:00 2001 From: Martin Redolatti Date: Mon, 22 Jan 2024 19:14:14 -0300 Subject: [PATCH] allow building fips-compliant binaries for linux,mac & windows for both sync & proxy --- .gitignore | 4 ++ Makefile | 52 +++++++++++++++++++++--- splitio/commitversion.go | 2 +- windows/Makefile | 68 ++++++++++++++++++++++++++++++++ windows/build_from_mac.sh | 6 +++ windows/entrypoint.sh | 6 +++ windows/macos_builder.Dockerfile | 10 +++++ 7 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 windows/Makefile create mode 100755 windows/build_from_mac.sh create mode 100644 windows/entrypoint.sh create mode 100644 windows/macos_builder.Dockerfile diff --git a/.gitignore b/.gitignore index 4235d749..a70fc78e 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,7 @@ build/* split-proxy split-sync /clilist + +windows/downloads +windows/unpacked +windows/build diff --git a/Makefile b/Makefile index fefba63d..b6f13abd 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,16 @@ # Setup defaults GO ?= go +MAKE ?= make ZIP ?= zip ARCH ?= amd64 PYTHON ?= python3 DOCKER ?= docker BUILD ?= build +BUILD_FIPS ?= $(BUILD)/fips +BUILD_FIPS_WIN_TMP ?= windows/build SHELL = /usr/bin/env bash -o pipefail +ENFORCE_FIPS := -tags enforce_fips +CURRENT_OS = $(shell uname -a | awk '{print $$1}') PLATFORM ?= # Extra arguments @@ -114,11 +119,14 @@ coverage.out: test_coverage # because of windows .exe suffix, we need a macro on the right side, which needs to be executed # after the `%` evaluation, therefore, in a second expansion + .SECONDEXPANSION: -$(BUILD)/split_%.zip: $(BUILD)/split_$$(call make_exec,%) +%.zip: $$(call mkexec,%) $(ZIP) -9 --junk-paths $@ $< -$(BUILD)/install_split_%.bin: $(BUILD)/split_%.zip +# factorized installer creation since it cannot be combined into a single +# target for both std & fips-compliant builds +define make-installer cat $(installer_tpl) \ | sed -e "s/AUTO_REPLACE_APP_NAME/$(call apptitle_from_zip,$<)/" \ | sed -e "s/AUTO_REPLACE_INSTALL_NAME/$(call installed_from_zip,$<)/" \ @@ -133,12 +141,44 @@ $(BUILD)/install_split_%.bin: $(BUILD)/split_%.zip chmod 755 $@ rm $@.tmp rm $< +endef + +$(BUILD)/install_split_%.bin: $(BUILD)/split_%.zip + $(make-installer) -execs := split_sync_linux split_sync_osx split_sync_windows.exe split_proxy_linux split_proxy_osx split_proxy_windows.exe -.INTERMEDIATE: $(addprefix $(BUILD)/,$(execs)) +$(BUILD_FIPS)/install_split_%.bin: $(BUILD_FIPS)/split_%.zip + $(make-installer) + +# Recipes to build main binaries (both std & fips-compliant) +# @{ +posix_execs := split_sync_linux split_sync_osx split_proxy_linux split_proxy_osx_fips +windows_execs := split_sync_windows.exe split_proxy_windows.exe +execs := $(posix_execs) $(windows_execs) +.INTERMEDIATE: $(addprefix $(BUILD)/,$(execs)) + +# regular binaries recipe $(addprefix $(BUILD)/,$(execs)): $(BUILD)/split_%: $(sources) go.sum CGO_ENABLED=0 GOARCH=$(ARCH) GOOS=$(call parse_os,$@) $(GO) build -o $@ cmd/$(call cmdfolder_from_bin,$@)/main.go +# fips-compliant posix binaries recipe +$(addprefix $(BUILD_FIPS)/,$(posix_execs)): $(BUILD_FIPS)/split_%: $(sources) go.sum + mkdir -p $(BUILD_FIPS) + GOEXPERIMENT=boringcrypto CGO_ENABLED=0 GOARCH=$(ARCH) GOOS=$(call parse_os,$@) $(GO) build $(ENFORCE_FIPS) -o $@ cmd/$(call cmdfolder_from_bin,$@)/main.go + +# fips-compliant windows binaries recipe +ifeq ($(CURRENT_OS),Darwin) # we're on macos, we need to build using a dockerized linux +$(addprefix $(BUILD_FIPS)/,$(windows_execs)): $(BUILD_FIPS)/split_%: $(sources) go.sum + mkdir -p $(BUILD_FIPS) + bash -c 'pushd windows && ./build_from_mac.sh' + cp $(BUILD_FIPS_WIN_TMP)/* $(BUILD_FIPS) +else +$(addprefix $(BUILD_FIPS)/,$(windows_execs)): $(BUILD_FIPS)/split_%: $(sources) go.sum + mkdir -p $(BUILD_FIPS) # we're on linux, we can build natively + $(MAKE) -f Makefile -C ./windows setup_ms_go binaries + cp $(BUILD_FIPS_WIN_TMP)/* $(BUILD_FIPS) +endif +# @} + entrypoint.%.sh: clilist cat docker/entrypoint.sh.tpl \ | sed 's/{{ARGS}}/$(shell ./clilist -target=$*)/' \ @@ -201,8 +241,8 @@ help: to_uppercase = $(shell echo '$1' | tr a-z A-Z) remove_ext_path = $(basename $(notdir $1)) normalize_os = $(if $(subst osx,,$1),$1,darwin) -parse_os = $(call normalize_os,$(word 3,$(subst _, ,$(call remove_ext_path,$1)))) -make_exec = $(if $(findstring windows,$1),$1.exe,$1) +parse_os = $(call normalize_os,$(word 3,$(subst _, ,$(call remove_ext_path,$1)))) +mkexec = $(if $(findstring windows,$1),$1.exe,$1) installed_from_zip = $(if $(findstring split_sync,$1),split-sync,split-proxy) apptitle_from_zip = $(if $(findstring split_sync,$1),Synchronizer,Proxy) cmdfolder_from_bin = $(if $(findstring split_sync,$1),synchronizer,proxy) diff --git a/splitio/commitversion.go b/splitio/commitversion.go index 99d3318a..0463666a 100644 --- a/splitio/commitversion.go +++ b/splitio/commitversion.go @@ -5,4 +5,4 @@ This file is created automatically, please do not edit */ // CommitVersion is the version of the last commit previous to release -const CommitVersion = "0f2619f" +const CommitVersion = "779ab29" diff --git a/windows/Makefile b/windows/Makefile new file mode 100644 index 00000000..ba096f1f --- /dev/null +++ b/windows/Makefile @@ -0,0 +1,68 @@ +CURRENT_PATH := $(shell pwd) +PARENT_PATH := $(shell dirname $(CURRENT_PATH)) +DOWNLOAD_FOLDER := $(CURRENT_PATH)/downloads +UNPACK_FOLDER := $(CURRENT_PATH)/unpacked +BIN_FOLDER := $(CURRENT_PATH)/unpacked/go/bin +BUILD_FOLDER := $(CURRENT_PATH)/build + + +GO := $(BIN_FOLDER)/go +ASSET ?= go1.21.linux-amd64.tar.gz +SOURCES := $(shell find $(PARENT_PATH) -path $(dirname $(pwd))/windows -prune -o -name "*.go" -print) \ + $(PARENT_PATH)/go.mod \ + $(PARENT_PATH)/go.sum + +.PHONY: clean setup_ms_go + +default: help + +## remove all downloaded/unpacked/generated files +clean: + rm -Rf downloads unpacked build + +## download and setup a ms-patched version of go which is fips-compliant for windows +setup_ms_go: $(UNPACK_FOLDER)/go + +## build fips-compliant split-proxy && split-sync +binaries: $(BUILD_FOLDER)/split-proxy-fips.exe $(BUILD_FOLDER)/split-sync-fips.exe + + +# -------- + + +$(DOWNLOAD_FOLDER)/go1.21.linux-amd64.tar.gz: + mkdir -p $(DOWNLOAD_FOLDER) + wget https://aka.ms/golang/release/latest/$(ASSET) --directory-prefix $(DOWNLOAD_FOLDER) + wget https://aka.ms/golang/release/latest/$(ASSET).sha256 --directory-prefix $(DOWNLOAD_FOLDER) + # TODO(mredolatti): validate SUM + +$(UNPACK_FOLDER)/go: $(DOWNLOAD_FOLDER)/$(ASSET) + mkdir -p $(UNPACK_FOLDER) + tar xvzf $(DOWNLOAD_FOLDER)/$(ASSET) --directory $(UNPACK_FOLDER) + +$(BUILD_FOLDER)/split-proxy-fips.exe: $(GO) $(SOURCES) + mkdir -p $(BUILD_FOLDER) + GOOS=windows GOEXPERIMENT=cngcrypto $(GO) build -tags=enforce_fips -o $@ $(PARENT_PATH)/cmd/proxy/main.go + +$(BUILD_FOLDER)/split-sync-fips.exe: $(GO) $(SOURCES) + mkdir -p $(BUILD_FOLDER) + GOOS=windows GOEXPERIMENT=cngcrypto $(GO) build -tags=enforce_fips -o $@ $(PARENT_PATH)/cmd/synchronizer/main.go + +# Help target borrowed from: https://docs.cloudposse.com/reference/best-practices/make-best-practices/ +## This help screen +help: + @printf "Available targets:\n\n" + @awk '/^[a-zA-Z\-\_0-9%:\\]+/ { \ + helpMessage = match(lastLine, /^## (.*)/); \ + if (helpMessage) { \ + helpCommand = $$1; \ + helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ + gsub("\\\\", "", helpCommand); \ + gsub(":+$$", "", helpCommand); \ + printf " \x1b[32;01m%-35s\x1b[0m %s\n", helpCommand, helpMessage; \ + } \ + } \ + { lastLine = $$0 }' $(MAKEFILE_LIST) | sort -u + @printf "\n" + + diff --git a/windows/build_from_mac.sh b/windows/build_from_mac.sh new file mode 100755 index 00000000..50c60017 --- /dev/null +++ b/windows/build_from_mac.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e + +docker build -t sync_fips_win_builder -f ./macos_builder.Dockerfile . +docker run --rm -v $(dirname $(pwd)):/buildenv sync_fips_win_builder diff --git a/windows/entrypoint.sh b/windows/entrypoint.sh new file mode 100644 index 00000000..a18c38a5 --- /dev/null +++ b/windows/entrypoint.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e + +cd buildenv/windows +make setup_ms_go binaries diff --git a/windows/macos_builder.Dockerfile b/windows/macos_builder.Dockerfile new file mode 100644 index 00000000..dbfb936a --- /dev/null +++ b/windows/macos_builder.Dockerfile @@ -0,0 +1,10 @@ +FROM debian:bookworm + +RUN apt update -y +RUN apt install -y build-essential ca-certificates +RUN update-ca-certificates + +COPY ./entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"]