<commit_before>package utils

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"syscall"

	"github.com/fatih/color"
)

var (
	srv *http.Server
)

func StartServer() *http.Server {
	srv = &http.Server{Addr: ":8000"}
	color.Green("File server listening at: 0.0.0.0:8000")

	http.Handle("/", http.FileServer(http.Dir("./package")))

	go func() {
		if err := srv.ListenAndServe(); err != nil {
			// cannot panic, because this probably is an intentional close
			log.Printf("Httpserver: ListenAndServe() error: %s", err)
		}
	}()

	// returning reference so caller can call Shutdown()
	return srv
}

func RunSetup(script string, ch chan int, args ...string) {
	//cmd := exec.Command("bash", "-s", script)
	cmd := exec.Command(script, args...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}

	defer stdout.Close()
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	if strings.Contains(script, "master") {
		go saveLog(stdout, true)
	} else {
		go saveLog(stdout, false)
	}

	if err := cmd.Wait(); err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			// The program has exited with an exit code != 0
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				log.Printf("Exit Status: %d", status.ExitStatus())
			}
		} else {
			log.Fatalf("cmd.Wait: %v", err)
		}
		ch <- 1
	} else {
		ch <- 0
	}
}

func matchToken(buf []byte) {
	if strings.Contains(string(buf), "kubeadm join --token") {

		os.Remove("./k8s.token")

		re := regexp.MustCompile("kubeadm join --token [0-9a-z.]*")
		result := re.Find(buf)

		//Get the token string
		token := strings.Split(string(result), " ")[3]

		ioutil.WriteFile("./k8s.token", []byte(token), os.ModeAppend)
		color.Green("%sMaster token %s saved into .k8s.token file.", CheckSymbol)
	}
}

func saveLog(stdout io.ReadCloser, saveToken bool) {
	buf := make([]byte, 1024)

	fd, _ := os.OpenFile("install.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)

	defer fd.Close()

	for {
		var n int
		n, err := stdout.Read(buf)

		if err != nil {
			log.Println("End of output...")
			break
		}

		if saveToken {
			matchToken(buf)
		}

		fmt.Println(string(buf))
		fd.WriteString(string(buf[:n]))
	}
}

func SetupDocker() bool {
	color.Blue("Start to install docker engine...\r\n\r\n")
	ch := make(chan int)

	go RunSetup("./docker.sh", ch)
	if <-ch == 1 {
		color.Red("%sFailed to install docker engine...\r\n\r\n", CrossSymbol)
		return false
	}

	color.Green("%sDocker engine installed...\r\n\r\n", CheckSymbol)
	return true
}

func SetupMaster() bool {
	color.Blue("Start to initialize Kubernetes master node...\r\n\r\n")
	ch := make(chan int)

	go RunSetup("./master.sh", ch, "master")
	if <-ch == 1 {
		color.Red("%sFailed to initialize Kubernetes master node...\r\n\r\n", CrossSymbol)
		return false
	}

	color.Green("%sKubernetes master node initialized...\r\n\r\n", CheckSymbol)
	return true
}<commit_msg>optimize setup process<commit_after>package utils

import (
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"syscall"

	"github.com/fatih/color"
)

var (
	srv *http.Server
)

func StartServer() *http.Server {
	srv = &http.Server{Addr: ":8000"}
	http.Handle("/", http.FileServer(http.Dir("./package")))

	go func() {
		if err := srv.ListenAndServe(); err != nil {
			// cannot panic, because this probably is an intentional close
			log.Printf("Httpserver: ListenAndServe() error: %s", err)
		}

		color.Blue("%sHTTP file server listening at: 0.0.0.0:8000", CheckSymbol)
	}()

	return srv
}

func RunSetup(script string, ch chan int, args ...string) {
	//cmd := exec.Command("bash", "-s", script)
	cmd := exec.Command(script, args...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}

	defer stdout.Close()
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	if strings.Contains(script, "master") {
		go saveLog(stdout, true)
	} else {
		go saveLog(stdout, false)
	}

	if err := cmd.Wait(); err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			// The program has exited with an exit code != 0
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				log.Printf("Exit Status: %d", status.ExitStatus())
			}
		} else {
			log.Fatalf("cmd.Wait: %v", err)
		}
		ch <- 1
	} else {
		ch <- 0
	}
}

func matchToken(buf []byte) {
	if strings.Contains(string(buf), "kubeadm join --token") {
		re := regexp.MustCompile("kubeadm join --token [0-9a-z.]*")
		result := re.Find(buf)

		//Get the token string
		token := strings.Split(string(result), " ")[3]
		ioutil.WriteFile("./.k8s-token", []byte(token), os.ModeAppend)
		color.Green("%sMaster token %s saved into .k8s.token file.", CheckSymbol, token)
	}
}

func outputProgress(buf []byte) {
	re := regexp.MustCompile("KUBEKIT_OUTPUT .*.")
	results := re.FindAll(buf, -1)

	if results != nil {
		for _, r := range results {
			//Get the token string
			output := strings.Replace(string(r), "KUBEKIT_OUTPUT ", "", 1)
			color.Blue(output)
		}
	}
}

func saveLog(stdout io.ReadCloser, saveToken bool) {

	fd, _ := os.OpenFile("install.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)

	defer fd.Close()

	for {
		var n int
		buf := make([]byte, 1024)
		n, err := stdout.Read(buf)

		if err != nil {
			//End of output
			break
		}

		//Output the install progress
		if strings.Contains(string(buf), "KUBEKIT_OUTPUT") {
			outputProgress(buf)
		}

		if saveToken {
			matchToken(buf)
		}

		fd.WriteString(string(buf[:n]))
	}
}

func SetupDocker() bool {
	color.Blue("Start to install docker engine...\r\n\r\n")
	ch := make(chan int)

	go RunSetup("./package/docker.sh", ch)
	if <-ch == 1 {
		color.Red("%sFailed to install docker engine...\r\n\r\n", CrossSymbol)
		return false
	}

	color.Green("%sDocker engine installed...\r\n\r\n", CheckSymbol)
	return true
}

func SetupMaster() bool {
	color.Blue("Start to initialize Kubernetes master node...\r\n\r\n")
	ch := make(chan int)

	go RunSetup("./package/master.sh", ch, "master")
	if <-ch == 1 {
		color.Red("%sFailed to initialize Kubernetes master node...\r\n\r\n", CrossSymbol)
		return false
	}

	color.Green("%sKubernetes master node initialized...\r\n\r\n", CheckSymbol)
	return true
}
{'fraction_non_alphanumeric': 0.18146530810286268, 'fraction_numerical': 0.010189228529839884, 'mean_word_length': 3.3366058906030855, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5345800', 'n_tokens_mistral': 2559, 'n_tokens_neox': 2319, 'n_words': 569}