mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-25 19:54:38 +00:00
Add ability to upload diagnostics to S3
Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
This commit is contained in:
parent
2121afb71d
commit
970bc31977
@ -2,16 +2,24 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
dockerSock = "/var/run/docker.sock"
|
dockerSock = "/var/run/docker.sock"
|
||||||
lgtm = "LGTM"
|
lgtm = "LGTM"
|
||||||
httpMagicPort = ":44554" // chosen arbitrarily due to IANA availability -- might change
|
httpMagicPort = ":44554" // chosen arbitrarily due to IANA availability -- might change
|
||||||
|
bucket = "editionsdiagnostics"
|
||||||
|
sessionIDField = "session"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -41,24 +49,103 @@ func (h HTTPDiagnosticListener) Listen() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
http.HandleFunc("/diagnose", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/diagnose", func(w http.ResponseWriter, r *http.Request) {
|
||||||
dir, err := ioutil.TempDir("", "diagnostics")
|
diagnosticsSessionID := r.FormValue(sessionIDField)
|
||||||
if err != nil {
|
|
||||||
log.Println("Error creating temp dir on diagnostic request:", err)
|
if diagnosticsSessionID == "" {
|
||||||
|
http.Error(w, "No 'session' field specified for diagnostics run", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := ioutil.TempFile(dir, "diagnostics")
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error creating temp file on diagnostic request:", err)
|
http.Error(w, "Error getting hostname:"+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tarWriter := tar.NewWriter(file)
|
// To keep URL cleaner
|
||||||
|
hostname = strings.Replace(hostname, ".", "-", -1)
|
||||||
|
|
||||||
Capture(tarWriter, cloudCaptures)
|
if _, err := w.Write([]byte("OK hostname=" + hostname + " session=" + diagnosticsSessionID + "\n")); err != nil {
|
||||||
|
http.Error(w, "Error writing: "+err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: upload written (and gzipped?) tar file to our S3
|
// Do the actual capture and uplaod to S3 in the background.
|
||||||
// bucket with specific path convention (per-user? by date?)
|
// No need to make caller sit and wait for the result. They
|
||||||
|
// probably have a lot of other things going on, like other
|
||||||
|
// servers to request diagnostics for.
|
||||||
|
//
|
||||||
|
// TODO(nathanleclaire): Potentially, endpoint to check the
|
||||||
|
// result of this capture and upload process as well.
|
||||||
|
go func() {
|
||||||
|
dir, err := ioutil.TempDir("", "diagnostics")
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error creating temp dir on diagnostic request:: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := ioutil.TempFile(dir, "diagnostics")
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error creating temp file on diagnostic request:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tarWriter := tar.NewWriter(file)
|
||||||
|
|
||||||
|
Capture(tarWriter, cloudCaptures)
|
||||||
|
|
||||||
|
if err := tarWriter.Close(); err != nil {
|
||||||
|
log.Println("Error closing archive writer: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
log.Println("Error closing file: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
readFile, err := os.Open(file.Name())
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error opening report file to upload: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer readFile.Close()
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
contentLength, err := io.Copy(buf, readFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error copying to buffer: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reportURI := fmt.Sprintf("https://%s.s3.amazonaws.com/%s-%s.tar", bucket, diagnosticsSessionID, hostname)
|
||||||
|
|
||||||
|
uploadReq, err := http.NewRequest("PUT", reportURI, buf)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error getting bucket request: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadReq.Header.Set("x-amz-acl", "bucket-owner-full-control")
|
||||||
|
uploadReq.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
|
||||||
|
uploadReq.Header.Set("Content-Length", strconv.Itoa(int(contentLength)))
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
|
||||||
|
if uploadResp, err := client.Do(uploadReq); err != nil {
|
||||||
|
log.Println("Error writing: ", err)
|
||||||
|
body, err := ioutil.ReadAll(uploadResp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error reading response body: ", err)
|
||||||
|
}
|
||||||
|
log.Println(string(body))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
log.Println("No error sending S3 request")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Diagnostics request finished")
|
||||||
|
}()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Start HTTP server to indicate general Docker health.
|
// Start HTTP server to indicate general Docker health.
|
||||||
|
Loading…
Reference in New Issue
Block a user