owncast/core/storageproviders/s3Storage.go

130 lines
3.1 KiB
Go
Raw Normal View History

package storageproviders
2020-06-03 10:34:05 +02:00
import (
"bufio"
"fmt"
2020-06-03 10:34:05 +02:00
"os"
"strings"
log "github.com/sirupsen/logrus"
"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/aws/aws-sdk-go/service/s3/s3manager"
"github.com/gabek/owncast/config"
"github.com/gabek/owncast/models"
2020-06-03 10:34:05 +02:00
)
//S3Storage is the s3 implementation of the ChunkStorageProvider
2020-06-03 10:34:05 +02:00
type S3Storage struct {
sess *session.Session
host string
s3Endpoint string
s3ServingEndpoint string
s3Region string
s3Bucket string
s3AccessKey string
s3Secret string
s3ACL string
2020-06-03 10:34:05 +02:00
}
//Setup sets up the s3 storage for saving the video to s3
func (s *S3Storage) Setup() error {
log.Trace("Setting up S3 for external storage of video...")
2020-06-03 10:34:05 +02:00
s.s3Endpoint = config.Config.S3.Endpoint
s.s3ServingEndpoint = config.Config.S3.ServingEndpoint
s.s3Region = config.Config.S3.Region
s.s3Bucket = config.Config.S3.Bucket
s.s3AccessKey = config.Config.S3.AccessKey
s.s3Secret = config.Config.S3.Secret
2020-07-28 06:41:51 +02:00
s.s3ACL = config.Config.S3.ACL
2020-06-03 10:34:05 +02:00
s.sess = s.connectAWS()
return nil
2020-06-03 10:34:05 +02:00
}
//Save saves the file to the s3 bucket
func (s *S3Storage) Save(filePath string, retryCount int) (string, error) {
2020-06-03 10:34:05 +02:00
// fmt.Println("Saving", filePath)
2020-06-09 18:31:27 +02:00
file, err := os.Open(filePath)
2020-06-03 10:34:05 +02:00
if err != nil {
return "", err
2020-06-03 10:34:05 +02:00
}
defer file.Close()
2020-06-03 10:34:05 +02:00
uploader := s3manager.NewUploader(s.sess)
2020-07-28 06:41:51 +02:00
uploadInput := &s3manager.UploadInput{
2020-06-03 10:34:05 +02:00
Bucket: aws.String(s.s3Bucket), // Bucket to be used
Key: aws.String(filePath), // Name of the file to be saved
Body: file, // File
2020-07-28 06:41:51 +02:00
}
if s.s3ACL != "" {
uploadInput.ACL = aws.String(s.s3ACL)
}
response, err := uploader.Upload(uploadInput)
2020-06-03 10:34:05 +02:00
if err != nil {
log.Trace("error uploading:", err.Error())
if retryCount < 4 {
log.Trace("Retrying...")
return s.Save(filePath, retryCount+1)
}
2020-06-03 10:34:05 +02:00
}
// fmt.Println("Uploaded", filePath, "to", response.Location)
return response.Location, nil
2020-06-03 10:34:05 +02:00
}
//GenerateRemotePlaylist implements the 'GenerateRemotePlaylist' method
func (s *S3Storage) GenerateRemotePlaylist(playlist string, variant models.Variant) string {
2020-06-03 10:34:05 +02:00
var newPlaylist = ""
scanner := bufio.NewScanner(strings.NewReader(playlist))
for scanner.Scan() {
line := scanner.Text()
if line[0:1] != "#" {
fullRemotePath := variant.GetSegmentForFilename(line)
if fullRemotePath == nil {
2020-06-09 10:52:15 +02:00
line = ""
} else if s.s3ServingEndpoint != "" {
line = fmt.Sprintf("%s/%s/%s", s.s3ServingEndpoint, config.Config.GetPrivateHLSSavePath(), fullRemotePath.RelativeUploadPath)
} else {
line = fullRemotePath.RemoteID
2020-06-09 10:52:15 +02:00
}
2020-06-03 10:34:05 +02:00
}
newPlaylist = newPlaylist + line + "\n"
}
return newPlaylist
}
func (s S3Storage) connectAWS() *session.Session {
creds := credentials.NewStaticCredentials(s.s3AccessKey, s.s3Secret, "")
_, err := creds.Get()
if err != nil {
2020-06-18 08:01:49 +02:00
log.Panicln(err)
2020-06-03 10:34:05 +02:00
}
sess, err := session.NewSession(
&aws.Config{
Region: aws.String(s.s3Region),
Credentials: creds,
Endpoint: aws.String(s.s3Endpoint),
S3ForcePathStyle: aws.Bool(true),
2020-06-03 10:34:05 +02:00
},
)
if err != nil {
2020-06-18 08:01:49 +02:00
log.Panicln(err)
2020-06-03 10:34:05 +02:00
}
return sess
}