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,7 +4,8 @@ DOCKER_IMAGE := virtual-kubelet
exec := $(DOCKER_IMAGE) exec := $(DOCKER_IMAGE)
github_repo := virtual-kubelet/virtual-kubelet github_repo := virtual-kubelet/virtual-kubelet
binary := 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 # 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.
@@ -22,9 +23,10 @@ safebuild:
$Q docker build --build-arg BUILD_TAGS=$(build_tags) -t $(DOCKER_IMAGE):$(VERSION) . $Q docker build --build-arg BUILD_TAGS=$(build_tags) -t $(DOCKER_IMAGE):$(VERSION) .
.PHONY: build .PHONY: build
build: build_tags_actual := $(shell scripts/process_build_tags.sh $(build_tags))
build: authors build: authors
@echo "Building..." @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 .PHONY: tags
tags: tags:
@@ -117,20 +119,26 @@ format: $(GOPATH)/bin/goimports
$Q find . -iname \*.go | grep -v \ $Q find . -iname \*.go | grep -v \
-e "^$$" $(addprefix -e ,$(IGNORED_PACKAGES)) | xargs goimports -w -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. # 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". # 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. # MODE must be set to one of "dev" (default), "delete" or "run", and is used as the skaffold command to be run.
.PHONY: skaffold .PHONY: skaffold
skaffold: MODE ?= dev skaffold: MODE ?= dev
skaffold: PROFILE := local 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: skaffold-validate skaffold-build
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 $(MODE) \ @skaffold $(MODE) \
-f $(PWD)/hack/skaffold/virtual-kubelet/skaffold.yml \ -f $(PWD)/hack/skaffold/virtual-kubelet/skaffold.yml \
-p $(PROFILE) -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. 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.`, This allows users to schedule kubernetes workloads on nodes that aren't running Kubernetes.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
initConfig()
defer rootContextCancel() defer rootContextCancel()
vk := vkubelet.New(vkubelet.Config{ vk := vkubelet.New(vkubelet.Config{
@@ -167,8 +169,6 @@ func init() {
log.L = logruslogger.FromLogrus(logrus.NewEntry(logrus.StandardLogger())) log.L = logruslogger.FromLogrus(logrus.NewEntry(logrus.StandardLogger()))
trace.T = opencensus.Adapter{} trace.T = opencensus.Adapter{}
cobra.OnInitialize(initConfig)
// read default node name from environment variable. // read default node name from environment variable.
// it can be overwritten by cli flags if specified. // it can be overwritten by cli flags if specified.
defaultNodeName := os.Getenv("DEFAULT_NODE_NAME") defaultNodeName := os.Getenv("DEFAULT_NODE_NAME")

View File

@@ -27,7 +27,7 @@ var versionCmd = &cobra.Command{
Short: "Show the version of the program", Short: "Show the version of the program",
Long: `Show the version of the program`, Long: `Show the version of the program`,
Run: func(cmd *cobra.Command, args []string) { 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 package register

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,8 @@
package register package register
import ( import (
"sort"
"github.com/cpuguy83/strongerrors" "github.com/cpuguy83/strongerrors"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/virtual-kubelet/virtual-kubelet/manager" "github.com/virtual-kubelet/virtual-kubelet/manager"
@@ -30,6 +32,22 @@ func GetProvider(name string, cfg InitConfig) (providers.Provider, error) {
return f(cfg) 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) { func register(name string, f initFunc) {
providerInits[name] = f 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[@]}"