mirror of
https://github.com/nicksherron/bashhub-server.git
synced 2025-09-10 14:24:30 +08:00
cmd/transfer: recovery and retries for http requests
This commit is contained in:
parent
3d026eb239
commit
b5381b2eab
2 changed files with 69 additions and 43 deletions
|
@ -36,7 +36,7 @@ $ GO111MODULE=on go get -u github.com/nicksherron/bashhub-server
|
||||||
```
|
```
|
||||||
#### Releases
|
#### Releases
|
||||||
Binaries for various os and architectures can be found in [releases](https://github.com/nicksherron/bashhub-server/releases).
|
Binaries for various os and architectures can be found in [releases](https://github.com/nicksherron/bashhub-server/releases).
|
||||||
If your system is not listed just submit a issue requesting your os and architecture.
|
If your system is not listed just submit an issue requesting your os and architecture.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
```
|
```
|
||||||
|
@ -48,6 +48,7 @@ Usage:
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
help Help about any command
|
help Help about any command
|
||||||
|
transfer Transfer bashhub history from one server to another
|
||||||
version Print the version number and build info
|
version Print the version number and build info
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
|
109
cmd/transfer.go
109
cmd/transfer.go
|
@ -26,7 +26,6 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -43,7 +42,7 @@ type cList struct {
|
||||||
type commandsList []cList
|
type commandsList []cList
|
||||||
|
|
||||||
var (
|
var (
|
||||||
barTemplate = `{{string . "message"}}{{counters . }} {{bar . }} {{percent . }} {{speed . "%s inserts/sec" }}`
|
barTemplate = `{{string . "message" | green }}{{counters . }} {{bar . }} {{percent . }} {{speed . "%s inserts/sec" | green}}`
|
||||||
bar *pb.ProgressBar
|
bar *pb.ProgressBar
|
||||||
progress bool
|
progress bool
|
||||||
srcUser string
|
srcUser string
|
||||||
|
@ -60,9 +59,29 @@ var (
|
||||||
cmdList commandsList
|
cmdList commandsList
|
||||||
transferCmd = &cobra.Command{
|
transferCmd = &cobra.Command{
|
||||||
Use: "transfer",
|
Use: "transfer",
|
||||||
Short: "transfer bashhub history ",
|
Short: "Transfer bashhub history from one server to another",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmd.Flags().Parse(args)
|
cmd.Flags().Parse(args)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case srcUser == "":
|
||||||
|
_ = cmd.Usage()
|
||||||
|
fmt.Print("\n\n")
|
||||||
|
log.Fatal("--src-user can't be blank")
|
||||||
|
case srcPass == "":
|
||||||
|
_ = cmd.Usage()
|
||||||
|
fmt.Print("\n\n")
|
||||||
|
log.Fatal("--src-pass can't be blank")
|
||||||
|
case dstUser == "":
|
||||||
|
_ = cmd.Usage()
|
||||||
|
fmt.Print("\n\n")
|
||||||
|
log.Fatal("--dst-user can't be blank")
|
||||||
|
case dstPass == "":
|
||||||
|
_ = cmd.Usage()
|
||||||
|
fmt.Print("\n\n")
|
||||||
|
log.Fatal("--dst-pass can't be blank")
|
||||||
|
}
|
||||||
|
|
||||||
if workers > 10 && srcURL == "https://bashhub.com" {
|
if workers > 10 && srcURL == "https://bashhub.com" {
|
||||||
msg := fmt.Sprintf(`
|
msg := fmt.Sprintf(`
|
||||||
WARNING: errors are likely to occur when setting workers higher
|
WARNING: errors are likely to occur when setting workers higher
|
||||||
|
@ -78,16 +97,15 @@ var (
|
||||||
counter := 0
|
counter := 0
|
||||||
if !progress {
|
if !progress {
|
||||||
bar = pb.ProgressBarTemplate(barTemplate).Start(len(cmdList)).SetMaxWidth(70)
|
bar = pb.ProgressBarTemplate(barTemplate).Start(len(cmdList)).SetMaxWidth(70)
|
||||||
bar.Set("message", "inserting records \t")
|
bar.Set("message", "transferring ")
|
||||||
}
|
}
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
// ignore http errors. We try and recover them
|
||||||
|
log.SetOutput(nil)
|
||||||
for _, v := range cmdList {
|
for _, v := range cmdList {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
counter++
|
counter++
|
||||||
go func(c cList) {
|
go commandLookup(v.UUID, client, 0)
|
||||||
defer wg.Done()
|
|
||||||
commandLookup(c.UUID, client)
|
|
||||||
}(v)
|
|
||||||
if counter > workers {
|
if counter > workers {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
counter = 0
|
counter = 0
|
||||||
|
@ -164,7 +182,7 @@ func sysRegister(mac string, site string, user string, pass string) string {
|
||||||
}
|
}
|
||||||
sys := map[string]interface{}{
|
sys := map[string]interface{}{
|
||||||
"clientVersion": "1.2.0",
|
"clientVersion": "1.2.0",
|
||||||
"name": "migration",
|
"name": "transfer",
|
||||||
"hostname": host,
|
"hostname": host,
|
||||||
"mac": mac,
|
"mac": mac,
|
||||||
}
|
}
|
||||||
|
@ -189,26 +207,13 @@ func sysRegister(mac string, site string, user string, pass string) string {
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
log.Println(resp.StatusCode)
|
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
log.Println(string(b))
|
|
||||||
|
|
||||||
sysRegistered = true
|
sysRegistered = true
|
||||||
return getToken(site, user, pass)
|
return getToken(site, user, pass)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getToken(site string, user string, pass string) string {
|
func getToken(site string, user string, pass string) string {
|
||||||
// function used by bashhub to identify system
|
mac := "888888888888888"
|
||||||
cmd := exec.Command("python", "-c", "import uuid; print(str(uuid.getnode()))")
|
|
||||||
m, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
mac := strings.ReplaceAll(string(m), "\n", ``)
|
|
||||||
auth := map[string]interface{}{
|
auth := map[string]interface{}{
|
||||||
"username": user,
|
"username": user,
|
||||||
"password": pass,
|
"password": pass,
|
||||||
|
@ -267,7 +272,7 @@ func getCommandList() commandsList {
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error on response.\n", err)
|
log.Fatal("Error on response.\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
@ -279,40 +284,55 @@ func getCommandList() commandsList {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
var result commandsList
|
var result commandsList
|
||||||
json.Unmarshal(body, &result)
|
err = json.Unmarshal(body, &result)
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func commandLookup(uuid string, client *http.Client) {
|
|
||||||
u := strings.TrimSpace(srcURL) + "/api/v1/command/" + strings.TrimSpace(uuid)
|
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func commandLookup(uuid string, client *http.Client, retries int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
mem := strings.Contains(fmt.Sprintf("%v", r), "runtime error: invalid memory address")
|
||||||
|
eof := strings.Contains(fmt.Sprintf("%v", r), "EOF")
|
||||||
|
if mem || eof {
|
||||||
|
if retries < 10 {
|
||||||
|
retries++
|
||||||
|
commandLookup(uuid, client, retries)
|
||||||
|
} else {
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
|
log.Println("ERROR: failed over 10 times looking up command from source with uuid: ", uuid)
|
||||||
|
log.SetOutput(nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
|
log.Fatal(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
u := strings.TrimSpace(srcURL) + "/api/v1/command/" + strings.TrimSpace(uuid)
|
||||||
|
req, err := http.NewRequest("GET", u, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
req.Header.Add("Authorization", srcToken)
|
req.Header.Add("Authorization", srcToken)
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error on response.\n", err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//defer func() {
|
|
||||||
// err = resp.Body.Close()
|
|
||||||
// if err != nil {
|
|
||||||
// log.Println(err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}()
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Fatalf("failed command lookup from %v, go status code %v", srcURL, resp.StatusCode)
|
log.Fatalf("failed command lookup from %v, go status code %v", srcURL, resp.StatusCode)
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
srcSend(body, client)
|
srcSend(body, client)
|
||||||
}
|
}
|
||||||
|
@ -322,19 +342,24 @@ func srcSend(data []byte, client *http.Client) {
|
||||||
if !progress {
|
if !progress {
|
||||||
bar.Add(1)
|
bar.Add(1)
|
||||||
}
|
}
|
||||||
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
body := bytes.NewReader(data)
|
body := bytes.NewReader(data)
|
||||||
|
|
||||||
u := dstURL + "/api/v1/import"
|
u := dstURL + "/api/v1/import"
|
||||||
req, err := http.NewRequest("POST", u, body)
|
req, err := http.NewRequest("POST", u, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
req.Header.Add("Authorization", dstToken)
|
req.Header.Add("Authorization", dstToken)
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
log.Println("Error on response.\n", err)
|
log.Println("Error on response.\n", err)
|
||||||
|
log.SetOutput(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
Loading…
Add table
Reference in a new issue