diff --git a/.gitignore b/.gitignore index 407bccc2143..2d59c24af00 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,9 @@ pkg/cloud/dashboard/Cargo.lock docs/site/node_modules docs/site/package-lock.json +.vscode + +# tools is responsible for collecting sealer third party package binary tools +tools +#coverage.out +tmp diff --git a/Make b/Make deleted file mode 100644 index 7ee04ba118b..00000000000 --- a/Make +++ /dev/null @@ -1,192 +0,0 @@ -# Copyright © 2022 Alibaba Group Holding Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Help by default, even if it's not first -.DEFAULT_GOAL := help - -.PHONY: all -all: tidy gen add-copyright format lint cover build - -# ============================================================================== -# Build options - -ROOT_PACKAGE=github.com/sealerio/sealer -VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version - -# ============================================================================== -# Includes - -include scripts/make-rules/common.mk # make sure include common.mk at the first include line -include scripts/make-rules/golang.mk -include scripts/make-rules/image.mk -include scripts/make-rules/deploy.mk -include scripts/make-rules/copyright.mk -include scripts/make-rules/gen.mk -include scripts/make-rules/ca.mk -include scripts/make-rules/release.mk -include scripts/make-rules/swagger.mk -include scripts/make-rules/dependencies.mk -include scripts/make-rules/tools.mk - -# ============================================================================== -# Usage - -define USAGE_OPTIONS - -Options: - DEBUG Whether to generate debug symbols. Default is 0. - BINS The binaries to build. Default is all of cmd. - This option is available when using: make build/build.multiarch - Example: make build BINS="iam-apiserver iam-authz-server" - IMAGES Backend images to make. Default is all of cmd starting with iam-. - This option is available when using: make image/image.multiarch/push/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-authz-server" - REGISTRY_PREFIX Docker registry prefix. Default is marmotedu. - Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.6.2 - PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64. - This option is available when using: make build.multiarch/image.multiarch/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-pump" PLATFORMS="linux_amd64 linux_arm64" - VERSION The version information compiled into binaries. - The default is obtained from gsemver or git. - V Set to 1 enable verbose build. Default is 0. -endef -export USAGE_OPTIONS - -# ============================================================================== -# Targets - -Dirs=$(shell ls) - -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifneq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif - - -fmt: ## Run go fmt against code. - go fmt ./... - -## vet: Run go vet against code. -vet: - go vet ./... - -## lint: Run go lint against code. -lint: - golangci-lint run -v ./... - -## style: code style: fmt,vet,lint -style: fmt vet lint - -## build: Build binaries by default -build: clean - @echo "build sealer and seautil bin" - scripts/build.sh - -## linux: Build binaries for linux -linux: clean - @echo "build sealer and seautil bin for linux" - GOOS=linux GOARCH=amd64 hack/build.sh $(GitTag) - -## linux-arm64: build binaries for linux -linux-arm64: clean - @echo "build sealer and seautil bin for linux" - GOOS=linux GOARCH=arm64 hack/build.sh $(GitTag) - -# sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. -build-in-docker: - docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux - -test-sealer: - @echo "run e2e test for sealer bin" - hack/test-sealer.sh - -clean: ## clean - @rm -rf _output - -install-addlicense: ## check license if not exist install addlicense tools -ifeq (, $(shell which addlicense)) - @{ \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v github.com/google/addlicense ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -ADDLICENSE_BIN=$(GOBIN)/addlicense -else -ADDLICENSE_BIN=$(shell which addlicense) -endif - -filelicense: SHELL:=/bin/bash -filelicense: ## add license - for file in ${Dirs} ; do \ - if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ - $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f hack/LICENSE_TEMPLATE ./$$file ; \ - fi \ - done - - -install-gosec: ## check license if not exist install addlicense tools -ifeq (, $(shell which gosec)) - @{ \ - set -e ;\ - curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ - } -GOSEC_BIN=$(GOBIN)/gosec -else -GOSEC_BIN=$(shell which gosec) -endif - -gosec: install-gosec - $(GOSEC_BIN) ./... - - -install-deepcopy-gen: -ifeq (, $(shell which deepcopy-gen)) - @{ \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v k8s.io/code-generator/cmd/deepcopy-gen ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -DEEPCOPY_BIN=$(GOBIN)/deepcopy-gen -else -DEEPCOPY_BIN=$(shell which deepcopy-gen) -endif - -HEAD_FILE := scripts/boilerplate.go.txt -INPUT_DIR := github.com/sealerio/sealer/types/api -deepcopy:install-deepcopy-gen - $(DEEPCOPY_BIN) \ - --input-dirs="$(INPUT_DIR)/v1" \ - -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ - --output-base "${GOPATH}/src" - $(DEEPCOPY_BIN) \ - --input-dirs="$(INPUT_DIR)/v2" \ - -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ - --output-base "${GOPATH}/src" - -## help: Show this help info. -.PHONY: help -help: Makefile - @printf "\nUsage: make ...\n\nTargets:\n" - @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' - @echo "$$USAGE_OPTIONS" \ No newline at end of file diff --git a/Makefile b/Makefile index 509dc5e5be2..1e260029b8a 100644 --- a/Makefile +++ b/Makefile @@ -12,19 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Help by default, even if it's not first +# ============================================================================== +# define the default goal +# + .DEFAULT_GOAL := help .PHONY: all all: tidy gen add-copyright format lint cover build # ============================================================================== -# Build options +# Build set ROOT_PACKAGE=github.com/sealerio/sealer VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version Dirs=$(shell ls) +GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) +GOOS ?= $(shell go env GOOS) +GOARCH ?= $(shell go env GOARCH) + +BUILD_SCRIPTS := scripts/build.sh # ============================================================================== # Includes @@ -34,9 +42,6 @@ include scripts/make-rules/golang.mk include scripts/make-rules/image.mk include scripts/make-rules/copyright.mk include scripts/make-rules/gen.mk -include scripts/make-rules/ca.mk -include scripts/make-rules/release.mk -include scripts/make-rules/swagger.mk include scripts/make-rules/dependencies.mk include scripts/make-rules/tools.mk @@ -46,25 +51,16 @@ include scripts/make-rules/tools.mk define USAGE_OPTIONS Options: - DEBUG Whether to generate debug symbols. Default is 0. - - BINS The binaries to build. Default is all of cmd. - This option is available when using: make build/build.multiarch - Example: make build BINS="iam-apiserver iam-authz-server" - - IMAGES Backend images to make. Default is all of cmd starting with iam-. - This option is available when using: make image/image.multiarch/push/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-authz-server" - REGISTRY_PREFIX Docker registry prefix. Default is marmotedu. - Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.6.2 + DEBUG Whether or not to generate debug symbols. Default is 0. - PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64. - This option is available when using: make build.multiarch/image.multiarch/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-pump" PLATFORMS="linux_amd64 linux_arm64" + BINS Binaries to build. Default is all binaries under cmd. + This option is available when using: make {build}(.multiarch) + Example: make build BINS="sealer sealctl" - VERSION The version information compiled into binaries. - The default is obtained from gsemver or git. + PLATFORMS Platform to build for. Default is linux_arm64 and linux_amd64. + This option is available when using: make {build}.multiarch + Example: make build.multiarch PLATFORMS="linux_arm64 linux_amd64" V Set to 1 enable verbose build. Default is 0. endef @@ -72,18 +68,11 @@ export USAGE_OPTIONS # ============================================================================== # Targets -GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) -GOOS ?= $(shell go env GOOS) -GOARCH ?= $(shell go env GOARCH) - -TOOLS_DIR := hack/build.sh -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifneq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif +## build: Build binaries by default +.PHONY: build +build: clean + @$(MAKE) go.build ## fmt: Run go fmt against code. .PHONY: fmt @@ -104,76 +93,47 @@ lint: .PHONY: style style: fmt vet lint -## build: Build binaries by default -build: clean - @echo "===========> build sealer and seautil bin" - @scripts/build.sh - ## linux-amd64: Build binaries for Linux (amd64) linux-amd64: clean @echo "Building sealer and seautil binaries for Linux (amd64)" - GOOS=linux GOARCH=amd64 $(TOOLS_DIR) $(GIT_TAG) + @GOOS=linux GOARCH=amd64 $(BUILD_SCRIPTS) $(GIT_TAG) ## linux-arm64: Build binaries for Linux (arm64) linux-arm64: clean @echo "Building sealer and seautil binaries for Linux (arm64)" - GOOS=linux GOARCH=arm64 $(TOOLS_DIR) $(GIT_TAG) + @GOOS=linux GOARCH=arm64 $(BUILD_SCRIPTS) $(GIT_TAG) ## build-in-docker: sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. build-in-docker: - docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux + @docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux -## clean: Remove all files that are created by building. -.PHONY: clean -clean: - @echo "===========> Cleaning all build output" - @-rm -rf _output +## gen: Generate all necessary files. +.PHONY: gen +gen: + @$(MAKE) gen.run -## install-addlicense: check license if not exist install addlicense tools -install-addlicense: -ifeq (, $(shell which addlicense)) - @{ \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v github.com/google/addlicense ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -ADDLICENSE_BIN=$(GOBIN)/addlicense -else -ADDLICENSE_BIN=$(shell which addlicense) -endif +## verify-copyright: Verify the license headers for all files. +.PHONY: verify-copyright +verify-license: + @$(MAKE) copyright.verify -filelicense: SHELL:=/bin/bash -## filelicense: add license -filelicense: - for file in ${Dirs} ; do \ - if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ - $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f scripts/LICENSE_TEMPLATE ./$$file ; \ - fi \ - done - - -## install-gosec: check license if not exist install addlicense tools -install-gosec: -ifeq (, $(shell which gosec)) - @{ \ - set -e ;\ - curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ - } -GOSEC_BIN=$(GOBIN)/gosec -else -GOSEC_BIN=$(shell which gosec) -endif +## add-copyright: Add copyright ensure source code files have license headers. +.PHONY: add-copyright +add-license: + @$(MAKE) copyright.add gosec: install-gosec $(GOSEC_BIN) ./... +## tools: Install dependent tools. +.PHONY: tools +tools: + @$(MAKE) tools.install +## install-deepcopy-gen: check license if not exist install deepcopy-gen tools. install-deepcopy-gen: ifeq (, $(shell which deepcopy-gen)) - @{ \ + { \ set -e ;\ LICENSE_TMP_DIR=$$(mktemp -d) ;\ cd $$LICENSE_TMP_DIR ;\ @@ -186,23 +146,33 @@ else DEEPCOPY_BIN=$(shell which deepcopy-gen) endif -HEAD_FILE := scripts/boilerplate.go.txt -INPUT_DIR := github.com/sealerio/sealer/types/api -deepcopy:install-deepcopy-gen +# BOILERPLATE := scripts/boilerplate.go.txt +# INPUT_DIR := github.com/sealerio/sealer/types/api + +## deepcopy: generate deepcopy code. +deepcopy: install-deepcopy-gen $(DEEPCOPY_BIN) \ --input-dirs="$(INPUT_DIR)/v1" \ -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ + --go-header-file "$(BOILERPLATE)" \ --output-base "${GOPATH}/src" $(DEEPCOPY_BIN) \ --input-dirs="$(INPUT_DIR)/v2" \ -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ + --go-header-file "$(BOILERPLATE)" \ --output-base "${GOPATH}/src" +## clean: Remove all files that are created by building. +.PHONY: clean +clean: + @$(MAKE) go.clean + ## help: Show this help info. .PHONY: help help: Makefile - @printf "\nUsage: make ...\n\nTargets:\n" - @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' - @echo "$$USAGE_OPTIONS" \ No newline at end of file + $(call makehelp) + +## all-help: Show all help details info. +.PHONY: all-help +all-help: go.help copyright.help tools.help image.help help + $(call makeallhelp) \ No newline at end of file diff --git a/build/buildimage/differ.go b/build/buildimage/differ.go index 40b89e3c5eb..11c39236967 100644 --- a/build/buildimage/differ.go +++ b/build/buildimage/differ.go @@ -37,7 +37,7 @@ import ( osi "github.com/sealerio/sealer/utils/os" ) -// TODO: update the variable name +// TODO: update the variable name. var ( copyToManifests = "manifests" copyToChart = "charts" @@ -45,8 +45,10 @@ var ( copyToApplication = "application" ) -type parseContainerImageStringSliceFunc func(srcPath string) ([]string, error) -type parseContainerImageListFunc func(srcPath string) ([]*v12.ContainerImage, error) +type ( + parseContainerImageStringSliceFunc func(srcPath string) ([]string, error) + parseContainerImageListFunc func(srcPath string) ([]*v12.ContainerImage, error) +) var parseContainerImageStringSliceFuncMap = map[string]func(srcPath string) ([]string, error){ copyToManifests: parseYamlImages, @@ -274,7 +276,6 @@ func parseApplicationKubeImages(kubePath string) ([]string, error) { } ima, err := imageSearcher.ListImages(path) - if err != nil { return err } @@ -351,7 +352,6 @@ func parseYamlImages(srcPath string) ([]string, error) { } ima, err := imageSearcher.ListImages(path) - if err != nil { return err } diff --git a/build/kubefile/command/command.go b/build/kubefile/command/command.go index 26918f15cae..677a6c90a84 100644 --- a/build/kubefile/command/command.go +++ b/build/kubefile/command/command.go @@ -34,10 +34,10 @@ const ( Label = "label" Maintainer = "maintainer" - // Deprecated + // Deprecated. Cmd = "cmd" - // the following commands are the intenal implementations for kube commands + // the following commands are the intenal implementations for kube commands. Add = "add" Arg = "arg" Copy = "copy" @@ -56,7 +56,7 @@ var ( LabelKubeCSIPrefix = fmt.Sprintf("%s-", LabelSupportedKubeCSIAlpha) ) -// SupportedCommands is list of all Kubefile commands +// SupportedCommands is list of all Kubefile commands. var SupportedCommands = map[string]struct{}{ Add: {}, Arg: {}, diff --git a/cmd/sealer/cmd/image/build.go b/cmd/sealer/cmd/image/build.go index ad395ccde92..118d762e1d6 100644 --- a/cmd/sealer/cmd/image/build.go +++ b/cmd/sealer/cmd/image/build.go @@ -28,11 +28,11 @@ import ( "github.com/sealerio/sealer/pkg/imageengine" "github.com/sealerio/sealer/pkg/imageengine/buildah" "github.com/sealerio/sealer/pkg/rootfs" + "github.com/sealerio/sealer/pkg/version" v1 "github.com/sealerio/sealer/types/api/v1" osi "github.com/sealerio/sealer/utils/os" "github.com/sealerio/sealer/utils/strings" "github.com/sealerio/sealer/utils/yaml" - "github.com/sealerio/sealer/version" "github.com/containerd/containerd/platforms" "github.com/containers/buildah/define" diff --git a/cmd/sealer/cmd/root.go b/cmd/sealer/cmd/root.go index 4bc0389d2f9..d9c2233d6df 100644 --- a/cmd/sealer/cmd/root.go +++ b/cmd/sealer/cmd/root.go @@ -28,7 +28,7 @@ import ( "github.com/sealerio/sealer/cmd/sealer/cmd/image" "github.com/sealerio/sealer/common" "github.com/sealerio/sealer/pkg/logger" - "github.com/sealerio/sealer/version" + "github.com/sealerio/sealer/pkg/version" ) type rootOpts struct { diff --git a/cmd/sealer/cmd/version.go b/cmd/sealer/cmd/version.go index d22c8701657..bf9fcea467a 100644 --- a/cmd/sealer/cmd/version.go +++ b/cmd/sealer/cmd/version.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" - "github.com/sealerio/sealer/version" + "github.com/sealerio/sealer/pkg/version" ) var shortPrint bool diff --git a/cmd/seautil/cmd/version.go b/cmd/seautil/cmd/version.go index 4d29a88800a..3dc177de7ef 100644 --- a/cmd/seautil/cmd/version.go +++ b/cmd/seautil/cmd/version.go @@ -22,7 +22,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/sealerio/sealer/version" + "github.com/sealerio/sealer/pkg/version" ) var shortPrint bool diff --git a/pkg/checker/node_checker.go b/pkg/checker/node_checker.go index 992e8571065..2b9648baba2 100644 --- a/pkg/checker/node_checker.go +++ b/pkg/checker/node_checker.go @@ -88,7 +88,7 @@ func (n *NodeChecker) Check(cluster *v2.Cluster, phase string) error { } func (n *NodeChecker) Output(nodeCLusterStatus NodeClusterStatus) error { - //t1, err := template.ParseFiles("templates/node_checker.tpl") + // t1, err := template.ParseFiles("templates/node_checker.tpl") t := template.New("node_checker") t, err := t.Parse( `Cluster Node Status diff --git a/version/base.go b/pkg/version/base.go similarity index 100% rename from version/base.go rename to pkg/version/base.go diff --git a/version/types.go b/pkg/version/types.go similarity index 100% rename from version/types.go rename to pkg/version/types.go diff --git a/version/version.go b/pkg/version/version.go similarity index 100% rename from version/version.go rename to pkg/version/version.go diff --git a/scripts/build.sh b/scripts/build.sh index 76c0c8958fe..c0112a2dce1 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -65,7 +65,7 @@ ldflags() { "-X '${SEALER_GO_PACKAGE}/version.${key}=${val}'" ) } - add_ldflag "buildDate" "$(date "+%F %T")" + add_ldflag "buildDate" "$(date "+%FT %T %z")" if [[ -n ${GIT_COMMIT-} ]]; then add_ldflag "gitCommit" "${GIT_COMMIT}" fi @@ -140,4 +140,3 @@ if [[ $MULTI_PLATFORM_BUILD ]]; then else build_binaries `go env GOOS` `go env GOARCH` fi - diff --git a/scripts/coverage.awk b/scripts/coverage.awk new file mode 100644 index 00000000000..49389054e2d --- /dev/null +++ b/scripts/coverage.awk @@ -0,0 +1,13 @@ +#!/usr/bin/env awk + +{ + print $0 + if (match($0, /^total:/)) { + sub(/%/, "", $NF); + printf("test coverage is %s%(quality gate is %s%)\n", $NF, target) + if (strtonum($NF) < target) { + printf("test coverage does not meet expectations: %d%, please add test cases!\n", target) + exit 1; + } + } +} diff --git a/scripts/make-rules/ca.mk b/scripts/make-rules/ca.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index ca6570d3422..3ed7650e47b 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -12,12 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +# ============================================================================== +# Makefile helper functions for common tasks +# + SHELL := /bin/bash DIRS=$(shell ls) DEBUG ?= 0 GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) GIT_COMMIT ?= $(shell git rev-parse --short HEAD || echo "0.0.0") -BUILD_DATE=$(shell date +%FT%T%z) +BUILD_DATE=$(shell date '+%FT %T %z') # "buildDate":"2023-03-31T 20:05:43 +0800" # include the common makefile COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) @@ -29,13 +33,13 @@ endif # OUTPUT_DIR: The directory where the build output is stored. ifeq ($(origin OUTPUT_DIR),undefined) -OUTPUT_DIR := $(ROOT_DIR)/dist +OUTPUT_DIR := $(ROOT_DIR)/_output $(shell mkdir -p $(OUTPUT_DIR)) endif # BIN_DIR: Directory where executable files are stored. ifeq ($(origin BIN_DIR),undefined) -BIN_DIR := $(ROOT_DIR)/out_put +BIN_DIR := $(OUTPUT_DIR)/bin $(shell mkdir -p $(BIN_DIR)) endif @@ -55,10 +59,31 @@ ifeq ($(origin VERSION), undefined) VERSION := $(shell git describe --abbrev=0 --dirty --always --tags | sed 's/-/./g') endif +# Check if the tree is dirty. default to dirty(maybe u should commit?) +GIT_TREE_STATE:="dirty" +ifeq (, $(shell git status --porcelain 2>/dev/null)) + GIT_TREE_STATE="clean" +endif +GIT_COMMIT:=$(shell git rev-parse HEAD) + +# Minimum test coverage +ifeq ($(origin COVERAGE),undefined) +COVERAGE := 60 +endif + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + # platforms: The OS must be linux when building docker images PLATFORMS ?= linux_amd64 linux_arm64 # TODO(sealer?): The OS can be linux/windows/darwin when building binaries? if only support linux # PLATFORMS ?= darwin_amd64 windows_amd64 linux_amd64 linux_arm64 + +# only support linux GOOS=linux # set a specific PLATFORM, defaults to the host platform @@ -83,12 +108,11 @@ endif # TODO: Whether you need to join utils? FIND := find . ! -path './utils/*' ! -path './vendor/*' XARGS := xargs -r -# CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/build -# FIND := find $(CODE_DIRS) -# Linux command settings -CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/staging -FIND := find $(CODE_DIRS) +# Linux command settings-CODE DIRS Copyright +# $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' +CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/build $(ROOT_DIR)/scripts $(ROOT_DIR)/utils $(ROOT_DIR)/common +FINDS := find $(CODE_DIRS) # Makefile settings: Select different behaviors by determining whether V option is set ifeq ($(origin V), undefined) # ifndef V @@ -100,4 +124,47 @@ COMMA := , # SPACE: Used to separate strings SPACE := # SPACE: Replace multiple consecutive Spaces with a single space -SPACE += \ No newline at end of file +SPACE += + + +# ============================================================================== +# Makefile helper functions for common tasks + +# Help information for the makefile package +define makehelp + @printf "\n\033[1mUsage: make ...\033[0m\n\n\\033[1mTargets:\\033[0m\n\n" + @sed -n 's/^##//p' $< | awk -F':' '{printf "\033[36m%-28s\033[0m %s\n", $$1, $$2}' | sed -e 's/^/ /' + @printf "\n\033[1m$$USAGE_OPTIONS\033[0m\n" +endef + +# Here are some examples of builds +define MAKEFILE_EXAMPLE +# make build BINS=sealer Only a single sealer binary is built +# make fmt vet lint Run code style check +# make gen Generate all necessary files +# make deepcopy Generate deepcopy code +# make verify-copyright Verify the license headers for all files +# make install-deepcopy-gen Install deepcopy-gen tools if the license is missing +# make build BINS=sealer V=1 DEBUG=1 Build debug binaries for only sealer +# make build.multiarch PLATFORMS="linux_arm64 linux_amd64" V=1 Build binaries for both platforms +endef +export MAKEFILE_EXAMPLE + +# Define all help functions @printf "\n\033[1mCurrent sealer version information: $(shell sealer version):\033[0m\n\n" +define makeallhelp + @printf "\n\033[1mMake example:\033[0m\n\n" + $(call MAKEFILE_EXAMPLE) + @printf "\n\033[1mAriables:\033[0m\n\n" + @echo " DEBUG: $(DEBUG)" + @echo " BINS: $(BINS)" + @echo " PLATFORMS: $(PLATFORMS)" + @echo " V: $(V)" +endef + +# Help information for other makefile packages +CUT_OFF?="---------------------------------------------------------------------------------" +HELP_NAME:=$(shell basename $(MAKEFILE_LIST)) +define smallhelp + @sed -n 's/^##//p' $< | awk -F':' '{printf "\033[36m%-35s\033[0m %s\n", $$1, $$2}' | sed -e 's/^/ /' + @echo $(CUT_OFF) +endef \ No newline at end of file diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk index e69de29bb2d..efb829d7c3d 100644 --- a/scripts/make-rules/copyright.mk +++ b/scripts/make-rules/copyright.mk @@ -0,0 +1,93 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============================================================================== +# wget https://github.com/google/addlicense/releases/download/v1.0.0/addlicense_1.0.0_Linux_x86_64.tar.gz +# Makefile helper functions for copyright +# + +# filelicense: SHELL:=/bin/bash +# ## filelicense: add license for all files +# filelicense: +# for file in ${Dirs} ; do \ +# if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ +# $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f scripts/LICENSE_TEMPLATE ./$$file ; \ +# fi \ +# done +# +# install-addlicense: +# ifeq (, $(shell which addlicense)) +# @{ \ +# set -e ;\ +# LICENSE_TMP_DIR=$$(mktemp -d) ;\ +# cd $$LICENSE_TMP_DIR ;\ +# go mod init tmp ;\ +# go get -v github.com/google/addlicense ;\ +# rm -rf $$LICENSE_TMP_DIR ;\ +# } +# ADDLICENSE_BIN=$(GOBIN)/addlicense +# else +# ADDLICENSE_BIN=$(shell which addlicense) +# endif +# +# ## install-gosec: check license if not exist install addlicense tools. +# install-gosec: +# ifeq (, $(shell which gosec)) +# @{ \ +# set -e ;\ +# curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ +# } +# GOSEC_BIN=$(GOBIN)/gosec +# else +# GOSEC_BIN=$(shell which gosec) +# endif + +LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/LICENSE_TEMPLATE + +.PHONY: copyright.verify +# TODO: GOBIN -> TOOLS_DIR +copyright.verify: tools.verify.addlicense + @echo "===========> Validate boilerplate headers for assign files starting in the $(ROOT_DIR) directory" + @$(GOBIN)/addlicense -v -check -ignore **/test/** -f $(LICENSE_TEMPLATE) $(CODE_DIRS) + @echo "===========> End of boilerplate headers check..." + +.PHONY: copyright.add +## copyright.add: Add the boilerplate headers for all files +copyright.add: tools.verify.addlicense + @echo "===========> Adding $(LICENSE_TEMPLATE) the boilerplate headers for all files" + @$(GOBIN)/addlicense -y $(shell date +"%Y") -v -c "Alibaba Group Holding Ltd." -f $(LICENSE_TEMPLATE) $(CODE_DIRS) + @echo "===========> End the copyright is added..." + +# Addlicense Flags: +# -c string +# copyright holder (default "Google LLC") +# -check +# check only mode: verify presence of license headers and exit with non-zero code if missing +# -f string +# license file +# -ignore value +# file patterns to ignore, for example: -ignore **/*.go -ignore vendor/** +# -l string +# license type: apache, bsd, mit, mpl (default "apache") +# -s Include SPDX identifier in license header. Set -s=only to only include SPDX identifier. +# -skip value +# [deprecated: see -ignore] file extensions to skip, for example: -skip rb -skip go +# -v verbose mode: print the name of the files that are modified or were skipped +# -y string +# copyright year(s) (default "2023") + +.PHONY: copyright.help +## copyright.help: Show copyright help +copyright.help: scripts/make-rules/copyright.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/dependencies.mk b/scripts/make-rules/dependencies.mk index e69de29bb2d..d533d082933 100644 --- a/scripts/make-rules/dependencies.mk +++ b/scripts/make-rules/dependencies.mk @@ -0,0 +1,36 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for dependencies +# + +.PHONY: dependencies.run +dependencies.run: dependencies.packages dependencies.tools + +.PHONY: dependencies.packages +dependencies.packages: + @$(GO) mod tidy + +.PHONY: dependencies.tools +dependencies.tools: dependencies.tools.blocker dependencies.tools.critical + +.PHONY: dependencies.tools.blocker +dependencies.tools.blocker: go.build.verify $(addprefix tools.verify., $(BLOCKER_TOOLS)) + +.PHONY: dependencies.tools.critical +dependencies.tools.critical: $(addprefix tools.verify., $(CRITICAL_TOOLS)) + +.PHONY: dependencies.tools.trivial +dependencies.tools.trivial: $(addprefix tools.verify., $(TRIVIAL_TOOLS)) \ No newline at end of file diff --git a/scripts/make-rules/deploy.mk b/scripts/make-rules/deploy.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/gen.mk b/scripts/make-rules/gen.mk index f0c1821bfab..2fcf79bdae2 100644 --- a/scripts/make-rules/gen.mk +++ b/scripts/make-rules/gen.mk @@ -13,11 +13,91 @@ # limitations under the License. # ============================================================================== -# Makefile helper functions for generate necessary files +# Makefile helper functions for generate necessary files and docs +# https://cloud.redhat.com/blog/kubernetes-deep-dive-code-generation-customresources +# ! The stock of code generated by `make gen` should be idempotent # +## install-deepcopy-gen: check license if not exist install deepcopy-gen tools +# install-deepcopy-gen: +# ifeq (, $(shell which deepcopy-gen)) +# { \ +# set -e ;\ +# LICENSE_TMP_DIR=$$(mktemp -d) ;\ +# cd $$LICENSE_TMP_DIR ;\ +# go mod init tmp ;\ +# go get -v k8s.io/code-generator/cmd/deepcopy-gen ;\ +# rm -rf $$LICENSE_TMP_DIR ;\ +# } +# DEEPCOPY_BIN=$(GOBIN)/deepcopy-gen +# else +# DEEPCOPY_BIN=$(shell which deepcopy-gen) +# endif + +# BOILERPLATE := scripts/boilerplate.go.txt +# INPUT_DIR := github.com/sealerio/sealer/types/api + +## deepcopy: generate deepcopy code +# deepcopy: install-deepcopy-gen +# $(DEEPCOPY_BIN) \ +# --input-dirs="$(INPUT_DIR)/v1" \ +# -O zz_generated.deepcopy \ +# --go-header-file "$(BOILERPLATE)" \ +# --output-base "${GOPATH}/src" +# $(DEEPCOPY_BIN) \ +# --input-dirs="$(INPUT_DIR)/v2" \ +# -O zz_generated.deepcopy \ +# --go-header-file "$(BOILERPLATE)" \ +# --output-base "${GOPATH}/src" + +# When 'make gen.run' is executed, the previously generated files are actually cleaned up and then automatically generated separately +## gen.run: gen.deepcopy gen.docgo .PHONY: gen.run -#gen.run: gen.errcode gen.docgo -gen.run: gen.clean gen.deepcopy gen.docs +gen.run: gen.clean gen.deepcopyV1 gen.deepcopyV2 #gen.docs + +BOILERPLATE := $(ROOT_DIR)/scripts/boilerplate.go.txt + +INPUT_DIR := $(ROOT_DIR)/types/api/v1 +INPUT_DIRV2 := $(ROOT_DIR)/types/api/v2 +INPUT_DIRS := $(ROOT_PACKAGE)/types/api/v1 +INPUT_DIRSV2 := $(ROOT_PACKAGE)/types/api/v2 + +# TODO: output-base: $(ROOT_PACKAGE)/types/api/v2/...... +## gen.deepcopy: generate deepcopy v1 code +.PHONY: gen.deepcopyV1 +gen.deepcopyV1: tools.verify.deepcopy-gen + @echo "===========> Generating deepcopy go source files in $(INPUT_DIRS)" + @$(TOOLS_DIR)/deepcopy-gen \ + --input-dirs="$(INPUT_DIRS)" \ + --output-file-base zz_generated.deepcopy \ + --go-header-file "$(BOILERPLATE)" \ + --output-base "$(INPUT_DIR)" + +## gen.deepcopyV2: generate deepcopy v2 code +.PHONY: gen.deepcopyV2 +gen.deepcopyV2: tools.verify.deepcopy-gen + @echo "===========> Generating deepcopy go source files in $(INPUT_DIRSV2)" + @$(TOOLS_DIR)/deepcopy-gen \ + --input-dirs="$(INPUT_DIRSV2)" \ + --output-file-base zz_generated.deepcopy \ + --go-header-file "$(BOILERPLATE)" \ + --output-base "$()" + +## gen.docgo: generate doc.go +.PHONY: gen.docs +gen.docs: go.build + @echo "===========> Generating deep of documents use $(BIN_DIR)/$(PLATFORM)/sealer gen-doc" + @$(BIN_DIR)/$(PLATFORM)/sealer gen-doc + +## gen.clean: clean the previously generated files +.PHONY: gen.clean +gen.clean: + @echo "===========> Delete $(INPUT_DIR)..." +# @find $(INPUT_DIR) -type f -name '*_generated.*.go' -delete + @echo "===========> Delete $(INPUT_DIRS)" +# @find $(INPUT_DIRV2) -type f -name '*_generated.*.go' -delete -INPUT_DIR := $(ROOT_DIR)/types/api \ No newline at end of file +## gen.help: show help for gen +.PHONY: gen.help +gen.help: scripts/make-rules/gen.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index e69de29bb2d..3b7d187e0ec 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -0,0 +1,185 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Build management helpers. These functions help to set, save and load the +# + +GO := go +# ! go 1.8 some packages fail to be pulled out. You are advised to use the gvm switchover version of the tools toolkit +GO_SUPPORTED_VERSIONS ?= |1.18|1.19|1.20| + +GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=${GIT_TAG} \ + -X $(VERSION_PACKAGE).gitCommit=${GIT_COMMIT} \ + -X $(VERSION_PACKAGE).GitTreeState=$(GIT_TREE_STATE) \ + -X $(VERSION_PACKAGE).buildDate=${BUILD_DATE} \ + -s -w # -s -w deletes debugging information and symbol tables +# ifneq ($(DLV),) +# GO_BUILD_FLAGS += -gcflags "all=-N -l" +# LDFLAGS = "" +# endif +ifeq ($(DEBUG), 1) + GO_BUILD_FLAGS += -gcflags "all=-N -l" + GO_LDFLAGS= +endif +GO_BUILD_FLAGS += -tags "containers_image_openpgp netgo exclude_graphdriver_devicemapper static osusergo exclude_graphdriver_btrfs" -trimpath -ldflags "$(GO_LDFLAGS)" + +# ifeq ($(GOOS),windows) +# GO_OUT_EXT := .exe +# endif + +ifeq ($(ROOT_PACKAGE),) + $(error the variable ROOT_PACKAGE must be set prior to including golang.mk, ->/Makefile) +endif + +GOPATH ?= $(shell go env GOPATH) +ifeq ($(origin GOBIN), undefined) + GOBIN := $(GOPATH)/bin +endif + +# COMMANDS is Specify all files under ${ROOT_DIR}/cmd/ except those ending in.md +COMMANDS ?= $(filter-out %.md, $(wildcard ${ROOT_DIR}/cmd/*)) +ifeq (${COMMANDS},) + $(error Could not determine COMMANDS, set ROOT_DIR or run in source dir) +endif + +# BINS is the name of each file in ${COMMANDS}, excluding the directory path +# If there are no files in ${COMMANDS}, or if all files end in.md, ${BINS} will be empty +BINS ?= $(foreach cmd,${COMMANDS},$(notdir ${cmd})) +ifeq (${BINS},) + $(error Could not determine BINS, set ROOT_DIR or run in source dir) +endif + +# TODO: EXCLUDE_TESTS variable, which contains the name of the package to be excluded from the test +EXCLUDE_TESTS := github.com/sealerio/sealer/test github.com/sealerio/sealer/pkg/logger + +# ============================================================================== +# make: Nothing to be done build and build sub targets +# _output $(OUTPUT_DIR) +# ├── assets +# │ ├── sealer-unknown-linux-amd64.tar.gz +# │ ├── sealer-unknown-linux-amd64.tar.gz.sha256sum +# │ ├── seautil-unknown-linux-amd64.tar.gz +# │ └── seautil-unknown-linux-amd64.tar.gz.sha256sum +# └── bin $(BIN_DIR) +# ├── sealer +# │ └── linux_amd64 +# │ │ └── sealer +# │ └── linux_arm64 +# │ └── sealer +# └── seautil +# └── linux_amd64 +# └── seautil +# COMMAND=sealer +# PLATFORM=linux_amd64 +# OS=linux +# ARCH=amd64 +# BINS=sealer seautil +# BIN_DIR=/root/workspaces/sealer/_output/bin +# ============================================================================== + +## go.build.verify: Verify that a suitable version of Go exists +.PHONY: go.build.verify +go.build.verify: + @echo "===========> Verify that a suitable version of Go exists, current version: $(shell $(GO) version)" +ifneq ($(shell $(GO) version | grep -q -E '\bgo($(GO_SUPPORTED_VERSIONS))\b' && echo 0 || echo 1), 0) + $(error unsupported go version. Please make install one of the following supported version: '$(GO_SUPPORTED_VERSIONS)'.You can use make install. gvm to install gvm and switch to the specified version) +endif + +## go.bin.%: Verify binary for specific platform +.PHONY: go.bin.% +go.bin.%: + $(eval COMMAND := $(word 2,$(subst ., ,$*))) + $(eval PLATFORM := $(word 1,$(subst ., ,$*))) + @echo "===========> Verifying binary $(COMMAND) $(VERSION) for $(PLATFORM)" + @if [ ! -f $(BIN_DIR)/$(PLATFORM)/$(COMMAND) ]; then echo $(MAKE) go.build PLATFORM=$(PLATFORM); fi + +## go.build.%: Build binary for specific platform +.PHONY: go.build.% +go.build.%: + $(eval COMMAND := $(word 2,$(subst ., ,$*))) + $(eval PLATFORM := $(word 1,$(subst ., ,$*))) + $(eval OS := $(word 1,$(subst _, ,$(PLATFORM)))) + $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) + @echo "COMMAND=$(COMMAND)" + @echo "PLATFORM=$(PLATFORM)" + @echo "OS=$(OS)" + @echo "ARCH=$(ARCH)" + @echo "BINS=$(BINS)" + @echo "BIN_DIR=$(BIN_DIR)" + @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS) $(ARCH)" + @mkdir -p $(OUTPUT_DIR)/bin/$(OS)/$(ARCH) + + @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(OUTPUT_DIR)/bin/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) + +## go.build: Build binaries +.PHONY: go.build +go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BINS))) + @echo "COMMAND=$(COMMAND)" + @echo "PLATFORM=$(PLATFORM)" + @echo "OS=$(OS)" + @echo "ARCH=$(ARCH)" + @echo "===========> Building binary $(BINS) $(VERSION) for $(PLATFORM)" + +## go.build.multiarch: Build multi-arch binaries +.PHONY: go.build.multiarch +go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) + +## go.lint: Run golangci to lint source codes +.PHONY: go.lint +go.lint: tools.verify.golangci-lint + @echo "===========> Run golangci to lint source codes" + @golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... + +## go.test: Run unit test +.PHONY: go.test +go.test: tools.verify.go-junit-report + @echo "===========> Run unit test" +# @set -o pipefail;$(GO) test -race -cover -coverprofile=$(OUTPUT_DIR)/coverage.out \ +# -timeout=10m -shuffle=on -short -v `go list ./...|\ +# egrep -v $(subst $(SPACE),'|',$(sort $(EXCLUDE_TESTS)))` 2>&1 | \ +# tee >(go-junit-report --set-exit-code >$(OUTPUT_DIR)/report.xml) +# @sed -i '/mock_.*.go/d' $(OUTPUT_DIR)/coverage.out # remove mock_.*.go files from test coverage +# @$(GO) tool cover -html=$(OUTPUT_DIR)/coverage.out -o $(OUTPUT_DIR)/coverage.html + +## go.test.cover: Run unit test and check coverage +.PHONY: go.test.cover +go.test.cover: go.test + @$(GO) tool cover -func=$(OUTPUT_DIR)/coverage.out | \ + awk -v target=$(COVERAGE) -f $(ROOT_DIR)/scripts/coverage.awk + +## go.test.integration: Run integration test +.PHONY: go.format +go.format: tools.verify.goimports + @echo "===========> Formating codes" + @$(FIND) -type f -name '*.go' | xargs gofmt -s -w + @$(FIND) -type f -name '*.go' | xargs $(TOOLS_DIR)/goimports -l -w -local $(ROOT_PACKAGE) + @$(GO) mod edit -fmt + +## go.updates: Check for updates to go.mod dependencies +.PHONY: go.updates +go.updates: tools.verify.go-mod-outdated + @$(GO) list -u -m -json all | go-mod-outdated -update -direct + +## go.clean: Clean all builds +.PHONY: go.clean +go.clean: + @echo "===========> Cleaning all builds $(OUTPUT_DIR) and $(BIN_DIR)" + @-rm -vrf $(OUTPUT_DIR) $(BIN_DIR) + @echo "===========> End clean..." + +## copyright.help: Show copyright help +.PHONY: go.help +go.help: scripts/make-rules/golang.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/image.mk b/scripts/make-rules/image.mk index e69de29bb2d..35ef75db748 100644 --- a/scripts/make-rules/image.mk +++ b/scripts/make-rules/image.mk @@ -0,0 +1,155 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for docker image +# TODO: For the time being only used for compilation, it can be arm or amd, please do not delete it, it can be extended with new functions +# ============================================================================== +# Path: scripts/make-rules/image.mk +# docker registry: registry.example.com/namespace/image:tag as: registry.hub.docker.com/cubxxw/: +# + +DOCKER := docker +DOCKER_SUPPORTED_API_VERSION ?= 1.32|1.40 + +REGISTRY_PREFIX ?= cubxxw +BASE_IMAGE = centos:centos8 + +EXTRA_ARGS ?= --no-cache +_DOCKER_BUILD_EXTRA_ARGS := + +ifdef HTTP_PROXY +_DOCKER_BUILD_EXTRA_ARGS += --build-arg HTTP_PROXY=${HTTP_PROXY} +endif + +ifneq ($(EXTRA_ARGS), ) +_DOCKER_BUILD_EXTRA_ARGS += $(EXTRA_ARGS) +endif + +# Determine image files by looking into build/docker/*/Dockerfile +IMAGES_DIR ?= $(wildcard ${ROOT_DIR}/build/docker/*) +# Determine images names by stripping out the dir names +IMAGES ?= $(filter-out tools,$(foreach image,${IMAGES_DIR},$(notdir ${image}))) + +# ifeq (${IMAGES},) +# $(error Could not determine IMAGES, set ROOT_DIR or run in source dir) +# endif + +# ============================================================================== +# Image targets +# ============================================================================== + +.PHONY: image.verify +## image.verify: Verify docker version +image.verify: + $(eval API_VERSION := $(shell $(DOCKER) version | grep -E 'API version: {1,6}[0-9]' | head -n1 | awk '{print $$3} END { if (NR==0) print 0}' )) + $(eval PASS := $(shell echo "$(API_VERSION) > $(DOCKER_SUPPORTED_API_VERSION)" | bc)) + @if [ $(PASS) -ne 1 ]; then \ + $(DOCKER) -v ;\ + echo "Unsupported docker version. Docker API version should be greater than $(DOCKER_SUPPORTED_API_VERSION)"; \ + exit 1; \ + fi + +.PHONY: image.daemon.verify +## image.daemon.verify: Verify docker daemon experimental features +image.daemon.verify: + $(eval PASS := $(shell $(DOCKER) version | grep -q -E 'Experimental: {1,5}true' && echo 1 || echo 0)) + @if [ $(PASS) -ne 1 ]; then \ + echo "Experimental features of Docker daemon is not enabled. Please add \"experimental\": true in '/etc/docker/daemon.json' and then restart Docker daemon."; \ + exit 1; \ + fi + +.PHONY: image.build +## image.build: Build docker images +image.build: image.verify go.build.verify $(addprefix image.build., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) + +.PHONY: image.build.multiarch +## image.build.multiarch: Build docker images for all platforms +image.build.multiarch: image.verify go.build.verify $(foreach p,$(PLATFORMS),$(addprefix image.build., $(addprefix $(p)., $(IMAGES)))) + +.PHONY: image.build.% +## image.build.%: Build docker image for a specific platform +image.build.%: go.build.% + $(eval IMAGE := $(COMMAND)) + $(eval IMAGE_PLAT := $(subst _,/,$(PLATFORM))) + @echo "===========> Building docker image $(IMAGE) $(VERSION) for $(IMAGE_PLAT)" + @mkdir -p $(TMP_DIR)/$(IMAGE) + @cat $(ROOT_DIR)/build/docker/$(IMAGE)/Dockerfile\ + | sed "s#BASE_IMAGE#$(BASE_IMAGE)#g" >$(TMP_DIR)/$(IMAGE)/Dockerfile + @cp $(OUTPUT_DIR)/platforms/$(IMAGE_PLAT)/$(IMAGE) $(TMP_DIR)/$(IMAGE)/ + @DST_DIR=$(TMP_DIR)/$(IMAGE) $(ROOT_DIR)/build/docker/$(IMAGE)/build.sh 2>/dev/null || true + $(eval BUILD_SUFFIX := $(_DOCKER_BUILD_EXTRA_ARGS) --pull -t $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) $(TMP_DIR)/$(IMAGE)) + @if [ $(shell $(GO) env GOARCH) != $(ARCH) ] ; then \ + $(MAKE) image.daemon.verify ;\ + $(DOCKER) build --platform $(IMAGE_PLAT) $(BUILD_SUFFIX) ; \ + else \ + $(DOCKER) build $(BUILD_SUFFIX) ; \ + fi + @rm -rf $(TMP_DIR)/$(IMAGE) + +.PHONY: image.push +## image.push: Push docker images +image.push: image.verify go.build.verify $(addprefix image.push., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) + +.PHONY: image.push.multiarch +## image.push.multiarch: Push docker images for all platforms +image.push.multiarch: image.verify go.build.verify $(foreach p,$(PLATFORMS),$(addprefix image.push., $(addprefix $(p)., $(IMAGES)))) + +.PHONY: image.push.% +## image.push.%: Push docker image for a specific platform +image.push.%: image.build.% + @echo "===========> Pushing image $(IMAGE) $(VERSION) to $(REGISTRY_PREFIX)" + $(DOCKER) push $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) + +.PHONY: image.manifest.push +## image.manifest.push: Push manifest list for multi-arch images +image.manifest.push: export DOCKER_CLI_EXPERIMENTAL := enabled +image.manifest.push: image.verify go.build.verify \ +$(addprefix image.manifest.push., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) + +.PHONY: image.manifest.push.% +## image.manifest.push.%: Push manifest list for multi-arch images for a specific platform +image.manifest.push.%: image.push.% image.manifest.remove.% + @echo "===========> Pushing manifest $(IMAGE) $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" + @$(DOCKER) manifest create $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) \ + $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) + @$(DOCKER) manifest annotate $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) \ + $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) \ + --os $(OS) --arch ${ARCH} + @$(DOCKER) manifest push --purge $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) + +# Docker cli has a bug: https://github.com/docker/cli/issues/954 +# If you find your manifests were not updated, +# Please manually delete them in $HOME/.docker/manifests/ +# and re-run. +.PHONY: image.manifest.remove.% +## image.manifest.remove.%: Remove local manifest list +image.manifest.remove.%: + @rm -rf ${HOME}/.docker/manifests/docker.io_$(REGISTRY_PREFIX)_$(IMAGE)-$(VERSION) + +.PHONY: image.manifest.push.multiarch +## image.manifest.push.multiarch: Push manifest list for multi-arch images for all platforms +image.manifest.push.multiarch: image.push.multiarch $(addprefix image.manifest.push.multiarch., $(IMAGES)) + +.PHONY: image.manifest.push.multiarch.% +## image.manifest.push.multiarch.%: Push manifest list for multi-arch images for all platforms for a specific image +image.manifest.push.multiarch.%: + @echo "===========> Pushing manifest $* $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" + REGISTRY_PREFIX=$(REGISTRY_PREFIX) PLATFROMS="$(PLATFORMS)" IMAGE=$* VERSION=$(VERSION) DOCKER_CLI_EXPERIMENTAL=enabled \ + $(ROOT_DIR)/build/lib/create-manifest.sh + +.PHONY: image.help +## image.help: Print help for image targets +image.help: scripts/make-rules/image.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/release.mk b/scripts/make-rules/release.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/swagger.mk b/scripts/make-rules/swagger.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index e69de29bb2d..b9f0b5a8927 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -0,0 +1,189 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for tools(https://github.com/avelino/awesome-go) -> DIR: {TOOT_DIR}/tools | (go >= 1.19) +# + +BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo + +.PHONY: tools.install +## tools.install: Install all tools +tools.install: $(addprefix tools.install., $(BUILD_TOOLS)) + +.PHONY: tools.install.% +## tools.install.%: Install a single tool +tools.install.%: + @echo "===========> Installing $,The default installation path is $(GOBIN)/$*" + @$(MAKE) install.$* + @echo "===========> $* installed successfully" + +.PHONY: tools.verify.% +## tools.verify.%: Check if a tool is installed and install it +tools.verify.%: + @echo "===========> Verifying $* is installed" + @if [ ! -f $(TOOLS_DIR)/$* ]; then GOBIN=$(TOOLS_DIR) $(MAKE) tools.install.$*; fi + +.PHONY: +## install.golangci-lint: Install golangci-lint +install.golangci-lint: + @echo "===========> Installing golangci-lint,The default installation path is $(GOBIN)/golangci-lint" + @$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest +# @golangci-lint completion bash > $(HOME)/.golangci-lint.bash +# @if ! grep -q .golangci-lint.bash $(HOME)/.bashrc; then echo "source \$$HOME/.golangci-lint.bash" >> $(HOME)/.bashrc; fi + +.PHONY: install.goimports +## install.goimports: Install goimports, used to format go source files +install.goimports: + @echo "===========> Installing goimports,The default installation path is $(GOBIN)/goimports" + @$(GO) install golang.org/x/tools/cmd/goimports@latest + +# Actions path: https://github.com/sealerio/sealer/tree/main/.github/workflows/go.yml#L37-L50 +.PHONY: install.addlicense +## install.addlicense: Install addlicense, used to add license header to source files +install.addlicense: + @$(GO) install github.com/google/addlicense@latest + +.PHONY: install.deepcopy-gen +## install.deepcopy-gen: Install deepcopy-gen, used to generate deep copy functions +install.deepcopy-gen: + @$(GO) install k8s.io/code-generator/cmd/deepcopy-gen@latest + +.PHONY: install.conversion-gen +## install.conversion-gen: Install conversion-gen, used to generate conversion functions +install.conversion-gen: + @$(GO) install k8s.io/code-generator/cmd/conversion-gen@latest + +.PHONY: install.ginkgo +## install.ginkgo: Install ginkgo to run a single test or set of tests +install.ginkgo: + @echo "===========> Installing ginkgo,The default installation path is $(GOBIN)/ginkgo" + @$(GO) install github.com/onsi/ginkgo/ginkgo@v1.16.2 + +# ============================================================================== +# Tools that might be used include go gvm +# + +.PHONY: install.go-junit-report +## go-junit-report: Install go-junit-report, used to convert go test output to junit xml +install.go-junit-report: + @$(GO) install github.com/jstemmer/go-junit-report@latest + +.PHONY: install.kube-score +## install.kube-score: Install kube-score, used to check kubernetes yaml files +install.kube-score: + @$(GO) install github.com/zegl/kube-score/cmd/kube-score@latest + +.PHONY: install.go-gitlint +## Install go-gitlint: Install go-gitlint, used to check git commit message +install.go-gitlint: + @$(GO) install github.com/marmotedu/go-gitlint/cmd/go-gitlint@latest + +.PHONY: install.gsemver +## install.gsemver: Install gsemver, used to generate semver +install.gsemver: + @$(GO) install github.com/arnaud-deprez/gsemver@latest + +.PHONY: install.git-chglog +## install.git-chglog: Install git-chglog, used to generate changelog +install.git-chglog: + @$(GO) install github.com/git-chglog/git-chglog/cmd/git-chglog@latest + +.PHONY: install.github-release +## install.github-release: Install github-release, used to create github release +install.github-release: + @$(GO) install github.com/github-release/github-release@latest + +.PHONY: install.gvm +## install.gvm: Install gvm, gvm is a Go version manager, built on top of the official go tool. +install.gvm: + @echo "===========> Installing gvm,The default installation path is ~/.gvm/scripts/gvm" + @bash < <(curl -s -S -L https://raw.gitee.com/moovweb/gvm/master/binscripts/gvm-installer) + @$(shell source /root/.gvm/scripts/gvm) + +.PHONY: install.coscli +## install.coscli: Install coscli. COSCLI is a command line tool for Tencent Cloud Object Storage (COS) +install.coscli: + @wget -q https://github.com/tencentyun/coscli/releases/download/v0.10.2-beta/coscli-linux -O ${HOME}/bin/coscli + @chmod +x ${HOME}/bin/coscli + +.PHONY: install.coscmd +## install.coscmd: Install coscmd, used to upload files to Tencent Cloud Object Storage (COS) +install.coscmd: + @if which pip &>/dev/null; then pip install coscmd; else pip3 install coscmd; fi + +.PHONY: install.golines +## install.golines: Install golines, used to format long lines +install.golines: + @$(GO) install github.com/segmentio/golines@latest + +.PHONY: install.go-mod-outdated +## install.go-mod-outdated: Install go-mod-outdated, used to check outdated dependencies +install.go-mod-outdated: + @$(GO) install github.com/psampaz/go-mod-outdated@latest + +.PHONY: install.mockgen +## install.mockgen: Install mockgen, used to generate mock functions +install.mockgen: + @$(GO) install github.com/golang/mock/mockgen@latest + +.PHONY: install.gotests +## install.gotests: Install gotests, used to generate test functions +install.gotests: + @$(GO) install github.com/cweill/gotests/gotests@latest + +.PHONY: install.protoc-gen-go +## install.protoc-gen-go: Install protoc-gen-go, used to generate go source files from protobuf files +install.protoc-gen-go: + @$(GO) install github.com/golang/protobuf/protoc-gen-go@latest + +.PHONY: install.cfssl +## install.cfssl: Install cfssl, used to generate certificates +install.cfssl: + @$(ROOT_DIR)/scripts/install/install.sh iam::install::install_cfssl + +.PHONY: install.depth +## install.depth: Install depth, used to check dependency tree +install.depth: + @$(GO) install github.com/KyleBanks/depth/cmd/depth@latest + +.PHONY: install.go-callvis +## install.go-callvis: Install go-callvis, used to visualize call graph +install.go-callvis: + @$(GO) install github.com/ofabry/go-callvis@latest + +.PHONY: install.gothanks +## install.gothanks: Install gothanks, used to thank go dependencies +install.gothanks: + @$(GO) install github.com/psampaz/gothanks@latest + +.PHONY: install.richgo +## install.richgo: Install richgo +install.richgo: + @$(GO) install github.com/kyoh86/richgo@latest + +.PHONY: install.rts +## install.rts: Install rts +install.rts: + @$(GO) install github.com/galeone/rts/cmd/rts@latest + +.PHONY: install.codegen +## install.codegen: Install code generator, used to generate code +install.codegen: + @$(GO) install ${ROOT_DIR}/tools/codegen/codegen.go + +.PHONY: tools.help +## tools.help: Display help information about the tools package +tools.help: scripts/make-rules/tools.mk + $(call smallhelp) \ No newline at end of file