Add postfinish hook

This commit is contained in:
Marius 2016-02-22 12:53:15 +01:00
parent 67d7757e9f
commit dbd4d54b4d
2 changed files with 52 additions and 1 deletions

4
.hooks/postfinish Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Upload finished"
printenv

View File

@ -7,6 +7,10 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time" "time"
"github.com/tus/tusd" "github.com/tus/tusd"
@ -32,11 +36,14 @@ var storeSize int64
var basepath string var basepath string
var timeout int64 var timeout int64
var s3Bucket string var s3Bucket string
var hooksDir string
var version bool var version bool
var stdout = log.New(os.Stdout, "[tusd] ", 0) var stdout = log.New(os.Stdout, "[tusd] ", 0)
var stderr = log.New(os.Stderr, "[tusd] ", 0) var stderr = log.New(os.Stderr, "[tusd] ", 0)
var hookInstalled bool
func init() { func init() {
flag.StringVar(&httpHost, "host", "0.0.0.0", "Host to bind HTTP server to") flag.StringVar(&httpHost, "host", "0.0.0.0", "Host to bind HTTP server to")
flag.StringVar(&httpPort, "port", "1080", "Port to bind HTTP server to") flag.StringVar(&httpPort, "port", "1080", "Port to bind HTTP server to")
@ -46,9 +53,17 @@ func init() {
flag.StringVar(&basepath, "base-path", "/files/", "Basepath of the HTTP server") flag.StringVar(&basepath, "base-path", "/files/", "Basepath of the HTTP server")
flag.Int64Var(&timeout, "timeout", 30*1000, "Read timeout for connections in milliseconds") flag.Int64Var(&timeout, "timeout", 30*1000, "Read timeout for connections in milliseconds")
flag.StringVar(&s3Bucket, "s3-bucket", "", "Use AWS S3 with this bucket as storage backend (requires the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION environment variables to be set)") flag.StringVar(&s3Bucket, "s3-bucket", "", "Use AWS S3 with this bucket as storage backend (requires the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION environment variables to be set)")
flag.StringVar(&hooksDir, "hooks-dir", "", "")
flag.BoolVar(&version, "version", false, "Print tusd version information") flag.BoolVar(&version, "version", false, "Print tusd version information")
flag.Parse() flag.Parse()
if hooksDir != "" {
hooksDir, _ = filepath.Abs(hooksDir)
hookInstalled = true
stdout.Printf("Using '%s' for hooks", hooksDir)
}
} }
func main() { func main() {
@ -104,7 +119,7 @@ func main() {
for { for {
select { select {
case info := <-handler.CompleteUploads: case info := <-handler.CompleteUploads:
stdout.Printf("Upload %s (%d bytes) finished\n", info.ID, info.Size) invokeHook(info)
} }
} }
}() }()
@ -122,6 +137,38 @@ func main() {
} }
} }
func invokeHook(info tusd.FileInfo) {
stdout.Printf("Upload %s (%d bytes) finished\n", info.ID, info.Size)
if !hookInstalled {
return
}
stdout.Println("Invoking hooks…")
cmd := exec.Command(hooksDir + "/postfinish")
env := os.Environ()
env = append(env, "TUS_ID="+info.ID)
env = append(env, "TUS_SIZE="+strconv.FormatInt(info.Size, 10))
for k, v := range info.MetaData {
k = strings.ToUpper(k)
env = append(env, "TUS_METADATA_"+k+"="+v)
}
cmd.Env = env
cmd.Dir = hooksDir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
go func() {
err := cmd.Run()
if err != nil {
stderr.Printf("Error running postfinish hook for %s: %s", info.ID, err)
}
}()
}
// Listener wraps a net.Listener, and gives a place to store the timeout // Listener wraps a net.Listener, and gives a place to store the timeout
// parameters. On Accept, it will wrap the net.Conn with our own Conn for us. // parameters. On Accept, it will wrap the net.Conn with our own Conn for us.
// Original implementation taken from https://gist.github.com/jbardin/9663312 // Original implementation taken from https://gist.github.com/jbardin/9663312