From f8c51004d47cd9802a910d53d764db76057a4d91 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Sat, 2 Mar 2019 11:25:47 -0800 Subject: [PATCH] Support building an allow-list of providers (#527) * Add providers subcommand to verify providers Allows users to check what providers are available * Fix version output to add new line This command was totally broken until we moved around the call to `initConfig()`, this just fixes the output now that it works. * Flip boolean of provider include tags All providers are still included by default and fix tags using the old format. --- Makefile | 30 ++++++---- cmd/providers.go | 55 ++++++++++++++++++ cmd/root.go | 4 +- cmd/version.go | 2 +- ...r_alicloud.go => provider_alibabacloud.go} | 2 +- providers/register/provider_aws.go | 2 +- providers/register/provider_azure.go | 2 +- providers/register/provider_azurebatch.go | 2 +- providers/register/provider_cri.go | 2 +- providers/register/provider_huawei.go | 2 +- providers/register/provider_mock.go | 2 +- providers/register/provider_nomad.go | 2 +- providers/register/provider_sfmesh.go | 2 +- providers/register/provider_vic.go | 2 +- providers/register/provider_web.go | 2 +- providers/register/register.go | 18 ++++++ scripts/process_build_tags.sh | 56 +++++++++++++++++++ 17 files changed, 162 insertions(+), 25 deletions(-) create mode 100644 cmd/providers.go rename providers/register/{provider_alicloud.go => provider_alibabacloud.go} (92%) create mode 100755 scripts/process_build_tags.sh diff --git a/Makefile b/Makefile index 6524a8e51..fdf837a3c 100644 --- a/Makefile +++ b/Makefile @@ -4,10 +4,11 @@ DOCKER_IMAGE := virtual-kubelet exec := $(DOCKER_IMAGE) github_repo := virtual-kubelet/virtual-kubelet binary := virtual-kubelet -build_tags := "netgo osusergo $(VK_BUILD_TAGS)" +build_tags := netgo osusergo $(VK_BUILD_TAGS) + # comment this line out for quieter things -#V := 1 # When V is set, print commands and build progress. +# V := 1 # When V is set, print commands and build progress. # Space separated patterns of packages to skip in list, test, format. IGNORED_PACKAGES := /vendor/ @@ -22,9 +23,10 @@ safebuild: $Q docker build --build-arg BUILD_TAGS=$(build_tags) -t $(DOCKER_IMAGE):$(VERSION) . .PHONY: build +build: build_tags_actual := $(shell scripts/process_build_tags.sh $(build_tags)) build: authors @echo "Building..." - $Q CGO_ENABLED=0 go build -a --tags $(build_tags) -ldflags '-extldflags "-static"' -o bin/$(binary) $(if $V,-v) $(VERSION_FLAGS) $(IMPORT_PATH) + $Q CGO_ENABLED=0 go build -a --tags '$(build_tags_actual)' -ldflags '-extldflags "-static"' -o bin/$(binary) $(if $V,-v) $(VERSION_FLAGS) $(IMPORT_PATH) .PHONY: tags tags: @@ -117,20 +119,26 @@ format: $(GOPATH)/bin/goimports $Q find . -iname \*.go | grep -v \ -e "^$$" $(addprefix -e ,$(IGNORED_PACKAGES)) | xargs goimports -w +.PHONY: skaffold-validate +skaffold-validate: + @if [[ ! "minikube,docker-for-desktop" =~ .*"$(kubectl_context)".* ]]; then \ + echo current-context is [$(kubectl_context)]. Must be one of [minikube,docker-for-desktop]; false; \ + fi + +.PHONY: skaffold-build +skaffold-build: tags_with_mock := $(VK_BUILD_TAGS) mock_provider +skaffold-build: + @if [[ ! "$(MODE)" == "delete" ]]; then \ + GOOS=linux GOARCH=amd64 $(MAKE) VK_BUILD_TAGS="$(tags_with_mock)" build; \ + fi + # skaffold deploys the virtual-kubelet to the Kubernetes cluster targeted by the current kubeconfig using skaffold. # The current context (as indicated by "kubectl config current-context") must be one of "minikube" or "docker-for-desktop". # MODE must be set to one of "dev" (default), "delete" or "run", and is used as the skaffold command to be run. .PHONY: skaffold skaffold: MODE ?= dev skaffold: PROFILE := local -skaffold: VK_BUILD_TAGS ?= no_alibabacloud_provider no_aws_provider no_azure_provider no_azurebatch_provider no_cri_provider no_huawei_provider no_vic_provider no_web_provider -skaffold: - @if [[ ! "minikube,docker-for-desktop" =~ .*"$(kubectl_context)".* ]]; then \ - echo current-context is [$(kubectl_context)]. Must be one of [minikube,docker-for-desktop]; false; \ - fi - @if [[ ! "$(MODE)" == "delete" ]]; then \ - GOOS=linux GOARCH=amd64 VK_BUILD_TAGS="$(VK_BUILD_TAGS)" $(MAKE) build; \ - fi +skaffold: skaffold-validate skaffold-build @skaffold $(MODE) \ -f $(PWD)/hack/skaffold/virtual-kubelet/skaffold.yml \ -p $(PROFILE) diff --git a/cmd/providers.go b/cmd/providers.go new file mode 100644 index 000000000..29fed9ab2 --- /dev/null +++ b/cmd/providers.go @@ -0,0 +1,55 @@ +// Copyright © 2017 NAME HERE +// +// 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. + +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/virtual-kubelet/virtual-kubelet/providers/register" +) + +// versionCmd represents the version command +var providersCmd = &cobra.Command{ + Use: "providers", + Short: "Show the list of supported providers", + Long: "Show the list of supported providers", + Args: cobra.MaximumNArgs(2), + Run: func(cmd *cobra.Command, args []string) { + switch len(args) { + case 0: + ls := register.List() + for _, p := range ls { + fmt.Fprintln(cmd.OutOrStdout(), p) + } + case 1: + if !register.Exists(args[0]) { + fmt.Fprintln(cmd.OutOrStderr(), "no such provider", args[0]) + + // TODO(@cpuuy83): would be nice to not short-circuit the exit here + // But at the momemt this seems to be the only way to exit non-zero and + // handle our own error output + os.Exit(1) + } + fmt.Fprintln(cmd.OutOrStdout(), args[0]) + } + return + }, +} + +func init() { + RootCmd.AddCommand(providersCmd) +} diff --git a/cmd/root.go b/cmd/root.go index 826963c7c..32b8cf636 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -90,6 +90,8 @@ var RootCmd = &cobra.Command{ backend implementation allowing users to create kubernetes nodes without running the kubelet. This allows users to schedule kubernetes workloads on nodes that aren't running Kubernetes.`, Run: func(cmd *cobra.Command, args []string) { + initConfig() + defer rootContextCancel() vk := vkubelet.New(vkubelet.Config{ @@ -167,8 +169,6 @@ func init() { log.L = logruslogger.FromLogrus(logrus.NewEntry(logrus.StandardLogger())) trace.T = opencensus.Adapter{} - cobra.OnInitialize(initConfig) - // read default node name from environment variable. // it can be overwritten by cli flags if specified. defaultNodeName := os.Getenv("DEFAULT_NODE_NAME") diff --git a/cmd/version.go b/cmd/version.go index 2206716a8..20545e18b 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -27,7 +27,7 @@ var versionCmd = &cobra.Command{ Short: "Show the version of the program", Long: `Show the version of the program`, Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("Version: %s, Built: %s", version.Version, version.BuildTime) + fmt.Printf("Version: %s, Built: %s\n", version.Version, version.BuildTime) }, } diff --git a/providers/register/provider_alicloud.go b/providers/register/provider_alibabacloud.go similarity index 92% rename from providers/register/provider_alicloud.go rename to providers/register/provider_alibabacloud.go index 98d67570f..c3d94f1db 100644 --- a/providers/register/provider_alicloud.go +++ b/providers/register/provider_alibabacloud.go @@ -1,4 +1,4 @@ -// +build !no_alibabacloud_provider +// +build alibabacloud_provider package register diff --git a/providers/register/provider_aws.go b/providers/register/provider_aws.go index dead12c78..c82a87b21 100644 --- a/providers/register/provider_aws.go +++ b/providers/register/provider_aws.go @@ -1,4 +1,4 @@ -// +build !no_aws_provider +// +build aws_provider package register diff --git a/providers/register/provider_azure.go b/providers/register/provider_azure.go index 5023afdf5..268acb169 100644 --- a/providers/register/provider_azure.go +++ b/providers/register/provider_azure.go @@ -1,4 +1,4 @@ -// +build !no_azure_provider +// +build azure_provider package register diff --git a/providers/register/provider_azurebatch.go b/providers/register/provider_azurebatch.go index b8fab0435..91dcefb4e 100644 --- a/providers/register/provider_azurebatch.go +++ b/providers/register/provider_azurebatch.go @@ -1,4 +1,4 @@ -// +build !no_azurebatch_provider +// +build azurebatch_provider package register diff --git a/providers/register/provider_cri.go b/providers/register/provider_cri.go index a9d4ee7d7..0ceacb301 100644 --- a/providers/register/provider_cri.go +++ b/providers/register/provider_cri.go @@ -1,4 +1,4 @@ -// +build linux,!no_cri_provider +// +build linux,cri_provider package register diff --git a/providers/register/provider_huawei.go b/providers/register/provider_huawei.go index 847a8975d..3130da634 100644 --- a/providers/register/provider_huawei.go +++ b/providers/register/provider_huawei.go @@ -1,4 +1,4 @@ -// +build !no_huawei_provider +// +build huawei_provider package register diff --git a/providers/register/provider_mock.go b/providers/register/provider_mock.go index f9a48df38..320eefee3 100644 --- a/providers/register/provider_mock.go +++ b/providers/register/provider_mock.go @@ -1,4 +1,4 @@ -// +build !no_mock_provider +// +build mock_provider package register diff --git a/providers/register/provider_nomad.go b/providers/register/provider_nomad.go index b9b4ea92d..17d6471e6 100644 --- a/providers/register/provider_nomad.go +++ b/providers/register/provider_nomad.go @@ -1,4 +1,4 @@ -// +build !no_nomad_provider +// +build nomad_provider package register diff --git a/providers/register/provider_sfmesh.go b/providers/register/provider_sfmesh.go index 9e4788b6b..97e600a99 100644 --- a/providers/register/provider_sfmesh.go +++ b/providers/register/provider_sfmesh.go @@ -1,4 +1,4 @@ -// +build !no_sfmesh_provider +// +build sfmesh_provider package register diff --git a/providers/register/provider_vic.go b/providers/register/provider_vic.go index 6e7582793..d32416847 100644 --- a/providers/register/provider_vic.go +++ b/providers/register/provider_vic.go @@ -1,4 +1,4 @@ -// +build linux,!no_vic_provider +// +build linux,vic_provider package register diff --git a/providers/register/provider_web.go b/providers/register/provider_web.go index f10b2034c..d3ea0ff4e 100644 --- a/providers/register/provider_web.go +++ b/providers/register/provider_web.go @@ -1,4 +1,4 @@ -// +build !no_web_provider +// +build web_provider package register diff --git a/providers/register/register.go b/providers/register/register.go index 11b853ebd..b8d979fde 100644 --- a/providers/register/register.go +++ b/providers/register/register.go @@ -1,6 +1,8 @@ package register import ( + "sort" + "github.com/cpuguy83/strongerrors" "github.com/pkg/errors" "github.com/virtual-kubelet/virtual-kubelet/manager" @@ -30,6 +32,22 @@ func GetProvider(name string, cfg InitConfig) (providers.Provider, error) { return f(cfg) } +// Exists checks if a provider is regstered +func Exists(name string) bool { + _, ok := providerInits[name] + return ok +} + +// List gets the list of all provider names +func List() []string { + ls := make([]string, 0, len(providerInits)) + for name := range providerInits { + ls = append(ls, name) + } + sort.Strings(ls) + return ls +} + func register(name string, f initFunc) { providerInits[name] = f } diff --git a/scripts/process_build_tags.sh b/scripts/process_build_tags.sh new file mode 100755 index 000000000..d88ef5a62 --- /dev/null +++ b/scripts/process_build_tags.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# set -e -o pipefail + +orig_tags=(${@}) +new_tags=() +omit_providers=() + +let found_provider=0 + +function debug() { + if [ "${V}" = "1" ]; then + (>&2 echo "$@") + fi +} + +for tag in ${orig_tags[@]}; do + case "${tag}" in + no_*_provider) + # filtered + debug "filtered old, invalid ${tag} from tag list, provider is already excluded" + + # store just in case no "proper" provider tags were provided + # In such cases we'd build everything, but we don't want to build these + p="${tag#no_}" + p="${p%_*}" + omit_providers+=("${p}") + ;; + *_provider) + found_provider+=1 + new_tags+=("${tag}") + ;; + *) + new_tags+=("${tag}") + ;; + esac +done + +if [ ${found_provider} -eq 0 ]; then + # include all providers + for i in $(ls providers/register/provider_*.go); do + p="${i#*provider_}" + p="${p%.*}" + + if [[ ! "${omit_providers[*]}" =~ "${p}" ]]; then + debug "including provider ${p}" + new_tags+=("${p}_provider") + else + debug "excluding provider ${p}" + fi + done +fi + + + +echo "${new_tags[@]}"