mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-27 20:36:29 -04:00
Handle more server-side errors from the client
This commit is contained in:
+9
-2
@@ -2,9 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rwinkhart/go-boilerplate/back"
|
||||
@@ -110,8 +110,15 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print EntryRoot, AgeDir and bool indicating OS type to stdout for client to store in config
|
||||
fmt.Print(global.EntryRoot + global.FSSpace + global.AgeDir + global.FSSpace + strconv.FormatBool(global.IsWindows))
|
||||
registerResp := synccommon.RegisterResp{EntryRoot: global.EntryRoot, AgeDir: global.AgeDir, IsWindows: global.IsWindows}
|
||||
registerRespBytes, err := json.Marshal(registerResp)
|
||||
if err != nil {
|
||||
fmt.Printf("{\"errMsg\":\"%s\"}", err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Print(string(registerRespBytes))
|
||||
case "init":
|
||||
// create the necessary directories for libmuttonserver to function
|
||||
_, err := global.DirInit(false)
|
||||
|
||||
@@ -561,5 +561,6 @@ func RunJob(returnLists bool) ([3][]string, error) {
|
||||
if err != nil {
|
||||
return [3][]string{nil, nil, nil}, errors.New("unable to sync entries: " + err.Error())
|
||||
}
|
||||
_ = sshClient.Close() // ignore error; non-critical/unlikely/not much could be done about it
|
||||
return lists, nil // dummy return for when not returning lists
|
||||
}
|
||||
|
||||
+15
-3
@@ -22,6 +22,7 @@ func ShearRemoteFromClient(vanityPath string, onlyShearAgeFile bool) error {
|
||||
}
|
||||
|
||||
var modifier string
|
||||
var output []byte
|
||||
sshClient, offlineMode, _, _, _, err := GetSSHClient()
|
||||
if offlineMode {
|
||||
goto end
|
||||
@@ -42,10 +43,13 @@ func ShearRemoteFromClient(vanityPath string, onlyShearAgeFile bool) error {
|
||||
if onlyShearAgeFile {
|
||||
modifier = "-age"
|
||||
}
|
||||
_, err = GetSSHOutput(sshClient, "libmuttonserver shear"+modifier, deviceID+"\n"+strings.ReplaceAll(vanityPath, global.PathSeparator, global.FSPath))
|
||||
output, err = GetSSHOutput(sshClient, "libmuttonserver shear"+modifier, deviceID+"\n"+strings.ReplaceAll(vanityPath, global.PathSeparator, global.FSPath))
|
||||
if err != nil {
|
||||
return errors.New("unable to shear target remotely: " + err.Error())
|
||||
}
|
||||
if len(output) > 11 {
|
||||
return errors.New("unable to complete shear; server-side error occurred: " + string(output)[11:len(output)-2])
|
||||
}
|
||||
|
||||
// close the SSH client
|
||||
err = sshClient.Close()
|
||||
@@ -78,6 +82,7 @@ func RenameRemoteFromClient(oldVanityPath, newVanityPath string) error {
|
||||
}
|
||||
|
||||
// create an SSH client
|
||||
var output []byte
|
||||
sshClient, offlineMode, _, _, _, err := GetSSHClient()
|
||||
if offlineMode {
|
||||
goto end
|
||||
@@ -87,13 +92,16 @@ func RenameRemoteFromClient(oldVanityPath, newVanityPath string) error {
|
||||
}
|
||||
|
||||
// call the server to move the target on the remote system and add the old target to the deletions list
|
||||
_, err = GetSSHOutput(sshClient, "libmuttonserver rename",
|
||||
output, err = GetSSHOutput(sshClient, "libmuttonserver rename",
|
||||
(deviceIDList)[0].Name()+"\n"+
|
||||
strings.ReplaceAll(oldVanityPath, global.PathSeparator, global.FSPath)+"\n"+
|
||||
strings.ReplaceAll(newVanityPath, global.PathSeparator, global.FSPath))
|
||||
if err != nil {
|
||||
return errors.New("unable to rename target remotely: " + err.Error())
|
||||
}
|
||||
if len(output) > 11 {
|
||||
return errors.New("unable to complete rename; server-side error occurred: " + string(output)[11:len(output)-2])
|
||||
}
|
||||
|
||||
// close the SSH client
|
||||
err = sshClient.Close()
|
||||
@@ -118,6 +126,7 @@ func AddFolderRemoteFromClient(vanityPath string) error {
|
||||
}
|
||||
|
||||
// create an SSH client
|
||||
var output []byte
|
||||
sshClient, offlineMode, _, _, _, err := GetSSHClient()
|
||||
if offlineMode {
|
||||
goto end
|
||||
@@ -127,10 +136,13 @@ func AddFolderRemoteFromClient(vanityPath string) error {
|
||||
}
|
||||
|
||||
// call the server to create the folder remotely
|
||||
_, err = GetSSHOutput(sshClient, "libmuttonserver addfolder", strings.ReplaceAll(vanityPath, global.PathSeparator, global.FSPath)) // call the server to create the folder remotely
|
||||
output, err = GetSSHOutput(sshClient, "libmuttonserver addfolder", strings.ReplaceAll(vanityPath, global.PathSeparator, global.FSPath)) // call the server to create the folder remotely
|
||||
if err != nil {
|
||||
return errors.New("unable to add folder remotely: " + err.Error())
|
||||
}
|
||||
if len(output) > 11 {
|
||||
return errors.New("unable to complete addfolder; server-side error occurred: " + string(output)[11:len(output)-2])
|
||||
}
|
||||
|
||||
// close the SSH client
|
||||
err = sshClient.Close()
|
||||
|
||||
+11
-7
@@ -16,25 +16,31 @@ const (
|
||||
AnsiDelete = "\033[38;5;1m"
|
||||
)
|
||||
|
||||
// FetchResponse defines the structure of responses from `libmuttonserver fetch`.
|
||||
// FetchResp defines the structure of responses from `libmuttonserver fetch`.
|
||||
type FetchResp struct {
|
||||
ErrMsg *string `json:"errMsg"` // nil if no error occurred
|
||||
ServerTime int64 `json:"serverTime"`
|
||||
Deletions []Deletion `json:"deletions"`
|
||||
FoldersToEntries map[string][]Entry `json:"folders"`
|
||||
}
|
||||
|
||||
type Deletion struct {
|
||||
VanityPath string `json:"vanityPath"`
|
||||
IsAgeFile bool `json:"isAgeFile"`
|
||||
}
|
||||
|
||||
type Entry struct {
|
||||
VanityPath string `json:"vanityPath"`
|
||||
ModTime int64 `json:"modTime"`
|
||||
AgeTimestamp *int64 `json:"ageTimestamp"` // nil if no age file is present (non-password entry)
|
||||
}
|
||||
|
||||
// RegisterResp defines the structure of responses from `libmuttonserver register`
|
||||
type RegisterResp struct {
|
||||
ErrMsg *string `json:"errMsg"` // nil if no error occurred
|
||||
EntryRoot string `json:"entryRoot"`
|
||||
AgeDir string `json:"ageDir"`
|
||||
IsWindows bool `json:"isWindows"`
|
||||
}
|
||||
|
||||
// GetModTimes returns a list of all entry modification times.
|
||||
func GetModTimes(entryList []string) []int64 {
|
||||
var modList []int64
|
||||
@@ -70,17 +76,15 @@ func ShearLocal(vanityPath, clientDeviceID string, onlyShearAgeFile bool) (strin
|
||||
if !onlyShearAgeFile {
|
||||
f, err := os.OpenFile(global.ConfigDir+global.PathSeparator+"deletions"+global.PathSeparator+device.Name()+global.FSSpace+"entry"+global.FSSpace+strings.ReplaceAll(vanityPath, "/", global.FSPath), os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
// do not print error as there is currently no way of seeing server-side errors
|
||||
// failure to add the target to the deletions list will exit the program and result in a client re-uploading the target (non-critical)
|
||||
os.Exit(back.ErrorWrite)
|
||||
return "", false, err
|
||||
}
|
||||
_ = f.Close() // error ignored; if the file could be created, it can probably be closed
|
||||
}
|
||||
f, err := os.OpenFile(global.ConfigDir+global.PathSeparator+"deletions"+global.PathSeparator+device.Name()+global.FSSpace+"age"+global.FSSpace+strings.ReplaceAll(vanityPath, "/", global.FSPath), os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
// do not print error as there is currently no way of seeing server-side errors
|
||||
// failure to add the target to the deletions list will exit the program and result in a client re-uploading the target (non-critical)
|
||||
os.Exit(back.ErrorWrite)
|
||||
return "", false, err
|
||||
}
|
||||
_ = f.Close() // error ignored; if the file could be created, it can probably be closed
|
||||
}
|
||||
|
||||
+12
-3
@@ -1,16 +1,17 @@
|
||||
package synccycles
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rwinkhart/go-boilerplate/back"
|
||||
"github.com/rwinkhart/libmutton/global"
|
||||
"github.com/rwinkhart/libmutton/syncclient"
|
||||
"github.com/rwinkhart/libmutton/synccommon"
|
||||
)
|
||||
|
||||
// DeviceIDGen generates a new client device ID and registers it with the server (will replace existing one).
|
||||
@@ -59,7 +60,15 @@ func DeviceIDGen(oldDeviceID, prefix string) (string, string, string, error) {
|
||||
cleanupOnFail()
|
||||
return "", "", "", errors.New("unable to register device ID with server: " + err.Error())
|
||||
}
|
||||
sshEntryRootSSHAgeDirSSHIsWindows := strings.Split(string(output), global.FSSpace)
|
||||
var registerResp synccommon.RegisterResp
|
||||
err = json.Unmarshal(output, ®isterResp)
|
||||
if err != nil {
|
||||
cleanupOnFail()
|
||||
return "", "", "", errors.New("unable to unmarshal server register response: " + err.Error())
|
||||
}
|
||||
if registerResp.ErrMsg != nil {
|
||||
return "", "", "", errors.New("unable to complete register; server-side error occurred: " + *registerResp.ErrMsg)
|
||||
}
|
||||
_ = sshClient.Close() // ignore error; non-critical/unlikely/not much could be done about it
|
||||
|
||||
// remove old device ID file (locally; may not exist)
|
||||
@@ -68,5 +77,5 @@ func DeviceIDGen(oldDeviceID, prefix string) (string, string, string, error) {
|
||||
return "", "", "", errors.New("unable to remove old device ID file (locally): " + err.Error())
|
||||
}
|
||||
|
||||
return sshEntryRootSSHAgeDirSSHIsWindows[0], sshEntryRootSSHAgeDirSSHIsWindows[1], sshEntryRootSSHAgeDirSSHIsWindows[2], nil
|
||||
return registerResp.EntryRoot, registerResp.AgeDir, strconv.FormatBool(registerResp.IsWindows), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user