2019-11-16 14:39:47 +00:00
|
|
|
package integration
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
batchv1 "k8s.io/api/batch/v1"
|
|
|
|
apiv1 "k8s.io/api/core/v1"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
yaml "k8s.io/apimachinery/pkg/util/yaml"
|
|
|
|
"k8s.io/client-go/kubernetes"
|
|
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
|
|
"sigs.k8s.io/kind/pkg/cluster"
|
|
|
|
"sigs.k8s.io/kind/pkg/cluster/create"
|
|
|
|
)
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
func runWithKind(ctx *cluster.Context, clientset *kubernetes.Clientset, jobName, kubebenchYAML, kubebenchImg string, timeout time.Duration) (string, error) {
|
|
|
|
err := deployJob(clientset, kubebenchYAML, kubebenchImg)
|
2019-11-16 14:39:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
p, err := findPodForJob(clientset, jobName, timeout)
|
2019-11-16 14:39:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
output := getPodLogs(clientset, p)
|
2019-11-16 14:39:47 +00:00
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
err = clientset.BatchV1().Jobs(apiv1.NamespaceDefault).Delete(jobName, nil)
|
2019-11-16 14:39:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
return output, nil
|
|
|
|
}
|
2019-11-16 14:39:47 +00:00
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
func setupCluster(clusterName, kindCfg string, duration time.Duration) (*cluster.Context, error) {
|
|
|
|
options := create.WithConfigFile(kindCfg)
|
|
|
|
toptions := create.WaitForReady(duration)
|
|
|
|
ctx := cluster.NewContext(clusterName)
|
|
|
|
if err := ctx.Create(options, toptions); err != nil {
|
|
|
|
return nil, err
|
2019-11-16 14:39:47 +00:00
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
return ctx, nil
|
2019-11-16 14:39:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getClientSet(configPath string) (*kubernetes.Clientset, error) {
|
|
|
|
config, err := clientcmd.BuildConfigFromFlags("", configPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
clientset, err := kubernetes.NewForConfig(config)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return clientset, nil
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
func deployJob(clientset *kubernetes.Clientset, kubebenchYAML, kubebenchImg string) error {
|
|
|
|
jobYAML, err := ioutil.ReadFile(kubebenchYAML)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(jobYAML), len(jobYAML))
|
|
|
|
job := &batchv1.Job{}
|
|
|
|
if err := decoder.Decode(job); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
job.Spec.Template.Spec.Containers[0].Image = kubebenchImg
|
|
|
|
|
|
|
|
_, err = clientset.BatchV1().Jobs(apiv1.NamespaceDefault).Create(job)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func findPodForJob(clientset *kubernetes.Clientset, jobName string, duration time.Duration) (*apiv1.Pod, error) {
|
2019-11-16 14:39:47 +00:00
|
|
|
failedPods := make(map[string]struct{})
|
2020-01-09 14:57:40 +00:00
|
|
|
selector := fmt.Sprintf("job-name=%s", jobName)
|
|
|
|
timeout := time.After(duration)
|
2019-11-16 14:39:47 +00:00
|
|
|
for {
|
2020-01-09 14:57:40 +00:00
|
|
|
time.Sleep(3 * time.Second)
|
2019-11-16 14:39:47 +00:00
|
|
|
podfailed:
|
|
|
|
select {
|
|
|
|
case <-timeout:
|
2020-01-09 14:57:40 +00:00
|
|
|
return nil, fmt.Errorf("podList - timed out: no Pod found for Job %s", jobName)
|
2019-11-16 14:39:47 +00:00
|
|
|
default:
|
2020-01-09 14:57:40 +00:00
|
|
|
pods, err := clientset.CoreV1().Pods(apiv1.NamespaceDefault).List(metav1.ListOptions{
|
|
|
|
LabelSelector: selector,
|
|
|
|
})
|
2019-11-16 14:39:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
fmt.Printf("Found (%d) pods\n", len(pods.Items))
|
|
|
|
for _, cp := range pods.Items {
|
|
|
|
if _, found := failedPods[cp.Name]; found {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
if strings.HasPrefix(cp.Name, jobName) {
|
2019-11-16 14:39:47 +00:00
|
|
|
fmt.Printf("pod (%s) - %#v\n", cp.Name, cp.Status.Phase)
|
|
|
|
if cp.Status.Phase == apiv1.PodSucceeded {
|
|
|
|
return &cp, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if cp.Status.Phase == apiv1.PodFailed {
|
|
|
|
fmt.Printf("pod (%s) - %s - retrying...\n", cp.Name, cp.Status.Phase)
|
|
|
|
failedPods[cp.Name] = struct{}{}
|
|
|
|
break podfailed
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:57:40 +00:00
|
|
|
return nil, fmt.Errorf("no Pod found for Job %q", jobName)
|
2019-11-16 14:39:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getPodLogs(clientset *kubernetes.Clientset, pod *apiv1.Pod) string {
|
|
|
|
podLogOpts := corev1.PodLogOptions{}
|
|
|
|
req := clientset.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &podLogOpts)
|
|
|
|
podLogs, err := req.Stream()
|
|
|
|
if err != nil {
|
|
|
|
return "getPodLogs - error in opening stream"
|
|
|
|
}
|
|
|
|
defer podLogs.Close()
|
|
|
|
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
_, err = io.Copy(buf, podLogs)
|
|
|
|
if err != nil {
|
|
|
|
return "getPodLogs - error in copy information from podLogs to buf"
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf.String()
|
|
|
|
}
|