Skip to content

Commit

Permalink
Converted to monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
balazsgrill committed Aug 3, 2024
1 parent c2fbaef commit 707e904
Show file tree
Hide file tree
Showing 13 changed files with 578 additions and 85 deletions.
2 changes: 1 addition & 1 deletion cmd/s3/basepathfs.go → bindings/basepathfs.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bindings

import (
"io/fs"
Expand Down
97 changes: 97 additions & 0 deletions bindings/bindings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package bindings

import (
"flag"
"log"
"os"
"os/signal"
"reflect"
"strings"
"syscall"
"time"

"github.com/balazsgrill/potatodrive/filesystem"
"github.com/spf13/afero"
"golang.org/x/sys/windows/registry"
)

func ConfigToFlags(config any) {
structPtrValue := reflect.ValueOf(config)
structValue := structPtrValue.Elem()
structType := structValue.Type()
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)

tagstr := field.Tag.Get("flag")
if tagstr != "" {
tagdata := strings.Split(tagstr, ",")
tag := tagdata[0]
msg := tagdata[1]
switch field.Type.Kind() {
case reflect.String:
flag.StringVar((*string)(structValue.Field(i).Addr().UnsafePointer()), tag, "", msg)
case reflect.Bool:
flag.BoolVar((*bool)(structValue.Field(i).Addr().UnsafePointer()), tag, false, msg)
}
}
}
}

func ReadConfigFromRegistry(key registry.Key, config any) error {
structPtrValue := reflect.ValueOf(config)
structValue := structPtrValue.Elem()
structType := structValue.Type()
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
fieldvalue := structValue.Field(i)
tag := field.Tag.Get("reg")
if tag != "" {
switch field.Type.Kind() {
case reflect.String:
value, _, err := key.GetStringValue(tag)
if os.IsNotExist(err) {
continue
}
if err != nil {
return err
}
fieldvalue.SetString(value)
case reflect.Bool:
value, _, err := key.GetIntegerValue(tag)
if os.IsNotExist(err) {
continue
}
if err != nil {
return err
}
fieldvalue.SetBool(value != 0)
}
}
}
return nil
}

func BindVirtualizationInstance(localpath string, remotefs afero.Fs) error {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
closer, err := filesystem.StartProjecting(localpath, remotefs)
if err != nil {
return err
}

t := time.NewTicker(30 * time.Second)
go func() {
for range t.C {
err = closer.PerformSynchronization()
if err != nil {
log.Panic(err)
}
}
}()

<-c
t.Stop()
closer.Close()
os.Exit(1)
return nil
}
62 changes: 62 additions & 0 deletions bindings/s3/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package s3

import (
"errors"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/balazsgrill/potatodrive/bindings"
s3 "github.com/fclairamb/afero-s3"
"github.com/spf13/afero"
)

type Config struct {
LocalPath string `flag:"localpath,Local folder" reg:"LocalPath"`
Endpoint string `flag:"endpoint,S3 endpoint" reg:"Endpoint"`
Region string `flag:"region,Region" reg:"Region"`
Bucket string `flag:"bucket,Bucket" reg:"Bucket"`
KeyId string `flag:"keyid,Access Key ID" reg:"KeyID"`
KeySecret string `flag:"secret,Access Key Secret" reg:"KeySecret"`
UseSSL bool `flag:"useSSL,Use SSL encryption for S3 connection" reg:"UseSSL"`
}

func (c *Config) Validate() error {
if c.Endpoint == "" {
return errors.New("endpoint is mandatory")
}
if c.LocalPath == "" {
return errors.New("localpath is mandatory")
}
if c.Region == "" {
return errors.New("region is mandatory")
}
if c.Bucket == "" {
return errors.New("bucket is mandatory")
}
if c.KeyId == "" {
return errors.New("keyid is mandatory")
}
if c.KeySecret == "" {
return errors.New("secret is mandatory")
}
return nil
}

func (c *Config) ToFileSystem() (afero.Fs, error) {
sess, err := session.NewSession(&aws.Config{
Region: aws.String(c.Region),
Endpoint: aws.String(c.Endpoint),
DisableSSL: aws.Bool(!c.UseSSL),
S3ForcePathStyle: aws.Bool(true),
Credentials: credentials.NewStaticCredentials(c.KeyId, c.KeySecret, ""),
})
if err != nil {
return nil, err
}

fs := s3.NewFs(c.Bucket, sess)
fs.MkdirAll("root", 0777)
rootfs := bindings.NewBasePathFs(fs, "root")
return rootfs, nil
}
90 changes: 13 additions & 77 deletions cmd/s3/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,102 +3,38 @@ package main
import (
"flag"
"log"
"os"
"os/signal"
"syscall"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/balazsgrill/projfero/filesystem"
s3 "github.com/fclairamb/afero-s3"
"github.com/balazsgrill/potatodrive/bindings"
cs3 "github.com/balazsgrill/potatodrive/bindings/s3"
"golang.org/x/sys/windows/registry"
)

func main() {
regkey := flag.String("regkey", "", "Registry key that holds configuration")
endpoint := flag.String("endpoint", "", "S3 endpoint")
accessKeyID := flag.String("keyid", "", "Access Key ID")
secretAccessKey := flag.String("secred", "", "Access Key Secret")
useSSL := flag.Bool("useSSL", false, "Use SSL encryption for S3 connection")
region := flag.String("region", "", "Region")
bucket := flag.String("bucket", "", "Bucket")
localpath := flag.String("localpath", "", "Local folder")
config := &cs3.Config{}
bindings.ConfigToFlags(config)
flag.Parse()

if *regkey != "" {
key, err := registry.OpenKey(registry.CURRENT_USER, *regkey, registry.QUERY_VALUE)
if err != nil {
log.Panic(err)
}
*endpoint, _, err = key.GetStringValue("Endpoint")
if err != nil {
log.Panic(err)
}
*accessKeyID, _, err = key.GetStringValue("KeyID")
if err != nil {
log.Panic(err)
}
*secretAccessKey, _, err = key.GetStringValue("KeySecret")
if err != nil {
log.Panic(err)
}
useSSLint, _, err := key.GetIntegerValue("UseSSL")
if err != nil {
log.Panic(err)
}
*useSSL = useSSLint != 0
*region, _, err = key.GetStringValue("Region")
if err != nil {
log.Panic(err)
}
*bucket, _, err = key.GetStringValue("Bucket")
if err != nil {
log.Panic(err)
}
*localpath, _, err = key.GetStringValue("Directory")
if err != nil {
log.Panic(err)
}
bindings.ReadConfigFromRegistry(key, config)
}

if *endpoint == "" || *accessKeyID == "" || *secretAccessKey == "" || *region == "" || *bucket == "" || *localpath == "" {
log.Panic("Missing configuration")
err := config.Validate()
if err != nil {
panic(err)
}

sess, _ := session.NewSession(&aws.Config{
Region: aws.String(*region),
Endpoint: aws.String(*endpoint),
DisableSSL: aws.Bool(!*useSSL),
S3ForcePathStyle: aws.Bool(true),
Credentials: credentials.NewStaticCredentials(*accessKeyID, *secretAccessKey, ""),
})

// Initialize the file system
fs := s3.NewFs(*bucket, sess)
fs.MkdirAll("root", 0777)
rootfs := NewBasePathFs(fs, "root")

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
closer, err := filesystem.StartProjecting(*localpath, rootfs)
fs, err := config.ToFileSystem()
if err != nil {
log.Panic(err)
}

t := time.NewTicker(30 * time.Second)
go func() {
for range t.C {
err = closer.PerformSynchronization()
if err != nil {
log.Panic(err)
}
}
}()

<-c
t.Stop()
closer.Close()
os.Exit(1)
err = bindings.BindVirtualizationInstance(config.LocalPath, fs)
if err != nil {
log.Panic(err)
}
}
2 changes: 1 addition & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os/signal"
"syscall"

"github.com/balazsgrill/projfero/filesystem"
"github.com/balazsgrill/potatodrive/filesystem"
"github.com/spf13/afero"
)

Expand Down
2 changes: 1 addition & 1 deletion filesystem/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

"C"

"github.com/balazsgrill/projfs"
"github.com/balazsgrill/potatodrive/projfs"
"github.com/google/uuid"
"github.com/spf13/afero"
)
Expand Down
2 changes: 1 addition & 1 deletion filesystem/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"testing"
"time"

"github.com/balazsgrill/projfero/filesystem"
"github.com/balazsgrill/potatodrive/filesystem"
"github.com/spf13/afero"
)

Expand Down
5 changes: 1 addition & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
module github.com/balazsgrill/projfero
module github.com/balazsgrill/potatodrive

go 1.21.0

require (
fyne.io/fyne/v2 v2.5.0
github.com/aws/aws-sdk-go v1.54.20
github.com/balazsgrill/projfs v0.0.2
github.com/fclairamb/afero-s3 v0.3.1
github.com/google/uuid v1.6.0
github.com/spf13/afero v1.11.0
Expand Down Expand Up @@ -43,5 +42,3 @@ require (
golang.org/x/text v0.16.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

//replace github.com/balazsgrill/projfs => ../projfs
2 changes: 2 additions & 0 deletions projfs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Golang bingings for [Windows Projected File System API](https://learn.microsoft.com/en-us/windows/win32/projfs/projected-file-system).
It can be used to implement user-space filesystem virtualization mounted to a local directory with local cache not unlike OneDrive.
Loading

0 comments on commit 707e904

Please sign in to comment.