diff --git a/.dapper b/.dapper index 71326dddb..345969ade 100755 --- a/.dapper +++ b/.dapper @@ -46,7 +46,7 @@ do set -x ;; --version|-v) - echo Submariner Dapper + echo Shipyard Dapper exit 0 ;; --mount-suffix|-S) @@ -69,13 +69,13 @@ done [ -n "$command" ] && set -- "$command" +buildargs=(--build-arg "ORG=${ORG}" --build-arg "PROJECT=${PROJECT}") +[ -n "${SHIPYARD_REPO}" ] && buildargs+=(--build-arg "SHIPYARD_REPO=${SHIPYARD_REPO}") +[ -n "${SHIPYARD_TAG}" ] && buildargs+=(--build-arg "SHIPYARD_TAG=${SHIPYARD_TAG}") gitid="$(git symbolic-ref --short HEAD 2>/dev/null | tr / _ || :)" gitid="${gitid:-$(git show --format=%h -s)}" container="$(basename "$(pwd)"):${gitid}" -DOCKER_BUILDKIT=1 docker build -t "${container}" -f "${file}" \ - --build-arg "BASE_BRANCH=${BASE_BRANCH:-devel}" \ - --build-arg "PROJECT=${PROJECT}" \ - . +DOCKER_BUILDKIT=1 docker build -t "${container}" -f "${file}" "${buildargs[@]}" . extract_var() { docker inspect "$1" | grep "$2" | sed -E "s/.*\"$2=(.*)\",?/\1/;q" diff --git a/.github/workflows/consuming.yml b/.github/workflows/consuming.yml index ce586618f..116b9e0e2 100644 --- a/.github/workflows/consuming.yml +++ b/.github/workflows/consuming.yml @@ -49,7 +49,7 @@ jobs: run: make -C shipyard images - name: Copy Shipyard resources - run: cp -n shipyard/{Dockerfile.*,Makefile.dapper,.dapper} . + run: cp -n shipyard/{Dockerfile.*,Makefile.dapper,Makefile.shipyard,.dapper} . - name: Make sure ${{ matrix.project }} is using the built Shipyard image run: sed -i 's/shipyard-dapper-base:*.*/shipyard-dapper-base:dev/' Dockerfile.dapper @@ -97,7 +97,7 @@ jobs: path: ${{ matrix.project }} - name: Copy Shipyard resources - run: cp -n Dockerfile.* Makefile.dapper .dapper ${{ matrix.project }}/ + run: cp -n Dockerfile.* Makefile.dapper Makefile.shipyard .dapper ${{ matrix.project }}/ - name: Make sure ${{ matrix.project }} is using the built Shipyard image run: sed -i 's/shipyard-dapper-base:*.*/shipyard-dapper-base:dev/' ${{ matrix.project }}/Dockerfile.dapper @@ -152,7 +152,7 @@ jobs: path: ${{ matrix.project }} - name: Copy Shipyard resources - run: cp -n Dockerfile.* Makefile.dapper .dapper ${{ matrix.project }}/ + run: cp -n Dockerfile.* Makefile.dapper* .dapper ${{ matrix.project }}/ - name: Make sure ${{ matrix.project }} is using the built Shipyard image run: sed -i 's/shipyard-dapper-base:*.*/shipyard-dapper-base:dev/' ${{ matrix.project }}/Dockerfile.dapper diff --git a/Dockerfile.dapper b/Dockerfile.dapper index f162560bc..edafe4511 100644 --- a/Dockerfile.dapper +++ b/Dockerfile.dapper @@ -1,9 +1,11 @@ -ARG BASE_BRANCH -FROM quay.io/submariner/shipyard-dapper-base:${BASE_BRANCH} +ARG SHIPYARD_REPO=quay.io/submariner +ARG SHIPYARD_TAG=devel +FROM ${SHIPYARD_REPO}/shipyard-dapper-base:${SHIPYARD_TAG} +ARG ORG ARG PROJECT ENV DAPPER_ENV="CI QUAY_USERNAME QUAY_PASSWORD MAKEFLAGS PLUGIN TEST_ARGS E2E_TESTDIR GITHUB_USER GITHUB_TOKEN USING" \ - DAPPER_SOURCE=/go/src/github.com/submariner-io/${PROJECT} DAPPER_DOCKER_SOCKET=true + DAPPER_SOURCE=/go/src/github.com/${ORG}/${PROJECT} DAPPER_DOCKER_SOCKET=true ENV OVN_DIR=${DAPPER_SOURCE}/ovn-kubernetes ENV DAPPER_OUTPUT=${DAPPER_SOURCE}/output diff --git a/Dockerfile.linting b/Dockerfile.linting index e4303d04f..5fd94e840 100644 --- a/Dockerfile.linting +++ b/Dockerfile.linting @@ -1,5 +1,6 @@ -ARG BASE_BRANCH -FROM quay.io/submariner/shipyard-linting:${BASE_BRANCH} +ARG SHIPYARD_REPO=quay.io/submariner +ARG SHIPYARD_TAG=devel +FROM ${SHIPYARD_REPO}/shipyard-linting:${SHIPYARD_TAG} ENV DAPPER_ENV="CI GITHUB_SHA MAKEFLAGS" \ DAPPER_SOURCE=/opt/linting diff --git a/Makefile b/Makefile index 2aeeebfbb..a2471c13b 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ include Makefile.versions # Shipyard-specific starts # We need to ensure images, including the Shipyard base image, are updated # before we start Dapper -clean-clusters cleanup cloud-prepare clusters deploy deploy-latest e2e golangci-lint post-mortem print-version scale unit upgrade-e2e: package/.image.shipyard-dapper-base +clean-clusters cleanup cloud-prepare clusters deploy deploy-latest e2e golangci-lint post-mortem packagedoc-lint print-version scale unit upgrade-e2e: package/.image.shipyard-dapper-base deploy deploy-latest e2e upgrade-e2e: package/.image.nettest .DEFAULT_GOAL := lint diff --git a/Makefile.clusters b/Makefile.clusters new file mode 100644 index 000000000..a4220b35f --- /dev/null +++ b/Makefile.clusters @@ -0,0 +1,60 @@ +### VARIABLES ### + +, := , +USING = $(subst $(,), ,$(using)) +_using = ${USING} + +# General make flags/variables +PARALLEL ?= true +TIMEOUT ?= 5m +export PARALLEL SETTINGS TIMEOUT + +# Flags affecting `make clusters` +K8S_VERSION ?= 1.28 +METALLB_VERSION ?= 0.13.5 +OLM_VERSION ?= v0.18.3 +PROVIDER ?= kind +export AIR_GAPPED DUAL_STACK K8S_VERSION LOAD_BALANCER METALLB_VERSION OLM OLM_VERSION OVERLAPPING PROMETHEUS PROVIDER + +### PROCESSING `using=` ### + +ifneq (,$(filter ocp,$(_using))) +PROVIDER = ocp +endif + +ifneq (,$(filter acm,$(_using))) +PROVIDER = acm +endif + +ifneq (,$(filter load-balancer,$(_using))) +LOAD_BALANCER = true +endif + +ifneq (,$(filter air-gap,$(_using))) +AIR_GAPPED = true +endif + +ifneq (,$(filter dual-stack,$(_using))) +DUAL_STACK = true +endif + +ifneq (,$(filter overlapping,$(_using))) +OVERLAPPING = true +endif + +ifneq (,$(filter prometheus,$(_using))) +PROMETHEUS = true +endif + +### TARGETS ### + +# [clean-clusters] removes running clusters +clean-clusters: + $(SCRIPTS_DIR)/cleanup.sh +cleanup: clean-clusters + +# [clusters] creates KIND clusters that can then be used to deploy Submariner +clusters: + $(SCRIPTS_DIR)/$@.sh + +.PHONY: clean-clusters cleanup clusters diff --git a/Makefile.dapper b/Makefile.dapper index a73e854c0..05c1efd8a 100644 --- a/Makefile.dapper +++ b/Makefile.dapper @@ -1,72 +1,17 @@ # This Makefile contains the rules required to set up our # Dapper-based build environment -, := , +ORG ?= submariner-io PROJECT ?= $(notdir $(CURDIR)) -BASE_DAPPER := Dockerfile.dapper -USING = $(subst $(,), ,$(using)) -LINTING_DAPPER := Dockerfile.linting -LINTING_GOALS := gitlint shellcheck yamllint markdownlint -NON_DAPPER_GOALS += .dapper shell targets $(LINTING_GOALS) -export MAKEFLAGS -export PROJECT -export USING +SHIPYARD_TAG ?= $(BASE_BRANCH) +SHIPYARD_URL ?= https://raw.githubusercontent.com/submariner-io/shipyard/$(BASE_BRANCH) +export ORG PROJECT SHIPYARD_TAG SHIPYARD_URL -# Define LOCAL_BUILD to build directly on the host and not inside a Dapper container -ifdef LOCAL_BUILD -DAPPER_HOST_ARCH ?= $(shell go env GOHOSTARCH) -SHIPYARD_DIR ?= ../shipyard -SCRIPTS_DIR ?= $(SHIPYARD_DIR)/scripts/shared - -export DAPPER_HOST_ARCH -export SHIPYARD_DIR -export SCRIPTS_DIR - -RUN_IN_DAPPER := - -.dapper: - -else - -.dapper: - @echo Downloading dapper - @curl -sfLO https://raw.githubusercontent.com/submariner-io/shipyard/$(BASE_BRANCH)/$@ - @chmod +x .dapper - @./.dapper -v - -SELINUX_CONTEXT := $(shell (selinuxenabled && echo -S z) 2>/dev/null) -RUN_IN_DAPPER = ./.dapper $(DAPPER_ARGS) $(SELINUX_CONTEXT) -- - -endif - -ifeq (true,$(DEBUG_PRINT)) -MAKE_DEBUG_FLAG = --debug=b -endif - -USING = $(subst $(,), ,$(using)) -_using = ${USING} - -ifneq (,$(filter dual-stack,$(_using))) -IPV6_FLAGS = --ipv6 --subnet fc00:1234:4444::/64 -endif - -# Only run command line goals in dapper (except things that have to run outside of dapper). -# Otherwise, make applies this rule to various files and tries to build them in dapper (which doesn't work, obviously). -$(filter-out .dapper prune-images shell targets $(NON_DAPPER_GOALS),$(MAKECMDGOALS)): .dapper $(BASE_DAPPER) - @[ -z "$$CI" ] || echo "::group::Launching a container to run 'make $@'" - -docker network create $(IPV6_FLAGS) -d bridge kind - +$(RUN_IN_DAPPER) make $(MAKE_DEBUG_FLAG) $@ - -# The original dockerfiles will live in Shipyard and be downloaded by consuming projects. -$(BASE_DAPPER) $(LINTING_DAPPER): +Makefile.shipyard: @echo Downloading $@ - @curl -sfLO https://raw.githubusercontent.com/submariner-io/shipyard/$(BASE_BRANCH)/$@ + @curl -sfLO $(SHIPYARD_URL)/$@ -# Run silently as the commands are pretty straightforward and `make` hasn't a lot to do -$(LINTING_GOALS): DAPPER_ARGS := -f $(LINTING_DAPPER) -$(LINTING_GOALS): .dapper $(LINTING_DAPPER) - @[ -z "$$CI" ] || echo "::group::Launching a container to run 'make $@'" - @$(RUN_IN_DAPPER) make $@ +include Makefile.shipyard # [prune-images] removes all Submariner-provided images and all untagged images # Use this to ensure you use current images @@ -81,14 +26,4 @@ prune-images: fi \ done -shell: DAPPER_ARGS := -s -shell: .dapper $(BASE_DAPPER) - $(RUN_IN_DAPPER) - -# Run silently to just list the targets (hence we can't use the generic dapper wrapper recipe). -# This only lists targets accessible inside dapper (which are 99% of targets we use) -targets: DAPPER_ARGS := -f $(LINTING_DAPPER) -targets: $(LINTING_DAPPER) - @$(RUN_IN_DAPPER) eval "\$${SCRIPTS_DIR}/targets.sh" - -.PHONY: prune-images shell targets $(LINTING_GOALS) +.PHONY: prune-images diff --git a/Makefile.inc b/Makefile.inc index 9db4f156f..45413c6c7 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -9,13 +9,7 @@ DEBUG_PRINT ?= true PARALLEL ?= true PROVIDER ?= kind TIMEOUT ?= 5m -export AIR_GAPPED DEBUG_PRINT DUAL_STACK GLOBALNET LOAD_BALANCER PARALLEL PLUGIN PRELOAD_IMAGES PROVIDER SETTINGS TEST_ARGS TIMEOUT - -# Specific to `clusters` -K8S_VERSION ?= 1.28 -METALLB_VERSION ?= 0.13.5 -OLM_VERSION ?= v0.18.3 -export K8S_VERSION METALLB_VERSION OLM OLM_VERSION PROMETHEUS +export AIR_GAPPED DEBUG_PRINT OVERLAPPING PARALLEL PLUGIN PRELOAD_IMAGES PROVIDER SETTINGS TEST_ARGS TIMEOUT # Specific to `deploy` CABLE_DRIVER ?= libreswan @@ -32,9 +26,6 @@ export LAZY_DEPLOY SUBCTL_VERIFICATIONS TESTDIR # Specific to `reload-images` export RESTART ?= none -# Specific to `shellcheck` -export SHELLCHECK_ARGS += $(shell [ ! -d scripts ] || find scripts -type f -exec awk 'FNR == 1 && /sh$$/ { print FILENAME }' {} +) - # Specific to `compile.sh` export BUILD_DEBUG BUILD_UPX LDFLAGS @@ -55,12 +46,15 @@ endef check_shipyard_file=$(if $(wildcard $(SHIPYARD_DIR)/$(1)),$(if $(wildcard $(1)),$(call _check_shipyard_file,$(1)),),) $(call check_shipyard_file,Makefile.dapper) +$(call check_shipyard_file,Makefile.shipyard) $(call check_shipyard_file,Dockerfile.dapper) $(call check_shipyard_file,Dockerfile.linting) ##### END GLOBAL FILES STALENESS CHECK ##### +include $(SHIPYARD_DIR)/Makefile.clusters include $(SHIPYARD_DIR)/Makefile.images +include $(SHIPYARD_DIR)/Makefile.linting include $(SHIPYARD_DIR)/Makefile.versions # Process extra flags from the `using=a,b,c` optional flag @@ -80,8 +74,13 @@ ifneq (,$(filter lighthouse,$(_using))) LIGHTHOUSE = true endif +# Support existing Submariner flag ifneq (,$(filter globalnet,$(_using))) -GLOBALNET = true +OVERLAPPING = true +endif + +ifneq (,$(filter overlapping,$(_using))) +OVERLAPPING = true endif ifneq (,$(filter helm,$(_using))) @@ -99,22 +98,16 @@ DEPLOYTOOL = ocm LIGHTHOUSE = true endif -ifneq (,$(filter prometheus,$(_using))) -PROMETHEUS = true -endif - # Force running E2E with `subctl verify` ifneq (,$(filter subctl-verify,$(_using))) TESTDIR = non-existent-dir endif ifneq (,$(filter ocp,$(_using))) -PROVIDER = ocp IMAGE_TAG = subctl endif ifneq (,$(filter acm,$(_using))) -PROVIDER = acm IMAGE_TAG = subctl endif @@ -126,10 +119,6 @@ ifneq (,$(filter air-gap,$(_using))) AIR_GAPPED = true endif -ifneq (,$(filter dual-stack,$(_using))) -DUAL_STACK = true -endif - ifeq ($(LIGHTHOUSE),true) SUBCTL_VERIFICATIONS = service-discovery endif @@ -143,7 +132,7 @@ ifeq ($(AIR_GAPPED),true) override PRELOAD_IMAGES = $(EXTRA_PRELOAD_IMAGES) nettest \ $(foreach image,gateway operator route-agent,submariner-$(image)) -ifeq ($(GLOBALNET),true) +ifeq ($(OVERLAPPING),true) override PRELOAD_IMAGES += submariner-globalnet endif ifeq ($(LIGHTHOUSE),true) @@ -157,7 +146,7 @@ export GO # Shipyard provided targets ##### CLEANING TARGETS ##### -.PHONY: clean clean-clusters clean-generated clean-buildx +.PHONY: clean clean-generated clean-buildx # [clean] cleans everything (running clusters, generated files ...) clean: clean-clusters clean-generated clean-buildx @@ -166,11 +155,6 @@ clean: clean-clusters clean-generated clean-buildx clean-generated: git clean -X -f -d -# [clean-clusters] removes running clusters -clean-clusters: - $(SCRIPTS_DIR)/cleanup.sh -cleanup: clean-clusters - # [clean-buildx] removes the buildx builder, if any clean-buildx: docker buildx version > /dev/null 2>&1 && \ @@ -178,11 +162,7 @@ clean-buildx: docker buildx rm ##### DEPLOYMENT& TESTING TARGETS ##### -.PHONY: clusters cloud-prepare deploy e2e scale upgrade-e2e deploy-latest - -# [clusters] creates KIND clusters that can then be used to deploy Submariner -clusters: - $(SCRIPTS_DIR)/$@.sh +.PHONY: cloud-prepare deploy e2e scale upgrade-e2e deploy-latest # [cloud-prepare] can be run on a POC/testing cloud environment to prepare it before deploying Submariner cloud-prepare: @@ -209,61 +189,6 @@ upgrade-e2e: deploy-latest deploy e2e deploy-latest: $(MAKE) -o images -o preload-images deploy SUBCTL_VERSION=latest IMAGE_TAG=subctl using=$(using) -##### LINTING TARGETS ##### -.PHONY: gitlint golangci-lint markdownlint packagedoc-lint shellcheck yamllint - -# [gitlint] validates the commits are valid -gitlint: - if [ -r .gitlint ]; then \ - gitlint --commits origin/$(BASE_BRANCH)..HEAD; \ - else \ - gitlint --config $(SHIPYARD_DIR)/.gitlint --commits origin/$(BASE_BRANCH)..HEAD; \ - fi - -# [golangci-lint] validates Go code in the project -golangci-lint: -ifneq (,$(shell find . -name '*.go')) - golangci-lint version - golangci-lint linters - golangci-lint run --timeout 10m -else - @echo 'There are no Go files to lint.' -endif - -# [markdownlint] validates Markdown files in the project -markdownlint: - md_ignored=(); \ - if [ -r .mdignore ]; then \ - md_ignored+=($$(< .mdignore)); \ - fi; \ - markdownlint -c .markdownlint.yml $${md_ignored[@]/#/-i } . - -# [packagedoc-lint] checks that the package docs don’t include the SPDX header -packagedoc-lint: - result=0; \ - for package in $$(find . -name vendor -prune -o -name \*.go -printf "%h\n" | sort -u); do \ - if $(GO) doc $$package | grep -q SPDX; then \ - echo $$package has an invalid package documentation; \ - result=1; \ - fi; \ - done 2>/dev/null; \ - exit $$result - -# [shellcheck] validates your shell files -shellcheck: -# Only run shellcheck if there are files to check -ifneq (,$(SHELLCHECK_ARGS)) - shellcheck -x -P $${SCRIPTS_DIR} $(SHELLCHECK_ARGS) - # https://github.com/koalaman/shellcheck/issues/1659 - ! grep $$'\t' $(SHELLCHECK_ARGS) -else - @echo 'There are no shell scripts to check; if this is incorrect, specify them in SHELLCHECK_ARGS.' -endif - -# [yamllint] validates YAML files in the project -yamllint: - yamllint --strict . - ##### MISC TARGETS ##### .PHONY: backport post-mortem unit diff --git a/Makefile.linting b/Makefile.linting new file mode 100644 index 000000000..31930da8f --- /dev/null +++ b/Makefile.linting @@ -0,0 +1,62 @@ +### VARIABLES ### + +SHELLCHECK_ARGS += $(shell [ ! -d scripts ] || find scripts -type f -exec awk 'FNR == 1 && /sh$$/ { print FILENAME }' {} +) +export SHELLCHECK_ARGS + +### TARGETS ### + +.PHONY: gitlint golangci-lint markdownlint packagedoc-lint shellcheck yamllint + +# [gitlint] validates the commits are valid +gitlint: + if [ -r .gitlint ]; then \ + gitlint --commits origin/$(BASE_BRANCH)..HEAD; \ + else \ + gitlint --config $(SHIPYARD_DIR)/.gitlint --commits origin/$(BASE_BRANCH)..HEAD; \ + fi + +# [golangci-lint] validates Go code in the project +golangci-lint: +ifneq (,$(shell find . -name '*.go')) + golangci-lint version + golangci-lint linters + golangci-lint run --timeout 10m +else + @echo 'There are no Go files to lint.' +endif + +# [markdownlint] validates Markdown files in the project +markdownlint: + md_ignored=(); \ + if [ -r .mdignore ]; then \ + md_ignored+=($$(< .mdignore)); \ + fi; \ + markdownlint -c .markdownlint.yml $${md_ignored[@]/#/-i } . + +# [packagedoc-lint] checks that the package docs don’t include the SPDX header +packagedoc-lint: + result=0; \ + for package in $$(find . -name vendor -prune -o -name \*.go -printf "%h\n" | sort -u); do \ + if $(GO) doc $$package | grep -q SPDX; then \ + echo $$package has an invalid package documentation; \ + result=1; \ + fi; \ + done 2>/dev/null; \ + exit $$result + +# [shellcheck] validates your shell files +shellcheck: +# Only run shellcheck if there are files to check +ifneq (,$(SHELLCHECK_ARGS)) + shellcheck -x -P $${SCRIPTS_DIR} $(SHELLCHECK_ARGS) + # https://github.com/koalaman/shellcheck/issues/1659 + ! grep $$'\t' $(SHELLCHECK_ARGS) +else + @echo 'There are no shell scripts to check; if this is incorrect, specify them in SHELLCHECK_ARGS.' +endif + +# [yamllint] validates YAML files in the project +yamllint: + yamllint --strict . + + diff --git a/Makefile.shipyard b/Makefile.shipyard new file mode 100644 index 000000000..59133ee73 --- /dev/null +++ b/Makefile.shipyard @@ -0,0 +1,82 @@ +# This Makefile contains the basic goals to set up a Shipyard based environment, which runs inside a container + +, := , +BASE_DAPPER := Dockerfile.dapper +USING = $(subst $(,), ,$(using)) +LINTING_DAPPER := Dockerfile.linting +LINTING_GOALS := gitlint shellcheck yamllint markdownlint +NON_DAPPER_GOALS += .dapper shell targets $(LINTING_GOALS) +SHIPYARD_GOALS += cleanup clean-clusters clusters golangci-lint packagedoc-lint +export MAKEFLAGS +export USING + +# Define LOCAL_BUILD to build directly on the host and not inside a Dapper container +ifdef LOCAL_BUILD +DAPPER_HOST_ARCH ?= $(shell go env GOHOSTARCH) +SHIPYARD_DIR ?= ../shipyard +SCRIPTS_DIR ?= $(SHIPYARD_DIR)/scripts/shared + +export DAPPER_HOST_ARCH +export SHIPYARD_DIR +export SCRIPTS_DIR + +RUN_IN_DAPPER := + +.dapper: + +else + +.dapper: + @echo Downloading dapper + @curl -sfLO $(SHIPYARD_URL)/$@ + @chmod +x .dapper + @./.dapper -v + +SELINUX_CONTEXT := $(shell (selinuxenabled && echo -S z) 2>/dev/null) +RUN_IN_DAPPER = ./.dapper $(DAPPER_ARGS) $(SELINUX_CONTEXT) -- + +endif + +ifeq (true,$(DEBUG_PRINT)) +MAKE_DEBUG_FLAG = --debug=b +endif + +USING = $(subst $(,), ,$(using)) +_using = ${USING} + +ifneq (,$(filter dual-stack,$(_using))) +IPV6_FLAGS = --ipv6 --subnet fc00:1234:4444::/64 +endif + +# Run only Shipyard goals inside the container when requested, otherwise run any suitable goal inside the container. +ifdef ONLY_SHIPYARD_GOALS +$(SHIPYARD_GOALS): .dapper $(BASE_DAPPER) +else +$(filter-out .dapper prune-images shell targets $(NON_DAPPER_GOALS),$(MAKECMDGOALS)): .dapper $(BASE_DAPPER) +endif + @[ -z "$$CI" ] || echo "::group::Launching a container to run 'make $@'" + -docker network create $(IPV6_FLAGS) -d bridge kind + +$(RUN_IN_DAPPER) make $(MAKE_DEBUG_FLAG) $@ + +# The original dockerfiles will live in Shipyard and be downloaded by consuming projects. +$(BASE_DAPPER) $(LINTING_DAPPER): + @echo Downloading $@ + @curl -sfLO $(SHIPYARD_URL)/$@ + +# Run silently as the commands are pretty straightforward and `make` hasn't a lot to do +$(LINTING_GOALS): DAPPER_ARGS := -f $(LINTING_DAPPER) +$(LINTING_GOALS): .dapper $(LINTING_DAPPER) + @[ -z "$$CI" ] || echo "::group::Launching a container to run 'make $@'" + @$(RUN_IN_DAPPER) make $@ + +shell: DAPPER_ARGS := -s +shell: .dapper $(BASE_DAPPER) + $(RUN_IN_DAPPER) + +# Run silently to just list the targets (hence we can't use the generic dapper wrapper recipe). +# This only lists targets accessible inside dapper (which are 99% of targets we use) +targets: DAPPER_ARGS := -f $(LINTING_DAPPER) +targets: $(LINTING_DAPPER) + @$(RUN_IN_DAPPER) eval "\$${SCRIPTS_DIR}/targets.sh" + +.PHONY: shell targets $(LINTING_GOALS) diff --git a/README.md b/README.md index 90a0e8995..b06575c3c 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ The simplest Makefile would look like this: ```Makefile BASE_BRANCH=devel PROJECT=shipyard -export BASE_BRANCH -export PROJECT +SHIPYARD_URL=https://raw.githubusercontent.com/submariner-io/shipyard/$(BASE_BRANCH) +export BASE_BRANCH PROJECT SHIPYARD_URL ifneq (,$(DAPPER_HOST_ARCH)) @@ -67,7 +67,7 @@ else Makefile.dapper: @echo Downloading $@ - @curl -sfLO https://raw.githubusercontent.com/submariner-io/shipyard/$(BASE_BRANCH)/$@ + @curl -sfLO $(SHIPYARD_URL)/$@ include Makefile.dapper diff --git a/package/Dockerfile.shipyard-dapper-base b/package/Dockerfile.shipyard-dapper-base index ea1cf54a9..eeb178b39 100644 --- a/package/Dockerfile.shipyard-dapper-base +++ b/package/Dockerfile.shipyard-dapper-base @@ -90,7 +90,7 @@ COPY Makefile.* .gitlint ${SHIPYARD_DIR}/ # Copy the global dapper file so that we can make sure consuming projects are up to date COPY Dockerfile.dapper ${SHIPYARD_DIR}/ -# Copy CI deployment scripts into image to share with all submariner-io/* projects +# Copy CI deployment scripts into image to share with all projects WORKDIR $SCRIPTS_DIR COPY scripts/shared/ . diff --git a/package/Dockerfile.shipyard-linting b/package/Dockerfile.shipyard-linting index 572687210..6fb457e4b 100644 --- a/package/Dockerfile.shipyard-linting +++ b/package/Dockerfile.shipyard-linting @@ -40,6 +40,6 @@ COPY Makefile.* .gitlint ${SHIPYARD_DIR}/ # Copy the global dapper file so that we can make sure consuming projects are up to date COPY Dockerfile.linting ${SHIPYARD_DIR}/ -# Copy shared scripts into image to share with all submariner-io/* projects +# Copy shared scripts into image to share with all projects WORKDIR $SCRIPTS_DIR COPY scripts/shared/ . diff --git a/scripts/shared/clusters.sh b/scripts/shared/clusters.sh index d1ea8cd9f..cca69b81c 100755 --- a/scripts/shared/clusters.sh +++ b/scripts/shared/clusters.sh @@ -3,7 +3,7 @@ set -em -o pipefail source "${SCRIPTS_DIR}/lib/utils" -print_env AIR_GAPPED GLOBALNET K8S_VERSION OLM OLM_VERSION PARALLEL PROMETHEUS PROVIDER SETTINGS TIMEOUT +print_env AIR_GAPPED K8S_VERSION OLM OLM_VERSION OVERLAPPING PARALLEL PROMETHEUS PROVIDER SETTINGS TIMEOUT source "${SCRIPTS_DIR}/lib/debug_functions" ### Functions ### diff --git a/scripts/shared/deploy.sh b/scripts/shared/deploy.sh index c37f84e4a..294855cd1 100755 --- a/scripts/shared/deploy.sh +++ b/scripts/shared/deploy.sh @@ -3,7 +3,7 @@ set -em source "${SCRIPTS_DIR}/lib/utils" -print_env CABLE_DRIVER DEPLOYTOOL GLOBALNET IMAGE_TAG LIGHTHOUSE PARALLEL PLUGIN PRELOAD_IMAGES SETTINGS TIMEOUT +print_env CABLE_DRIVER DEPLOYTOOL OVERLAPPING IMAGE_TAG LIGHTHOUSE PARALLEL PLUGIN PRELOAD_IMAGES SETTINGS TIMEOUT source "${SCRIPTS_DIR}/lib/debug_functions" source "${SCRIPTS_DIR}/lib/deploy_funcs" @@ -99,10 +99,39 @@ function install_bundle() { echo "[INFO](${cluster}) Bundle ${bundle} installed" } +function declare_global_cidrs() { + declare -gA global_CIDRs + + for cluster in "${clusters[@]}"; do + # shellcheck disable=SC2034 + global_CIDRs[$cluster]="242.254.${cluster_number[$cluster]}.0/24" + done +} + +# This is a workaround and can be removed once we switch the CNI from kindnet to a different one. +# In order to support health-check and hostNetwork use-cases, submariner requires an IPaddress from the podCIDR +# for each node in the cluster. Normally, most of the CNIs create a cniInterface on the host and assign an IP +# from the podCIDR to the interface. Submariner relies on this interface to support the aforementioned use-cases. +# However, with kindnet CNI, it was seen that it does not create a dedicated CNI Interface on the nodes. +# But as soon as a pod is scheduled on a node, it creates a veth-xxx interface which has an IPaddress from the +# podCIDR. In this workaround, we are scheduling a dummy pod as a demonSet on the cluster to trigger the creation +# of this veth-xxx interface which can be used as a cniInterface and we can continue to validate Submariner use-cases. +function schedule_dummy_pod() { + [[ -z "${cluster_cni[$cluster]}" ]] || return 0 + local ns="subm-kindnet-workaround" + source "${SCRIPTS_DIR}"/lib/deploy_funcs + import_image "${REPO}/nettest" + + echo "Creating the ${ns} namespace..." + kubectl create namespace "${ns}" || : + deploy_resource "${RESOURCES_DIR}"/dummypod.yaml "$ns" +} + ### Main ### load_settings declare_cidrs +[[ "$OVERLAPPING" != "true" ]] || declare_global_cidrs declare_kubeconfig # Always import nettest image on kind, to be able to test connectivity and other things @@ -113,6 +142,7 @@ declare_kubeconfig load_library deploy DEPLOYTOOL deploytool_prereqs +[[ "$PROVIDER" != kind ]] || run_all_clusters schedule_dummy_pod run_if_defined pre_deploy diff --git a/scripts/shared/lib/clusters_kind b/scripts/shared/lib/clusters_kind index bcf44af80..b21e06e3e 100755 --- a/scripts/shared/lib/clusters_kind +++ b/scripts/shared/lib/clusters_kind @@ -35,12 +35,20 @@ function generate_cluster_yaml() { local nodes for node in ${cluster_nodes[${cluster}]}; do nodes="${nodes}"$'\n'"- role: $node"; done + local config_file + config_file="${RESOURCES_DIR}/${cluster}-config.yaml" + if [[ "$DUAL_STACK" ]]; then service_cidr_ipv6="${service_IPv6_CIDRs[${cluster}]}" pod_cidr_ipv6="${cluster_IPv6_CIDRs[${cluster}]}" - render_template "${RESOURCES_DIR}/kind-cluster-dual-stack-config.yaml" > "${RESOURCES_DIR}/${cluster}-config.yaml" + render_template "${RESOURCES_DIR}/kind-cluster-dual-stack-config.yaml" > "$config_file" else - render_template "${RESOURCES_DIR}/kind-cluster-config.yaml" > "${RESOURCES_DIR}/${cluster}-config.yaml" + render_template "${RESOURCES_DIR}/kind-cluster-config.yaml" > "$config_file" + fi + + if [[ -n "${cluster_custom_config[$cluster]}" ]]; then + # shellcheck disable=SC2016 # We intentionally don't expand the argument to eval-all as it's using yq syntax, not sh + echo "${cluster_custom_config[$cluster]}" | yq -i eval-all '. as $item ireduce ({}; . * $item )' "$config_file" - fi } @@ -116,29 +124,10 @@ function provider_create_cluster() { kind create cluster ${image_flag:+"$image_flag"} --name="${cluster}" --config="${RESOURCES_DIR}/${cluster}-config.yaml" kind_fixup_config - [[ -n "${cluster_cni[$cluster]}" ]] || delete_cluster_on_fail schedule_dummy_pod [[ "$LOAD_BALANCER" != true ]] || delete_cluster_on_fail deploy_load_balancer [[ "$AIR_GAPPED" != true ]] || air_gap_iptables } -# This is a workaround and can be removed once we switch the CNI from kindnet to a different one. -# In order to support health-check and hostNetwork use-cases, submariner requires an IPaddress from the podCIDR -# for each node in the cluster. Normally, most of the CNIs create a cniInterface on the host and assign an IP -# from the podCIDR to the interface. Submariner relies on this interface to support the aforementioned use-cases. -# However, with kindnet CNI, it was seen that it does not create a dedicated CNI Interface on the nodes. -# But as soon as a pod is scheduled on a node, it creates a veth-xxx interface which has an IPaddress from the -# podCIDR. In this workaround, we are scheduling a dummy pod as a demonSet on the cluster to trigger the creation -# of this veth-xxx interface which can be used as a cniInterface and we can continue to validate Submariner use-cases. -function schedule_dummy_pod() { - local ns="subm-kindnet-workaround" - source "${SCRIPTS_DIR}"/lib/deploy_funcs - import_image "${REPO}/nettest" - - echo "Creating the ${ns} namespace..." - kubectl create namespace "${ns}" || : - deploy_resource "${RESOURCES_DIR}"/dummypod.yaml "$ns" -} - function delete_cluster_on_fail() { ( "$@"; ) & if ! wait $! ; then @@ -166,9 +155,7 @@ function air_gap_iptables() { function deploy_load_balancer() { local kind_ip start_ip end_ip net_addr kind_ip=$(docker network inspect -f '{{.IPAM.Config}}' kind | awk '/.*/ { print $2 }') - net_addr=$(echo "${cluster_CIDRs[$cluster]}" | cut -f2 -d'.') - [[ "$GLOBALNET" != true ]] || net_addr=$(echo "${global_CIDRs[$cluster]}" | cut -f3 -d'.') - start_ip=$(echo "$kind_ip" | cut -f1-2 -d'.')."$net_addr".100 + start_ip=$(echo "$kind_ip" | cut -f1-2 -d'.')."${cluster_number[$cluster]}".100 end_ip=$(echo "$start_ip" | cut -f1-3 -d'.').250 kubectl apply -f "https://raw.githubusercontent.com/metallb/metallb/v${METALLB_VERSION}/config/manifests/metallb-native.yaml" diff --git a/scripts/shared/lib/deploy_bundle b/scripts/shared/lib/deploy_bundle index 5e3d7f682..cef311c59 100644 --- a/scripts/shared/lib/deploy_bundle +++ b/scripts/shared/lib/deploy_bundle @@ -53,7 +53,7 @@ function setup_broker() { # Enable the service-discovery component if defined local components="connectivity" components+=$([[ "${LIGHTHOUSE}" == "true" ]] && echo ", service-discovery" || echo "") - components+=$([[ "${GLOBALNET}" == "true" ]] && echo ", globalnet" || echo "") + components+=$([[ "${OVERLAPPING}" == "true" ]] && echo ", globalnet" || echo "") ### Create the Broker instance render_template "${RESOURCES_DIR}"/bundle/broker.yaml | kubectl apply -f - diff --git a/scripts/shared/lib/deploy_funcs b/scripts/shared/lib/deploy_funcs index 56472c128..56ca9218a 100644 --- a/scripts/shared/lib/deploy_funcs +++ b/scripts/shared/lib/deploy_funcs @@ -44,7 +44,7 @@ function get_svc_ip() { local svc_name=$1 local svc_ip - if [[ "${GLOBALNET}" = "true" ]]; then + if [[ "${OVERLAPPING}" = "true" ]]; then svc_ip=$(with_retries 30 get_globalip "${svc_name}") else svc_ip=$(kubectl --context="$cluster" get svc -l "app=${svc_name}" | awk 'FNR == 2 {print $3}') diff --git a/scripts/shared/lib/deploy_helm b/scripts/shared/lib/deploy_helm index a801da255..4066237af 100644 --- a/scripts/shared/lib/deploy_helm +++ b/scripts/shared/lib/deploy_helm @@ -70,14 +70,14 @@ function helm_install_subm() { --set broker.token="${submariner_broker_token}" \ --set broker.namespace="${BROKER_NAMESPACE}" \ --set broker.ca="${submariner_broker_ca}" \ - --set broker.globalnet="${GLOBALNET}" \ + --set broker.globalnet="${OVERLAPPING}" \ --set submariner.serviceDiscovery="${LIGHTHOUSE}" \ --set submariner.cableDriver="${CABLE_DRIVER}" \ --set submariner.clusterId="${cluster}" \ --set submariner.clusterCidr="${cluster_CIDRs[$cluster]}" \ --set submariner.serviceCidr="${service_CIDRs[$cluster]}" \ --set submariner.globalCidr="${global_CIDRs[$cluster]}" \ - --set serviceAccounts.globalnet.create="${GLOBALNET}" \ + --set serviceAccounts.globalnet.create="${OVERLAPPING}" \ --set serviceAccounts.lighthouseAgent.create="${LIGHTHOUSE}" \ --set serviceAccounts.lighthouseCoreDns.create="${LIGHTHOUSE}" \ --set submariner.natEnabled="false" \ diff --git a/scripts/shared/lib/deploy_operator b/scripts/shared/lib/deploy_operator index a56e6873f..58845df1e 100644 --- a/scripts/shared/lib/deploy_operator +++ b/scripts/shared/lib/deploy_operator @@ -28,7 +28,7 @@ function deploytool_prereqs() { function setup_broker() { local extra_flags=() - [[ "${GLOBALNET}" = true ]] && extra_flags+=(--globalnet) + [[ "${OVERLAPPING}" = true ]] && extra_flags+=(--globalnet) if [[ "${LIGHTHOUSE}" == true ]]; then extra_flags+=(--components 'service-discovery,connectivity') else diff --git a/scripts/shared/lib/utils b/scripts/shared/lib/utils index fb2aa951c..8e067cb67 100644 --- a/scripts/shared/lib/utils +++ b/scripts/shared/lib/utils @@ -164,14 +164,11 @@ function registry_running() { return $? } -function add_cluster_cidrs() { +function set_cluster_cidrs() { local val=$1 local idx=$2 - if [[ "${GLOBALNET}" == "true" ]]; then - val="0" - global_CIDRs[$idx]="242.254.${1}.0/24" - fi + [[ "$OVERLAPPING" != "true" ]] || val="0" cluster_CIDRs[$idx]="10.$((val+129)).0.0/16" service_CIDRs[$idx]="100.$((val+65)).0.0/16" @@ -183,11 +180,12 @@ function add_cluster_cidrs() { function declare_cidrs() { local DEBUG_PRINT=false # shellcheck disable=SC2034 # these variables are used elsewhere - declare -gA cluster_CIDRs cluster_IPv6_CIDRs service_CIDRs service_IPv6_CIDRs global_CIDRs + declare -gA cluster_number cluster_CIDRs cluster_IPv6_CIDRs service_CIDRs service_IPv6_CIDRs local cluster i=1 for cluster in "${clusters[@]}"; do - add_cluster_cidrs "$i" "$cluster" + cluster_number[$cluster]="$i" + set_cluster_cidrs "$i" "$cluster" i=$(("$i"+1)) done } @@ -222,7 +220,7 @@ function load_settings() { local DEBUG_PRINT=false expect_env SETTINGS "Deployment settings file" declare -ga clusters - declare -gA cluster_cni cluster_nodes cluster_subm cluster_gateways + declare -gA cluster_cni cluster_nodes cluster_subm cluster_gateways cluster_custom_config local cluster_count cluster_count=$(_yq ".cluster-count") @@ -244,6 +242,7 @@ function load_settings() { cluster_subm["${cluster}"]=$(_yq ".clusters.${cluster}.submariner") cluster_subm["${cluster}"]=$(_yq ".submariner") cluster_gateways["${cluster}"]=$(_yq ".clusters.${cluster}.gateways // .gateways") + cluster_custom_config["${cluster}"]=$(_yq ".clusters.${cluster}.customConfig // .customConfig") done cat << EOM @@ -254,6 +253,7 @@ Cluster settings:: nodes per cluster - $(typeset -p cluster_nodes | cut -f 2- -d=) install submariner - $(typeset -p cluster_subm | cut -f 2- -d=) label cluster gateways - $(typeset -p cluster_gateways | cut -f 2- -d=) + custom configuration - $(typeset -p cluster_custom_config | cut -f 2- -d=) EOM } diff --git a/scripts/shared/resources/bundle/broker.yaml b/scripts/shared/resources/bundle/broker.yaml index ff3ebcaaf..532263c44 100644 --- a/scripts/shared/resources/bundle/broker.yaml +++ b/scripts/shared/resources/bundle/broker.yaml @@ -7,5 +7,5 @@ metadata: spec: components: ["${components}"] defaultGlobalnetClusterSize: 8192 - globalnetEnabled: ${GLOBALNET} + globalnetEnabled: ${OVERLAPPING} globalnetCIDRRange: 169.254.0.0/16