263 lines
4.9 KiB
Go
263 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/pojntfx/stfs/examples"
|
|
"github.com/pojntfx/stfs/pkg/cache"
|
|
"github.com/pojntfx/stfs/pkg/config"
|
|
"github.com/pojntfx/stfs/pkg/fs"
|
|
"github.com/pojntfx/stfs/pkg/keys"
|
|
"github.com/pojntfx/stfs/pkg/operations"
|
|
"github.com/pojntfx/stfs/pkg/persisters"
|
|
"github.com/pojntfx/stfs/pkg/tape"
|
|
"github.com/pojntfx/stfs/pkg/utility"
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
func createFs(
|
|
drive string,
|
|
metadata string,
|
|
|
|
recordSize int,
|
|
readOnly bool,
|
|
verbose bool,
|
|
|
|
signature string,
|
|
signaturePassword string,
|
|
|
|
encryption string,
|
|
encryptionPassword string,
|
|
|
|
compression string,
|
|
compressionLevel string,
|
|
|
|
writeCache string,
|
|
writeCacheDir string,
|
|
|
|
fileSystemCache string,
|
|
fileSystemCacheDir string,
|
|
fileSystemCacheDuration time.Duration,
|
|
) (afero.Fs, error) {
|
|
signaturePrivkey, signaturePubkey, err := utility.Keygen(
|
|
config.PipeConfig{
|
|
Signature: signature,
|
|
Encryption: config.NoneKey,
|
|
},
|
|
config.PasswordConfig{
|
|
Password: signaturePassword,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
signatureRecipient, err := keys.ParseSignerRecipient(signature, signaturePubkey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
signatureIdentity, err := keys.ParseSignerIdentity(signature, signaturePrivkey, signaturePassword)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
encryptionPrivkey, encryptionPubkey, err := utility.Keygen(
|
|
config.PipeConfig{
|
|
Signature: config.NoneKey,
|
|
Encryption: encryption,
|
|
},
|
|
config.PasswordConfig{
|
|
Password: encryptionPassword,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
encryptionRecipient, err := keys.ParseRecipient(encryption, encryptionPubkey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
encryptionIdentity, err := keys.ParseIdentity(encryption, encryptionPrivkey, encryptionPassword)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tm := tape.NewTapeManager(
|
|
drive,
|
|
recordSize,
|
|
false,
|
|
)
|
|
|
|
metadataPersister := persisters.NewMetadataPersister(metadata)
|
|
if err := metadataPersister.Open(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
jsonLogger := &examples.Logger{
|
|
Verbose: verbose,
|
|
}
|
|
|
|
metadataConfig := config.MetadataConfig{
|
|
Metadata: metadataPersister,
|
|
}
|
|
pipeConfig := config.PipeConfig{
|
|
Compression: compression,
|
|
Encryption: encryption,
|
|
Signature: signature,
|
|
RecordSize: recordSize,
|
|
}
|
|
backendConfig := config.BackendConfig{
|
|
GetWriter: tm.GetWriter,
|
|
CloseWriter: tm.Close,
|
|
|
|
GetReader: tm.GetReader,
|
|
CloseReader: tm.Close,
|
|
|
|
GetDrive: tm.GetDrive,
|
|
CloseDrive: tm.Close,
|
|
}
|
|
readCryptoConfig := config.CryptoConfig{
|
|
Recipient: signatureRecipient,
|
|
Identity: encryptionIdentity,
|
|
Password: encryptionPassword,
|
|
}
|
|
|
|
readOps := operations.NewOperations(
|
|
backendConfig,
|
|
metadataConfig,
|
|
|
|
pipeConfig,
|
|
readCryptoConfig,
|
|
|
|
func(event *config.HeaderEvent) {
|
|
jsonLogger.Debug("Header read", event)
|
|
},
|
|
)
|
|
|
|
writeOps := operations.NewOperations(
|
|
backendConfig,
|
|
metadataConfig,
|
|
|
|
pipeConfig,
|
|
config.CryptoConfig{
|
|
Recipient: encryptionRecipient,
|
|
Identity: signatureIdentity,
|
|
Password: signaturePassword,
|
|
},
|
|
|
|
func(event *config.HeaderEvent) {
|
|
jsonLogger.Debug("Header write", event)
|
|
},
|
|
)
|
|
|
|
stfs := fs.NewSTFS(
|
|
readOps,
|
|
writeOps,
|
|
|
|
config.MetadataConfig{
|
|
Metadata: metadataPersister,
|
|
},
|
|
|
|
compressionLevel,
|
|
func() (cache.WriteCache, func() error, error) {
|
|
return cache.NewCacheWrite(
|
|
writeCacheDir,
|
|
writeCache,
|
|
)
|
|
},
|
|
false,
|
|
readOnly,
|
|
|
|
func(hdr *config.Header) {
|
|
jsonLogger.Trace("Header transform", hdr)
|
|
},
|
|
jsonLogger,
|
|
)
|
|
|
|
root, err := stfs.Initialize("/", os.ModePerm)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return cache.NewCacheFilesystem(
|
|
stfs,
|
|
root,
|
|
fileSystemCache,
|
|
fileSystemCacheDuration,
|
|
fileSystemCacheDir,
|
|
)
|
|
}
|
|
|
|
func main() {
|
|
tmp, err := os.MkdirTemp(os.TempDir(), "stfs-test-*")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
drive := filepath.Join(tmp, "drive.tar")
|
|
metadata := filepath.Join(tmp, "metadata.sqlite")
|
|
|
|
recordSize := 20
|
|
readOnly := false
|
|
verbose := true
|
|
|
|
signature := config.SignatureFormatPGPKey
|
|
signaturePassword := "testSignaturePassword"
|
|
|
|
encryption := config.EncryptionFormatAgeKey
|
|
encryptionPassword := "testEncryptionPassword"
|
|
|
|
compression := config.CompressionFormatZStandardKey
|
|
compressionLevel := config.CompressionLevelFastestKey
|
|
|
|
writeCache := config.WriteCacheTypeFile
|
|
writeCacheDir := filepath.Join(tmp, "write-cache")
|
|
|
|
fileSystemCache := config.FileSystemCacheTypeDir
|
|
fileSystemCacheDir := filepath.Join(tmp, "filesystem-cache")
|
|
fileSystemCacheDuration := time.Hour
|
|
|
|
fs, err := createFs(
|
|
drive,
|
|
metadata,
|
|
|
|
recordSize,
|
|
readOnly,
|
|
verbose,
|
|
|
|
signature,
|
|
signaturePassword,
|
|
|
|
encryption,
|
|
encryptionPassword,
|
|
|
|
compression,
|
|
compressionLevel,
|
|
|
|
writeCache,
|
|
writeCacheDir,
|
|
|
|
fileSystemCache,
|
|
fileSystemCacheDir,
|
|
fileSystemCacheDuration,
|
|
)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
log.Println("stat /")
|
|
|
|
stat, err := fs.Stat("/")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
log.Println("Result of stat /:", stat)
|
|
}
|