From b71ede4c1ba09c700c1c58a4c0617be3f961f627 Mon Sep 17 00:00:00 2001 From: mahdi Date: Tue, 21 Nov 2023 17:08:40 +0100 Subject: [PATCH] sys/ssh - add DownloadFile --- ssh/ssh.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/sys.go | 21 ++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/ssh/ssh.go b/ssh/ssh.go index 5ff63c0..a552473 100644 --- a/ssh/ssh.go +++ b/ssh/ssh.go @@ -8,8 +8,11 @@ import ( "net" "os" "os/user" + "strings" "gitea.meta-tech.academy/go/core/echo" + "gitea.meta-tech.academy/go/core/sys" + "gitea.meta-tech.academy/go/core/util" "github.com/pkg/sftp" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" @@ -115,6 +118,59 @@ func (s *Ssh) Scp() *sftp.Client { return scp } +type ApplyOnSize func(s *Ssh, size int64) + +func (s *Ssh) DownloadFile(remoteFile string, localFile string, display bool, close bool, fn ...ApplyOnSize) bool { + done := false + alreadyDownload := false + checksum := "" + buf := s.Exec(fmt.Sprintf("du --apparent-size --block-size=1 \"%s\" | awk '{ print $1}'", remoteFile), false) + size := util.Str2int64(buf.String(), 10, -1) + buf.Reset() + if len(fn) > 0 { + fn[0](s, size) + } + buf = s.Exec(fmt.Sprintf("sha256sum \"%s\" | cut -d' ' -f1", remoteFile), false) + checksum = strings.TrimSuffix(buf.String(), "\n") + buf.Reset() + if sys.CheckFileSize(size, localFile) { + if display { + echo.Cstyle("usageCom").Echo(" already downloaded\n") + } + alreadyDownload = sys.CheckSumFile(checksum, localFile) + if display { + if alreadyDownload { + echo.Cstyle("usageCom").Echo(" file integrity confirmed\n") + } else { + echo.Cstyle("podFullName").Echo(" file seems corrupt, retry download\n") + } + } + } else if display { + echo.Cstyle("podFullName").Echo(" file seems corrupt, retry download\n") + } + if !alreadyDownload { + scp := s.Scp() + if close { + defer scp.Close() + } + if err := s.downloadFile(size, scp, remoteFile, localFile); err != nil { + done = sys.CheckSumFile(checksum, localFile) + if display { + echo.Cstyle("usageCom").Echo(" file downloaded !\n") + if done { + echo.Cstyle("usageCom").Echo(" file integrity confirmed\n") + } else { + echo.Cstyle("usageCom").Echo(" file seems corrupt, abort\n") + } + echo.State(done) + } + } else { + log.Fatal(err) + } + } + return done +} + func (s *Ssh) ScpDownload(size int64, remoteFile string, localFile string, close bool) bool { var done bool = false scp := s.Scp() diff --git a/sys/sys.go b/sys/sys.go index 6f9944e..2d7f0ab 100644 --- a/sys/sys.go +++ b/sys/sys.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "os/signal" + "strings" "syscall" "golang.org/x/sys/unix" @@ -156,3 +157,23 @@ func IsFileExists(path string) bool { } return exists } + +func CheckFileSize(remoteSize int64, path string) bool { + var size int64 = -1 + if IsFileExists(path) { + if infos, err := os.Stat(path); err == nil { + size = infos.Size() + } + } + return size == remoteSize +} + +func CheckSumFile(remoteChecksum string, path string) bool { + var checksum string = "" + if IsFileExists(path) { + var buf bytes.Buffer + RunBufferedCmd(exec.Command("sha256sum", path), &buf) + checksum = strings.Split(buf.String(), " ")[0] + } + return checksum == remoteChecksum +}