more k8s stuff

This commit is contained in:
dhaval055
2023-09-29 18:14:06 +00:00
parent 288b8afab9
commit 7e0a73d007
19 changed files with 1199 additions and 320 deletions
+204 -57
View File
@@ -33,6 +33,15 @@ import (
"net/http"
"os"
"strings"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"time"
// "k8s.io/client-go/tools/clientcmd"
// "k8s.io/client-go/util/homedir"
)
// Parses a directory with a Dockerfile into a tar for Docker images..
@@ -318,70 +327,208 @@ func buildImageMemory(fs billy.Filesystem, tags []string, dockerfileFolder strin
return nil
}
func getK8sClient() (*kubernetes.Clientset, error) {
config, err := rest.InClusterConfig()
if err != nil {
return nil, fmt.Errorf("[ERROR] failed to get in-cluster config: %v", err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("[ERROR] failed to create Kubernetes client: %v", err)
}
return clientset, nil
}
func deleteJob(client *kubernetes.Clientset, jobName, namespace string) error {
deletePolicy := metav1.DeletePropagationForeground
return client.BatchV1().Jobs(namespace).Delete(context.TODO(), jobName, metav1.DeleteOptions{
PropagationPolicy: &deletePolicy,
})
}
func buildImage(tags []string, dockerfileFolder string) error {
ctx := context.Background()
client, err := client.NewEnvClient()
if err != nil {
log.Printf("Unable to create docker client: %s", err)
return err
isKubernetes := false
if os.Getenv("IS_KUBERNETES") == "true" {
isKubernetes = true
}
log.Printf("[INFO] Docker Tags: %s", tags)
dockerfileSplit := strings.Split(dockerfileFolder, "/")
if isKubernetes {
log.Printf("K8S ###################")
log.Print("dockerfileFolder: ", dockerfileFolder)
log.Print("tags: ", tags)
log.Print("only tag: ", tags[1])
// Create a buffer
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
defer tw.Close()
baseDir := strings.Join(dockerfileSplit[0:len(dockerfileSplit)-1], "/")
// Builds the entire folder into buf
err = getParsedTar(tw, baseDir, "")
if err != nil {
log.Printf("Tar issue: %s", err)
}
dockerFileTarReader := bytes.NewReader(buf.Bytes())
buildOptions := types.ImageBuildOptions{
Remove: true,
Tags: tags,
BuildArgs: map[string]*string{},
}
//NetworkMode: "host",
httpProxy := os.Getenv("HTTP_PROXY")
if len(httpProxy) > 0 {
buildOptions.BuildArgs["HTTP_PROXY"] = &httpProxy
}
httpsProxy := os.Getenv("HTTPS_PROXY")
if len(httpProxy) > 0 {
buildOptions.BuildArgs["https_proxy"] = &httpsProxy
}
// Build the actual image
imageBuildResponse, err := client.ImageBuild(
ctx,
dockerFileTarReader,
buildOptions,
)
if err != nil {
return err
}
// Read the STDOUT from the build process
defer imageBuildResponse.Body.Close()
buildBuf := new(strings.Builder)
_, err = io.Copy(buildBuf, imageBuildResponse.Body)
if err != nil {
return err
} else {
if strings.Contains(buildBuf.String(), "errorDetail") {
log.Printf("[ERROR] Docker build:\n%s\nERROR ABOVE: Trying to pull tags from: %s", buildBuf.String(), strings.Join(tags, "\n"))
return errors.New(fmt.Sprintf("Failed building %s. Check backend logs for details. Most likely means you have an old version of Docker.", strings.Join(tags, ",")))
registryName := ""
if len(os.Getenv("REGISTRY_URL")) > 0 {
registryName = os.Getenv("REGISTRY_URL")
}
log.Printf("[INFO] registry name: %s", registryName)
contextDir := strings.Replace(dockerfileFolder, "Dockerfile", "", -1)
contextDir = "/app/" + contextDir
log.Print("contextDir: ", contextDir)
dockerFile := "./Dockerfile"
client, err := getK8sClient()
if err != nil {
fmt.Printf("Unable to authencticate : %v\n", err)
return err
}
job := &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "shuffle-app-builder",
},
Spec: batchv1.JobSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "kaniko",
Image: "gcr.io/kaniko-project/executor:latest",
Args: []string{
"--verbosity=debug",
"--dockerfile=" + dockerFile,
"--context=dir://" + contextDir,
"--skip-tls-verify",
"--destination=" + registryName + "/" + tags[1],
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "kaniko-workspace",
MountPath: "/app/generated",
},
},
},
},
NodeSelector: map[string]string{
"node": "master",
},
RestartPolicy: corev1.RestartPolicyNever,
Volumes: []corev1.Volume{
{
Name: "kaniko-workspace",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: "backend-apps-claim",
},
},
},
},
},
},
},
}
createdJob, err := client.BatchV1().Jobs("shuffle").Create(context.TODO(), job, metav1.CreateOptions{})
if err != nil {
log.Printf("Failed to start image builder job: %s", err)
return err
}
timeout := time.After(5 * time.Minute)
tick := time.Tick(5 * time.Second)
for {
select {
case <-timeout:
return fmt.Errorf("job didn't complete within the expected time")
case <-tick:
currentJob, err := client.BatchV1().Jobs("shuffle").Get(context.TODO(), createdJob.Name, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("[ERROR] failed to fetch %s status: %v", createdJob.Name, err)
}
if currentJob.Status.Succeeded > 0 {
log.Printf("[INFO] Job %s completed successfully!", createdJob.Name)
log.Printf("[INFO] Cleaning up the job %s", createdJob.Name)
err := deleteJob(client, createdJob.Name, "shuffle")
if err != nil {
return fmt.Errorf("[ERROR] failed deleting job %s with error: %s", createdJob.Name, err)
}
log.Println("Job deleted successfully!")
return nil
} else if currentJob.Status.Failed > 0 {
log.Printf("[ERROR] %s job failed with error: %s", createdJob.Name, err)
err := deleteJob(client, createdJob.Name, "shuffle")
if err != nil {
return fmt.Errorf("[ERROR] failed deleting job %s with error: %s", createdJob.Name, err)
}
}
}
}
} else {
//docker part here
}
// ctx := context.Background()
// client, err := client.NewEnvClient()
// if err != nil {
// log.Printf("Unable to create docker client: %s", err)
// return err
// }
// log.Printf("[INFO] Docker Tags: %s", tags)
// dockerfileSplit := strings.Split(dockerfileFolder, "/")
// // Create a buffer
// buf := new(bytes.Buffer)
// tw := tar.NewWriter(buf)
// defer tw.Close()
// baseDir := strings.Join(dockerfileSplit[0:len(dockerfileSplit)-1], "/")
// // Builds the entire folder into buf
// err = getParsedTar(tw, baseDir, "")
// if err != nil {
// log.Printf("Tar issue: %s", err)
// }
// dockerFileTarReader := bytes.NewReader(buf.Bytes())
// buildOptions := types.ImageBuildOptions{
// Remove: true,
// Tags: tags,
// BuildArgs: map[string]*string{},
// }
// //NetworkMode: "host",
// httpProxy := os.Getenv("HTTP_PROXY")
// if len(httpProxy) > 0 {
// buildOptions.BuildArgs["HTTP_PROXY"] = &httpProxy
// }
// httpsProxy := os.Getenv("HTTPS_PROXY")
// if len(httpProxy) > 0 {
// buildOptions.BuildArgs["https_proxy"] = &httpsProxy
// }
// // Build the actual image
// imageBuildResponse, err := client.ImageBuild(
// ctx,
// dockerFileTarReader,
// buildOptions,
// )
// if err != nil {
// return err
// }
// // Read the STDOUT from the build process
// defer imageBuildResponse.Body.Close()
// buildBuf := new(strings.Builder)
// _, err = io.Copy(buildBuf, imageBuildResponse.Body)
// if err != nil {
// return err
// } else {
// if strings.Contains(buildBuf.String(), "errorDetail") {
// log.Printf("[ERROR] Docker build:\n%s\nERROR ABOVE: Trying to pull tags from: %s", buildBuf.String(), strings.Join(tags, "\n"))
// return errors.New(fmt.Sprintf("Failed building %s. Check backend logs for details. Most likely means you have an old version of Docker.", strings.Join(tags, ",")))
// }
// }
return nil
}