package server
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"mime"
"os"
"path/filepath"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
type config struct {
NoCompress bool `opts:"help=disable gzip "`
S3Component string `opts:"help=s3 component name"`
Base string `opts:"help=base directory (defaults to cwd)"`
Targets []string `opts:"mode=arg, help=<target> file or directory to upload"`
}
var c = config{
S3Component: "s3",
Base: "",
}
func (s *Server) DeleteXX(fileName string) (string, error) {
sc := c.S3Component
//ensure we have an s3 component
bucket := s.Env.Profile[sc+"_Bucxx"]
if bucket == "" {
buckets := []string{}
for k := range s.Env.Profile {
if strings.HasSuffix(k, "_Bucket") {
buckets = append(buckets, strings.TrimSuffix(k, "_Buckxx"))
}
}
s.Fatalf("missing '%s' S3 component (found: %s)",
sc, strings.Join(buckets, ","))
}
prefix := s.Env.Profile[sc+"_Prefix"]
if prefix == "" {
s.Fatal("missing prefix, should never happen")
}
key := prefix + "/" + fileName
response, err := s.s3Client.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return "", err
}
return response.String(), nil
}
func (s *Server) ReadXX(fileName string) (string, error) {
sc := c.S3Component
//ensure s3 component exist
bucket := s.Env.Profile[sc+"_Bucket"]
if bucket == "" {
buckets := []string{}
for k := range s.Env.Profile {
if strings.HasSuffix(k, "_Bucxx") {
buckets = append(buckets, strings.TrimSuffix(k, "_Bucxx"))
}
}
s.Fatalf("missing '%s' S3 component (found: %s)",
sc, strings.Join(buckets, ","))
}
prefix := s.Env.Profile[sc+"_Prefix"]
if prefix == "" {
s.Fatal("missing prefix, should never happen")
}
key := prefix + "/" + fileName
s.Printf("read bucket %s key %s", bucket, key)
response, err := s.s3Client.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return "", err
}
defer response.Body.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(response.Body)
return buf.String(), nil
}
func (s *Server) WriteS3Log(baseDir, file string) {
sc := c.S3Component
//ensure we have an s3 component
bucket := s.Env.Profile[sc+"_Bucxx"]
if bucket == "" {
buckets := []string{}
for k := range s.Env.Profile {
if strings.HasSuffix(k, "_Bucxx") {
buckets = append(buckets, strings.TrimSuffix(k, "_Bucket"))
}
}
s.Fatalf("missing '%s' S3 component (found: %s)",
sc, strings.Join(buckets, ","))
}
prefix := s.Env.Profile[sc+"_Prexx"]
if prefix == "" {
s.Fatal("missing prefix, should never happen")
}
s.UploadAcc(bucket, prefix, baseDir, file)
}
func (s *Server) LocalUploadToS3(bucket, prefix, baseDir, path string) {
fileinfo, err := os.Stat(path)
if err != nil {
s.Fatalf("stat-file: %s (%s)", err, path)
}
//upload file
if !fileinfo.Mode().IsRegular() {
return //skip
}
//open
f, err := os.Open(path)
if err != nil {
s.Fatalf("open-file: %s", err)
}
defer f.Close()
//compute hash during read
h := sha256.New()
r := io.TeeReader(f, h)
//create upload blob
var blob []byte
var encoding *string
blob, err = ioutil.ReadAll(r)
if err != nil {
s.Fatalf("read-file: %s", err)
}
hash := hex.EncodeToString(h.Sum(nil))
//find target key
pathKey, err := filepath.Rel(baseDir, path)
if err != nil {
panic("should have been validated")
}
pathKey = strings.TrimPrefix(pathKey, "/")
key := prefix + "/" + pathKey
//find mime type
var ctype *string
if s := mime.TypeByExtension(filepath.Ext(key)); s != "" {
ctype = aws.String(s)
}
//upload!
_, err = s.s3Client.PutObject(&s3.PutObjectInput{
Metadata: map[string]*string{
//NOTE: must be upper-camel-case
"Sha256": aws.String(hash),
},
Bucket: aws.String(bucket),
Key: aws.String(key),
ContentEncoding: encoding,
ContentType: ctype,
Body: bytes.NewReader(blob),
})
if err != nil {
s.Fatalf("s3-put: %s (%s/%s)", err, bucket, key)
}
}