mirror of https://github.com/k3s-io/k3s
Remove unused helpers in apiclient.go and deploy the dummy deployment from a yaml spec
parent
183f71d57a
commit
e261627260
|
@ -17,31 +17,30 @@ limitations under the License.
|
|||
package master
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kuberuntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"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"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
)
|
||||
|
||||
const apiCallRetryInterval = 500 * time.Millisecond
|
||||
|
||||
func CreateClientFromFile(path string) (*clientset.Clientset, error) {
|
||||
adminKubeconfig, err := clientcmd.LoadFromFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err)
|
||||
}
|
||||
adminClientConfig, err := clientcmd.NewDefaultClientConfig(
|
||||
*adminKubeconfig,
|
||||
&clientcmd.ConfigOverrides{},
|
||||
).ClientConfig()
|
||||
adminClientConfig, err := clientcmd.NewDefaultClientConfig(*adminKubeconfig, &clientcmd.ConfigOverrides{}).ClientConfig()
|
||||
if err != nil {
|
||||
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")
|
||||
start := time.Now()
|
||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||
nodeList, err := client.Nodes().List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
fmt.Println("[apiclient] Temporarily unable to list nodes (will retry)")
|
||||
|
@ -83,21 +82,16 @@ func CreateClientAndWaitForAPI(file string) (*clientset.Clientset, error) {
|
|||
return true, nil
|
||||
})
|
||||
|
||||
createDummyDeployment(client)
|
||||
if err := createAndWaitForADummyDeployment(client); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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) {
|
||||
start := time.Now()
|
||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||
// TODO: use /healthz API instead of this
|
||||
cs, err := client.ComponentStatuses().List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
|
@ -125,76 +119,31 @@ func WaitForAPI(client *clientset.Clientset) {
|
|||
})
|
||||
}
|
||||
|
||||
func NewDaemonSet(daemonName string, podSpec v1.PodSpec) *extensions.DaemonSet {
|
||||
l := standardLabels(daemonName)
|
||||
return &extensions.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: daemonName},
|
||||
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"),
|
||||
}},
|
||||
func createAndWaitForADummyDeployment(client *clientset.Clientset) error {
|
||||
dummyDeploymentBytes, err := kubeadmutil.ParseTemplate(DummyDeployment, struct{ ImageRepository, Arch string }{
|
||||
ImageRepository: kubeadmapi.GlobalEnvParams.RepositoryPrefix,
|
||||
Arch: runtime.GOARCH,
|
||||
})
|
||||
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
|
||||
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)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
|
||||
d, err := client.Extensions().Deployments(metav1.NamespaceSystem).Get("dummy", metav1.GetOptions{})
|
||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||
d, err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Get("dummy", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("[apiclient] Failed to get test deployment [%v] (will retry)\n", err)
|
||||
return false, nil
|
||||
|
@ -208,7 +157,8 @@ func createDummyDeployment(client *clientset.Clientset) {
|
|||
fmt.Println("[apiclient] Test deployment succeeded")
|
||||
|
||||
// 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)
|
||||
}
|
||||
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"],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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