Last active
November 1, 2018 18:34
-
-
Save markbates/93f8bd139997b1273aad4bf59ab6d6f9 to your computer and use it in GitHub Desktop.
store and resolver implementation using s3 for Packr v2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net/http" | |
_ "github.com/gobuffalo/buffalo" | |
"github.com/gobuffalo/packr/v2" | |
"github.com/markbates/s3packr/s3packr" | |
) | |
func main() { | |
box := packr.New("my templates", "../mysite/templates") | |
box.DefaultResolver = s3packr.NewResolver() | |
http.Handle("/", http.FileServer(box)) | |
fmt.Println("listening on :3000") | |
http.ListenAndServe(":3000", nil) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"os" | |
"github.com/gobuffalo/logger" | |
"github.com/gobuffalo/packr/v2/jam/parser" | |
"github.com/gobuffalo/packr/v2/plog" | |
"github.com/markbates/s3packr/s3packr" | |
) | |
func main() { | |
plog.Logger = logger.New(logger.DebugLevel) | |
paths := os.Args[1:] | |
if len(paths) == 0 { | |
paths = []string{"."} | |
} | |
ps, err := parser.NewFromRoots(paths, &parser.RootsOptions{}) | |
if err != nil { | |
log.Fatal(err) | |
} | |
boxes, err := ps.Run() | |
if err != nil { | |
log.Fatal(err) | |
} | |
for _, box := range boxes { | |
s3 := s3packr.New(box) | |
if err := s3.Pack(box); err != nil { | |
log.Fatal(err) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package s3packr | |
import ( | |
"context" | |
"github.com/gobuffalo/packr/v2/file" | |
"github.com/gobuffalo/packr/v2/file/resolver" | |
"github.com/google/go-cloud/blob" | |
"github.com/pkg/errors" | |
) | |
type Resolver struct { | |
*resolver.Disk | |
} | |
func NewResolver() resolver.Resolver { | |
return Resolver{ | |
Disk: &resolver.Disk{Root: "."}, | |
} | |
} | |
func (r Resolver) Resolve(box string, path string) (file.File, error) { | |
var f file.File | |
key := Key(box + path) | |
withBucket(func(ctx context.Context, buck *blob.Bucket) error { | |
r, err := buck.NewReader(ctx, key) | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
defer r.Close() | |
f, err = file.NewFileR(path, r) | |
return err | |
}) | |
if f != nil { | |
return f, nil | |
} | |
f, err := r.Disk.Resolve(box, path) | |
if err != nil { | |
return f, errors.WithStack(err) | |
} | |
return f, nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package s3packr | |
import ( | |
"crypto/sha1" | |
"fmt" | |
"io" | |
"path/filepath" | |
"strings" | |
) | |
func Key(s string) string { | |
h := sha1.New() | |
io.WriteString(h, strings.ToLower(s)) | |
return fmt.Sprintf("%x%s", h.Sum(nil), filepath.Ext(s)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package s3packr | |
import ( | |
"context" | |
"io" | |
"os" | |
"path/filepath" | |
"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/gobuffalo/envy" | |
"github.com/gobuffalo/packr/v2/jam/parser" | |
"github.com/gobuffalo/packr/v2/jam/store" | |
"github.com/gobuffalo/packr/v2/plog" | |
"github.com/google/go-cloud/blob" | |
"github.com/google/go-cloud/blob/s3blob" | |
"github.com/pkg/errors" | |
) | |
var _ store.Store = &S3Store{} | |
type S3Store struct { | |
*store.Disk | |
} | |
func New(box *parser.Box) *S3Store { | |
return &S3Store{ | |
Disk: store.NewDisk(box.AbsPath, box.Package), | |
} | |
} | |
func (s *S3Store) Pack(box *parser.Box) error { | |
plog.Debug(s, "Pack", "box", box) | |
return filepath.Walk(box.AbsPath, func(path string, info os.FileInfo, err error) error { | |
if info.IsDir() { | |
return nil | |
} | |
return s.upload(box.Name, path) | |
}) | |
} | |
func (s *S3Store) upload(box string, path string) error { | |
return withBucket(func(ctx context.Context, buck *blob.Bucket) error { | |
w, err := buck.NewWriter(ctx, Key(box+path), &blob.WriterOptions{ | |
ContentType: "application/octet-stream", | |
}) | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
defer w.Close() | |
f, err := os.Open(path) | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
defer f.Close() | |
_, err = io.Copy(w, f) | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
return nil | |
}) | |
} | |
func withBucket(fn func(context.Context, *blob.Bucket) error) error { | |
ctx, cancel := context.WithTimeout(context.Background(), time.Second) | |
defer cancel() | |
key, err := envy.MustGet("S3_KEY") | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
secret, err := envy.MustGet("S3_SECRET") | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
config := aws.NewConfig() | |
config.Region = aws.String("us-east-1") | |
config.Credentials = credentials.NewStaticCredentialsFromCreds(credentials.Value{ | |
AccessKeyID: key, | |
SecretAccessKey: secret, | |
}) | |
sess, err := session.NewSession(config) | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
buck, err := s3blob.OpenBucket(ctx, sess, "s3packr-demo") | |
if err != nil { | |
return errors.WithStack(err) | |
} | |
return fn(ctx, buck) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment