0

I am using a handlerfunc k8sHandler(w http.ResponseWriter, r *http.Request) , which has a for loop inside it, basically it loops over a list of hosts in a file and runs a script on each host. So, I wanted to print the output in the browser when it connects to each host like.. currently I using fmt.Fprintf(w, "Connecting to host", host)

Connecting to host host1

Connecting to host host2

func k8sHandler(w http.ResponseWriter, r *http.Request) {
    user := "root"
    key_path := "/home/mrawat/.ssh/id_rsa"
    f, err := os.Open("/home/mrawat/golang/k8s-main/files/servers_list.txt")
    if err != nil {
        log.Fatal(err)
    }
    // remember to close the file at the end of the program
    defer f.Close()

    // read the file line by line using scanner
    scanner := bufio.NewScanner(f)

    for scanner.Scan() {
        // do something with a line

        host := fmt.Sprintf("%s\n", scanner.Text())
        host = removeSpace(host)
        fmt.Fprintf(w, "Connecting to host", host)
        w.(http.Flusher).Flush()
        display(w, "upload", "Upload successful.")
        privPEM, err := ioutil.ReadFile("/home/mrawat/.ssh/id_rsa")
        sshConf, err := scp.NewSSHConfigFromPrivateKey("root", privPEM)


        port := ":22"
        hostname := host + port
        fmt.Println(hostname)
        scpClient, err := scp.NewClient(hostname, sshConf, &scp.ClientOption{})

        defer scpClient.Close()

        // Do the file transfer without timeout/context
        err = scpClient.CopyFileToRemote("/home/mrawat/golang/k8s-main/k8s_bash.sh", "/tmp/k8s_bash.sh", &scp.FileTransferOption{})

        // Do the file copy with timeout, context and file properties preserved.
        // Note that the context and timeout will both take effect.

        fo := &scp.FileTransferOption{
            Timeout:      30 * time.Second,
            PreserveProp: true,
        }
        err = scpClient.CopyFileToRemote("/path/to/local/file", "/path/at/remote", fo)

        name, err := os.Hostname()
        if err != nil {
            panic(err)
        }

        key_path = "/home/mrawat/.ssh/id_rsa"

        client, session, err := connectToHost(user, host, key_path)
        if err != nil {
            panic(err)
        }
        out, err := session.CombinedOutput("/bin/bash /tmp/k8s_bash.sh > /tmp/k8s-config.yaml")
        if err != nil {
            panic(err)
        }
        fmt.Println(string(out))
        //display_k8sup()
        client.Close()
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
}

Likewise.. it is printing the above output but only once the complete loop is completed. It is not printing it in runtime one after another.. Is there a way to print the output in runtime..??

mkopriva
  • 35,176
  • 4
  • 57
  • 71
Manu
  • 11
  • 2
  • 3
    Try flushing the writer after each `Fprintf`, e.g. `w.(http.Flusher).Flush()`. Docs https://pkg.go.dev/net/http@go1.17.3#Flusher. How it's all rendered also depends on the client though, so flushing may not be the only thing you'll need to do. – mkopriva Dec 01 '21 at 10:31
  • @mkopriva I have updated my code in the question along with flush but it didn't help.. Do you see a problem there? – Manu Dec 01 '21 at 11:13
  • 1
    Take a look at the answer in the linked duplicate, read it properly and take note of what headers need to be set prior to writing the first message. – mkopriva Dec 01 '21 at 11:19
  • I appreciate your response, though flushing is not helping. I will continue to troubleshoot the problem.. – Manu Dec 01 '21 at 11:58
  • 1
    @mkopriva Thanks for sharing the information. It started working now. – Manu Dec 01 '21 at 12:19

0 Answers0