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.
This commit is contained in:
Brian Goff
2019-03-02 11:25:47 -08:00
committed by GitHub
parent a5d7400232
commit f8c51004d4
17 changed files with 162 additions and 25 deletions

View File

@@ -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)

55
cmd/providers.go Normal file
View File

@@ -0,0 +1,55 @@
// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
//
// 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)
}

View File

@@ -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")

View File

@@ -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)
},
}

View File

@@ -1,4 +1,4 @@
// +build !no_alibabacloud_provider
// +build alibabacloud_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_aws_provider
// +build aws_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_azure_provider
// +build azure_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_azurebatch_provider
// +build azurebatch_provider
package register

View File

@@ -1,4 +1,4 @@
// +build linux,!no_cri_provider
// +build linux,cri_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_huawei_provider
// +build huawei_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_mock_provider
// +build mock_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_nomad_provider
// +build nomad_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_sfmesh_provider
// +build sfmesh_provider
package register

View File

@@ -1,4 +1,4 @@
// +build linux,!no_vic_provider
// +build linux,vic_provider
package register

View File

@@ -1,4 +1,4 @@
// +build !no_web_provider
// +build web_provider
package register

View File

@@ -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
}

56
scripts/process_build_tags.sh Executable file
View File

@@ -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[@]}"