COCOS-151 - Add compression/decompression option for CLI/Agent (#200)

* on the fly compression

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* rename file-hash to checksum

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* check error properly

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* fix lint

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* fix connection handling

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

---------

Signed-off-by: Sammy Oina <sammyoina@gmail.com>
This commit is contained in:
Sammy Kerata Oina
2024-08-21 12:54:52 +03:00
committed by GitHub
parent e4ef1aae36
commit 899bfb0ec5
12 changed files with 287 additions and 132 deletions
+37
View File
@@ -3,9 +3,12 @@
package internal
import (
"encoding/hex"
"io"
"os"
"path/filepath"
"golang.org/x/crypto/sha3"
)
// CopyFile copies a file from srcPath to dstPath.
@@ -46,3 +49,37 @@ func DeleteFilesInDir(dirPath string) error {
return nil
}
// Checksum calculates the SHA3-256 checksum of the file or directory at path.
func Checksum(path string) ([]byte, error) {
file, err := os.Stat(path)
if err != nil {
return nil, err
}
if file.IsDir() {
f, err := ZipDirectoryToMemory(path)
if err != nil {
return nil, err
}
sum := sha3.Sum256(f)
return sum[:], nil
} else {
f, err := os.ReadFile(path)
if err != nil {
return nil, err
}
sum := sha3.Sum256(f)
return sum[:], nil
}
}
// ChecksumHex calculates the SHA3-256 checksum of the file or directory at path and returns it as a hex-encoded string.
func ChecksumHex(path string) (string, error) {
sum, err := Checksum(path)
if err != nil {
return "", err
}
return hex.EncodeToString(sum), nil
}
+102
View File
@@ -0,0 +1,102 @@
// Copyright (c) Ultraviolet
// SPDX-License-Identifier: Apache-2.0
package internal
import (
"archive/zip"
"bytes"
"io"
"os"
"path/filepath"
)
func ZipDirectoryToMemory(sourceDir string) ([]byte, error) {
buf := new(bytes.Buffer)
zipWriter := zip.NewWriter(buf)
err := filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
relPath, err := filepath.Rel(sourceDir, path)
if err != nil {
return err
}
zipHeader, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
zipHeader.Name = relPath
zipWriterEntry, err := zipWriter.CreateHeader(zipHeader)
if err != nil {
return err
}
fileToZip, err := os.Open(path)
if err != nil {
return err
}
defer fileToZip.Close()
_, err = io.Copy(zipWriterEntry, fileToZip)
return err
})
if err != nil {
zipWriter.Close()
return nil, err
}
if err := zipWriter.Close(); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func UnzipFromMemory(zipData []byte, targetDir string) error {
reader := bytes.NewReader(zipData)
zipReader, err := zip.NewReader(reader, int64(len(zipData)))
if err != nil {
return err
}
for _, file := range zipReader.File {
filePath := filepath.Join(targetDir, file.Name)
if file.FileInfo().IsDir() {
if err := os.MkdirAll(filePath, os.ModePerm); err != nil {
return err
}
continue
}
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return err
}
srcFile, err := file.Open()
if err != nil {
return err
}
defer srcFile.Close()
dstFile, err := os.Create(filePath)
if err != nil {
return err
}
defer dstFile.Close()
if _, err := io.Copy(dstFile, srcFile); err != nil {
return err
}
}
return nil
}