mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 09:22:44 +00:00
Remove unused helpers in apiclient.go and deploy the dummy deployment from a yaml spec
This commit is contained in:
parent
183f71d57a
commit
e261627260
@ -17,31 +17,30 @@ limitations under the License.
|
|||||||
package master
|
package master
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
kuberuntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
)
|
)
|
||||||
|
|
||||||
const apiCallRetryInterval = 500 * time.Millisecond
|
|
||||||
|
|
||||||
func CreateClientFromFile(path string) (*clientset.Clientset, error) {
|
func CreateClientFromFile(path string) (*clientset.Clientset, error) {
|
||||||
adminKubeconfig, err := clientcmd.LoadFromFile(path)
|
adminKubeconfig, err := clientcmd.LoadFromFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err)
|
return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err)
|
||||||
}
|
}
|
||||||
adminClientConfig, err := clientcmd.NewDefaultClientConfig(
|
adminClientConfig, err := clientcmd.NewDefaultClientConfig(*adminKubeconfig, &clientcmd.ConfigOverrides{}).ClientConfig()
|
||||||
*adminKubeconfig,
|
|
||||||
&clientcmd.ConfigOverrides{},
|
|
||||||
).ClientConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create API client configuration [%v]", err)
|
return nil, fmt.Errorf("failed to create API client configuration [%v]", err)
|
||||||
}
|
}
|
||||||
@ -64,7 +63,7 @@ func CreateClientAndWaitForAPI(file string) (*clientset.Clientset, error) {
|
|||||||
|
|
||||||
fmt.Println("[apiclient] Waiting for at least one node to register and become ready")
|
fmt.Println("[apiclient] Waiting for at least one node to register and become ready")
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||||
nodeList, err := client.Nodes().List(metav1.ListOptions{})
|
nodeList, err := client.Nodes().List(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[apiclient] Temporarily unable to list nodes (will retry)")
|
fmt.Println("[apiclient] Temporarily unable to list nodes (will retry)")
|
||||||
@ -83,21 +82,16 @@ func CreateClientAndWaitForAPI(file string) (*clientset.Clientset, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
createDummyDeployment(client)
|
if err := createAndWaitForADummyDeployment(client); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func standardLabels(n string) map[string]string {
|
|
||||||
return map[string]string{
|
|
||||||
"component": n, "name": n, "k8s-app": n,
|
|
||||||
"kubernetes.io/cluster-service": "true", "tier": "node",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WaitForAPI(client *clientset.Clientset) {
|
func WaitForAPI(client *clientset.Clientset) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||||
// TODO: use /healthz API instead of this
|
// TODO: use /healthz API instead of this
|
||||||
cs, err := client.ComponentStatuses().List(metav1.ListOptions{})
|
cs, err := client.ComponentStatuses().List(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -125,76 +119,31 @@ func WaitForAPI(client *clientset.Clientset) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDaemonSet(daemonName string, podSpec v1.PodSpec) *extensions.DaemonSet {
|
func createAndWaitForADummyDeployment(client *clientset.Clientset) error {
|
||||||
l := standardLabels(daemonName)
|
dummyDeploymentBytes, err := kubeadmutil.ParseTemplate(DummyDeployment, struct{ ImageRepository, Arch string }{
|
||||||
return &extensions.DaemonSet{
|
ImageRepository: kubeadmapi.GlobalEnvParams.RepositoryPrefix,
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: daemonName},
|
Arch: runtime.GOARCH,
|
||||||
Spec: extensions.DaemonSetSpec{
|
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: l},
|
|
||||||
Template: v1.PodTemplateSpec{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Labels: l},
|
|
||||||
Spec: podSpec,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewService(serviceName string, spec v1.ServiceSpec) *v1.Service {
|
|
||||||
l := standardLabels(serviceName)
|
|
||||||
return &v1.Service{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: serviceName,
|
|
||||||
Labels: l,
|
|
||||||
},
|
|
||||||
Spec: spec,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDeployment(deploymentName string, replicas int32, podSpec v1.PodSpec) *extensions.Deployment {
|
|
||||||
l := standardLabels(deploymentName)
|
|
||||||
return &extensions.Deployment{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: deploymentName},
|
|
||||||
Spec: extensions.DeploymentSpec{
|
|
||||||
Replicas: &replicas,
|
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: l},
|
|
||||||
Template: v1.PodTemplateSpec{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Labels: l},
|
|
||||||
Spec: podSpec,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetMasterTaintTolerations(meta *metav1.ObjectMeta) {
|
|
||||||
tolerationsAnnotation, _ := json.Marshal([]v1.Toleration{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
|
|
||||||
if meta.Annotations == nil {
|
|
||||||
meta.Annotations = map[string]string{}
|
|
||||||
}
|
|
||||||
meta.Annotations[v1.TolerationsAnnotationKey] = string(tolerationsAnnotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createDummyDeployment(client *clientset.Clientset) {
|
|
||||||
fmt.Println("[apiclient] Creating a test deployment")
|
|
||||||
dummyDeployment := NewDeployment("dummy", 1, v1.PodSpec{
|
|
||||||
HostNetwork: true,
|
|
||||||
SecurityContext: &v1.PodSecurityContext{},
|
|
||||||
Containers: []v1.Container{{
|
|
||||||
Name: "dummy",
|
|
||||||
Image: images.GetAddonImage("pause"),
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error when parsing dummy deployment template: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
dummyDeployment := &extensions.Deployment{}
|
||||||
|
if err := kuberuntime.DecodeInto(api.Codecs.UniversalDecoder(), dummyDeploymentBytes, dummyDeployment); err != nil {
|
||||||
|
return fmt.Errorf("unable to decode dummy deployment %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||||
// TODO: we should check the error, as some cases may be fatal
|
// TODO: we should check the error, as some cases may be fatal
|
||||||
if _, err := client.Extensions().Deployments(metav1.NamespaceSystem).Create(dummyDeployment); err != nil {
|
if _, err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Create(dummyDeployment); err != nil {
|
||||||
fmt.Printf("[apiclient] Failed to create test deployment [%v] (will retry)\n", err)
|
fmt.Printf("[apiclient] Failed to create test deployment [%v] (will retry)\n", err)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||||
d, err := client.Extensions().Deployments(metav1.NamespaceSystem).Get("dummy", metav1.GetOptions{})
|
d, err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Get("dummy", metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[apiclient] Failed to get test deployment [%v] (will retry)\n", err)
|
fmt.Printf("[apiclient] Failed to get test deployment [%v] (will retry)\n", err)
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -208,7 +157,8 @@ func createDummyDeployment(client *clientset.Clientset) {
|
|||||||
fmt.Println("[apiclient] Test deployment succeeded")
|
fmt.Println("[apiclient] Test deployment succeeded")
|
||||||
|
|
||||||
// TODO: In the future, make sure the ReplicaSet and Pod are garbage collected
|
// TODO: In the future, make sure the ReplicaSet and Pod are garbage collected
|
||||||
if err := client.Extensions().Deployments(metav1.NamespaceSystem).Delete("dummy", &metav1.DeleteOptions{}); err != nil {
|
if err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Delete("dummy", &metav1.DeleteOptions{}); err != nil {
|
||||||
fmt.Printf("[apiclient] Failed to delete test deployment [%v] (will ignore)\n", err)
|
fmt.Printf("[apiclient] Failed to delete test deployment [%v] (will ignore)\n", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2016 The Kubernetes Authors.
|
|
||||||
|
|
||||||
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 master
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStandardLabels(t *testing.T) {
|
|
||||||
var tests = []struct {
|
|
||||||
n string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
n: "foo",
|
|
||||||
expected: "foo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
n: "bar",
|
|
||||||
expected: "bar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rt := range tests {
|
|
||||||
actual := standardLabels(rt.n)
|
|
||||||
if actual["component"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed standardLabels:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual["component"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual["name"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed standardLabels:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual["name"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual["k8s-app"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed standardLabels:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual["k8s-app"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewDaemonSet(t *testing.T) {
|
|
||||||
var tests = []struct {
|
|
||||||
dn string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
dn: "foo",
|
|
||||||
expected: "foo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dn: "bar",
|
|
||||||
expected: "bar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rt := range tests {
|
|
||||||
p := v1.PodSpec{}
|
|
||||||
actual := NewDaemonSet(rt.dn, p)
|
|
||||||
if actual.Spec.Selector.MatchLabels["k8s-app"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewDaemonSet:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.Spec.Selector.MatchLabels["k8s-app"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual.Spec.Selector.MatchLabels["component"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewDaemonSet:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.Spec.Selector.MatchLabels["component"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual.Spec.Selector.MatchLabels["name"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewDaemonSet:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.Spec.Selector.MatchLabels["name"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewService(t *testing.T) {
|
|
||||||
var tests = []struct {
|
|
||||||
dn string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
dn: "foo",
|
|
||||||
expected: "foo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dn: "bar",
|
|
||||||
expected: "bar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rt := range tests {
|
|
||||||
p := v1.ServiceSpec{}
|
|
||||||
actual := NewService(rt.dn, p)
|
|
||||||
if actual.ObjectMeta.Labels["k8s-app"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewService:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.ObjectMeta.Labels["k8s-app"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual.ObjectMeta.Labels["component"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewService:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.ObjectMeta.Labels["component"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual.ObjectMeta.Labels["name"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewService:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.ObjectMeta.Labels["name"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewDeployment(t *testing.T) {
|
|
||||||
var tests = []struct {
|
|
||||||
dn string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
dn: "foo",
|
|
||||||
expected: "foo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dn: "bar",
|
|
||||||
expected: "bar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rt := range tests {
|
|
||||||
p := v1.PodSpec{}
|
|
||||||
actual := NewDeployment(rt.dn, 1, p)
|
|
||||||
if actual.Spec.Selector.MatchLabels["k8s-app"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewDeployment:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.Spec.Selector.MatchLabels["k8s-app"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual.Spec.Selector.MatchLabels["component"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewDeployment:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.Spec.Selector.MatchLabels["component"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if actual.Spec.Selector.MatchLabels["name"] != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed NewDeployment:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual.Spec.Selector.MatchLabels["name"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
43
cmd/kubeadm/app/master/templates.go
Normal file
43
cmd/kubeadm/app/master/templates.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 master
|
||||||
|
|
||||||
|
const (
|
||||||
|
DummyDeployment = `
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dummy
|
||||||
|
name: dummy
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dummy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dummy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: {{ .ImageRepository }}/pause-{{ .Arch }}:3.0
|
||||||
|
name: dummy
|
||||||
|
hostNetwork: true
|
||||||
|
`
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user