Skip to content

Commit

Permalink
translate rsync exit code to error message (solve #20). May help #109
Browse files Browse the repository at this point in the history
…and #110
  • Loading branch information
z4yx committed Mar 28, 2020
1 parent 1388757 commit 720db66
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
38 changes: 38 additions & 0 deletions internal/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,37 @@ import (
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os/exec"
"regexp"
"time"
)

var rsyncExitValues = map[int]string{
0: "Success",
1: "Syntax or usage error",
2: "Protocol incompatibility",
3: "Errors selecting input/output files, dirs",
4: "Requested action not supported: an attempt was made to manipulate 64-bit files on a platform that cannot support them; or an option was specified that is supported by the client and not by the server.",
5: "Error starting client-server protocol",
6: "Daemon unable to append to log-file",
10: "Error in socket I/O",
11: "Error in file I/O",
12: "Error in rsync protocol data stream",
13: "Errors with program diagnostics",
14: "Error in IPC code",
20: "Received SIGUSR1 or SIGINT",
21: "Some error returned by waitpid()",
22: "Error allocating core memory buffers",
23: "Partial transfer due to error",
24: "Partial transfer due to vanished source files",
25: "The --max-delete limit stopped deletions",
30: "Timeout in data send/receive",
35: "Timeout waiting for daemon connection",
}

// GetTLSConfig generate tls.Config from CAFile
func GetTLSConfig(CAFile string) (*tls.Config, error) {
caCert, err := ioutil.ReadFile(CAFile)
Expand Down Expand Up @@ -115,3 +140,16 @@ func ExtractSizeFromRsyncLog(logFile string) string {
re := regexp.MustCompile(`(?m)^Total file size: ([0-9\.]+[KMGTP]?) bytes`)
return ExtractSizeFromLog(logFile, re)
}

// TranslateRsyncErrorCode translates the exit code of rsync to a message
func TranslateRsyncErrorCode(cmdErr error) (exitCode int, msg string) {

if exiterr, ok := cmdErr.(*exec.ExitError); ok {
exitCode = exiterr.ExitCode()
strerr, valid := rsyncExitValues[exitCode]
if valid {
msg = fmt.Sprintf("rsync error: %s", strerr)
}
}
return
}
58 changes: 58 additions & 0 deletions worker/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,34 @@ exit 0
})

})
Convey("If the rsync program fails", t, func() {
tmpDir, err := ioutil.TempDir("", "tunasync")
defer os.RemoveAll(tmpDir)
So(err, ShouldBeNil)
tmpFile := filepath.Join(tmpDir, "log_file")

Convey("in the rsyncProvider", func() {

c := rsyncConfig{
name: "tuna",
upstreamURL: "rsync://rsync.tuna.moe/tuna/",
workingDir: tmpDir,
logDir: tmpDir,
logFile: tmpFile,
extraOptions: []string{"--somethine-invalid"},
interval: 600 * time.Second,
}

provider, err := newRsyncProvider(c)
So(err, ShouldBeNil)

err = provider.Run()
So(err, ShouldNotBeNil)
loggedContent, err := ioutil.ReadFile(provider.LogFile())
So(err, ShouldBeNil)
So(string(loggedContent), ShouldContainSubstring, "Syntax or usage error")
})
})
}

func TestRsyncProviderWithAuthentication(t *testing.T) {
Expand Down Expand Up @@ -556,4 +584,34 @@ exit 0
// fmt.Println(string(loggedContent))
})
})

Convey("If the rsync program fails", t, func(ctx C) {
tmpDir, err := ioutil.TempDir("", "tunasync")
defer os.RemoveAll(tmpDir)
So(err, ShouldBeNil)
tmpFile := filepath.Join(tmpDir, "log_file")

Convey("in the twoStageRsyncProvider", func() {

c := twoStageRsyncConfig{
name: "tuna-two-stage-rsync",
upstreamURL: "rsync://0.0.0.1/",
stage1Profile: "debian",
workingDir: tmpDir,
logDir: tmpDir,
logFile: tmpFile,
excludeFile: tmpFile,
}

provider, err := newTwoStageRsyncProvider(c)
So(err, ShouldBeNil)

err = provider.Run()
So(err, ShouldNotBeNil)
loggedContent, err := ioutil.ReadFile(provider.LogFile())
So(err, ShouldBeNil)
So(string(loggedContent), ShouldContainSubstring, "Error in socket I/O")

})
})
}
7 changes: 7 additions & 0 deletions worker/rsync_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ func (p *rsyncProvider) Run() error {
return err
}
if err := p.Wait(); err != nil {
code, msg := internal.TranslateRsyncErrorCode(err)
if code != 0 {
logger.Debug("Rsync exitcode %d (%s)", code, msg)
if p.logFileFd != nil {
p.logFileFd.WriteString(msg + "\n")
}
}
return err
}
p.dataSize = internal.ExtractSizeFromRsyncLog(p.LogFile())
Expand Down
7 changes: 7 additions & 0 deletions worker/two_stage_rsync_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ func (p *twoStageRsyncProvider) Run() error {
err = p.Wait()
p.Lock()
if err != nil {
code, msg := internal.TranslateRsyncErrorCode(err)
if code != 0 {
logger.Debug("Rsync exitcode %d (%s)", code, msg)
if p.logFileFd != nil {
p.logFileFd.WriteString(msg + "\n")
}
}
return err
}
}
Expand Down

0 comments on commit 720db66

Please sign in to comment.