added ZSTD Layer
parent
d1bddfd037
commit
0b00bac7df
@ -0,0 +1,258 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.cheetah.cat/worksucc/gma-puzzles/common"
|
||||||
|
adriver "github.com/arangodb/go-driver"
|
||||||
|
ahttp "github.com/arangodb/go-driver/http"
|
||||||
|
"github.com/klauspost/compress/zstd"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
arangoDB adriver.Database
|
||||||
|
arangoCTX context.Context
|
||||||
|
colChunk adriver.Collection
|
||||||
|
colFile adriver.Collection
|
||||||
|
colFile2Chunk adriver.Collection
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConnectDB(baseURL string, arangoUser string, arangoPWD string, arangoDatabase string) (driver adriver.Database, ctx context.Context, err error) {
|
||||||
|
log.Println("connectDB:", "Starting Connection Process...")
|
||||||
|
|
||||||
|
// Retry Loop for Failed Connections
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
if i == 5 {
|
||||||
|
return driver, ctx, fmt.Errorf("connectdb unable to connect to database %d times", i)
|
||||||
|
} else if i > 0 {
|
||||||
|
time.Sleep(30 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to ArangoDB URL
|
||||||
|
conn, err := ahttp.NewConnection(ahttp.ConnectionConfig{
|
||||||
|
Endpoints: []string{baseURL},
|
||||||
|
TLSConfig: &tls.Config{ /*...*/ },
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("connectDB:", "Cannot Connect to ArangoDB!", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect Driver to User
|
||||||
|
client, err := adriver.NewClient(adriver.ClientConfig{
|
||||||
|
Connection: conn,
|
||||||
|
Authentication: adriver.BasicAuthentication(arangoUser, arangoPWD),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("connectDB:", "Cannot Authenticate ArangoDB User!", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Context for Database Access
|
||||||
|
ctx = context.Background()
|
||||||
|
driver, err = client.Database(ctx, arangoDatabase)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("connectDB:", "Cannot Load ArangoDB Database!", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Println("connectDB:", "Connection Sucessful!")
|
||||||
|
return driver, ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return driver, ctx, fmt.Errorf("connectDB: FUCK HOW DID THIS EXCUTE?")
|
||||||
|
}
|
||||||
|
func InitDatabase() (err error) {
|
||||||
|
arangoDB, arangoCTX, err = ConnectDB("http://192.168.45.8:8529/", "gma-inator", "gma-inator", "gma-inator")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
colChunk, err = arangoDB.Collection(arangoCTX, "chunk")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
colFile, err = arangoDB.Collection(arangoCTX, "file")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
colFile2Chunk, err = arangoDB.Collection(arangoCTX, "file_chunk_map")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type PoolRecoveryData struct {
|
||||||
|
PoolID string `json:"_key"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Created time.Time `json:"date"`
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
|
||||||
|
ItemCount int `json:"itemCount"`
|
||||||
|
Items []string `json:"items"`
|
||||||
|
RecoveryData []common.DB_File `json:"recoveryData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func bla() error {
|
||||||
|
entries, err := os.ReadDir("/mnt/SC9000/storagePools/")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, e := range entries {
|
||||||
|
if !e.IsDir() {
|
||||||
|
fmt.Printf("Scanning For Local Pools, found %s:", e.Name())
|
||||||
|
|
||||||
|
tarFinalPath := filepath.Join("/mnt/SC9000/storagePools/", e.Name())
|
||||||
|
stats, err := os.Stat(tarFinalPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
parts := strings.Split(e.Name(), ".")
|
||||||
|
var chunk common.DB_Chunk
|
||||||
|
_, err = colChunk.ReadDocument(arangoCTX, parts[0], &chunk)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
chunk.Finalized = true
|
||||||
|
chunk.NotReady = false
|
||||||
|
chunk.ReadOnly = true
|
||||||
|
chunk.Size = stats.Size()
|
||||||
|
|
||||||
|
zstFile, err := os.Open(tarFinalPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
shaHasher := sha256.New()
|
||||||
|
_, err = io.Copy(shaHasher, zstFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonPath := filepath.Join("/mnt/SC9000/storagePools/", fmt.Sprintf("%s.json", parts[0]))
|
||||||
|
|
||||||
|
_, err = os.Stat(jsonPath)
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
|
|
||||||
|
// rewrite json from db
|
||||||
|
|
||||||
|
zstFile.Seek(0, 0)
|
||||||
|
decompressor, err := zstd.NewReader(zstFile)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer decompressor.Close()
|
||||||
|
|
||||||
|
items := []string{}
|
||||||
|
tarReader := tar.NewReader(decompressor)
|
||||||
|
for {
|
||||||
|
header, err := tarReader.Next()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
items = append(items, header.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
poolRecoveryData := PoolRecoveryData{
|
||||||
|
PoolID: parts[0],
|
||||||
|
Size: uint64(stats.Size()),
|
||||||
|
Created: time.Now(),
|
||||||
|
Hash: fmt.Sprintf("%x", shaHasher.Sum(nil)),
|
||||||
|
ItemCount: 500,
|
||||||
|
Items: items,
|
||||||
|
//RecoveryData,
|
||||||
|
}
|
||||||
|
chunk.Hash = poolRecoveryData.Hash
|
||||||
|
|
||||||
|
//TODO: fetch RecoveryData from DB
|
||||||
|
poolRecoveryData.RecoveryData = make([]common.DB_File, len(items))
|
||||||
|
_, _, err = colFile.ReadDocuments(arangoCTX, items, poolRecoveryData.RecoveryData)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error @ReadDocuments %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
json, err := json.MarshalIndent(poolRecoveryData, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error @json.MarshalIndent %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
recoveryFile, err := os.Create(jsonPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = recoveryFile.Write(json)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error @recoveryFile.Write %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var poolRecoveryData PoolRecoveryData
|
||||||
|
|
||||||
|
readJSONFile, err := os.Open(jsonPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer readJSONFile.Close()
|
||||||
|
|
||||||
|
readBytes, err := io.ReadAll(readJSONFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(readBytes, &poolRecoveryData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
poolRecoveryData.Size = uint64(stats.Size())
|
||||||
|
poolRecoveryData.Created = time.Now()
|
||||||
|
poolRecoveryData.Hash = fmt.Sprintf("%x", shaHasher.Sum(nil))
|
||||||
|
chunk.Hash = poolRecoveryData.Hash
|
||||||
|
|
||||||
|
json, err := json.MarshalIndent(poolRecoveryData, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error @json.MarshalIndent %v", err)
|
||||||
|
}
|
||||||
|
recoveryFile, err := os.Create(jsonPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = recoveryFile.Write(json)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error @recoveryFile.Write %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = colChunk.UpdateDocument(arangoCTX, parts[0], &chunk)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
err := InitDatabase()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bla()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/klauspost/compress/zstd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
tarFile, err := os.Create("test.tar.zst")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer tarFile.Close()
|
||||||
|
|
||||||
|
compressor, err := zstd.NewWriter(tarFile, zstd.WithEncoderLevel(4))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer compressor.Close()
|
||||||
|
|
||||||
|
tw := tar.NewWriter(compressor)
|
||||||
|
defer tw.Close()
|
||||||
|
|
||||||
|
entries, err := os.ReadDir("/home/cheetah/dev/gma-puzzles/zstd-tar-test/testpayload")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range entries {
|
||||||
|
originalPath := filepath.Join("/home/cheetah/dev/gma-puzzles/zstd-tar-test/testpayload", e.Name())
|
||||||
|
|
||||||
|
file, err := os.Open(originalPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
info, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tarFileHeader, err := tar.FileInfoHeader(info, info.Name())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = tw.WriteHeader(tarFileHeader)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(tw, file)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(info.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tw.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = compressor.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = tarFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue