~edwargix/git.sr.ht

ca92f1c0aa9cd2461d8834ab26441c60b3ac3def — наб 4 years ago c98c344
Pipe the deliveries and payload into stage 3 instead of passing them in argv

Also removes a useless chdir to the cwd in the fork

Closes: ~sircmpwn/git.sr.ht#279
2 files changed, 36 insertions(+), 8 deletions(-)

M gitsrht-update-hook/post-update.go
M gitsrht-update-hook/stage-3.go
M gitsrht-update-hook/post-update.go => gitsrht-update-hook/post-update.go +17 -6
@@ 6,6 6,7 @@ import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"syscall"



@@ 335,28 336,38 @@ func postUpdate() {
		return
	}

	// Run stage 3 asyncronously - the last few tasks can be done without
	// Run stage 3 asynchronously - the last few tasks can be done without
	// blocking the pusher's terminal.
	wd, err := os.Getwd()
	if err != nil {
	var stage3Pipe [2]int
	if err := syscall.Pipe(stage3Pipe[:]); err != nil {
		log.Fatalf("Failed to execute stage 3: %v", err)
	}
	syscall.CloseOnExec(stage3Pipe[1])

	procAttr := syscall.ProcAttr{
		Dir:   wd,
		Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()},
		Dir:   "",
		Files: []uintptr{uintptr(stage3Pipe[0]), os.Stdout.Fd(), os.Stderr.Fd()},
		Env:   os.Environ(),
		Sys: &syscall.SysProcAttr{
			Foreground: false,
		},
	}
	pid, err := syscall.ForkExec(hook, []string{
		"hooks/stage-3", string(deliveriesJson), string(payloadBytes),
		"hooks/stage-3",
		strconv.Itoa(len(deliveriesJson)), strconv.Itoa(len(payloadBytes)),
	}, &procAttr)
	if err != nil {
		log.Fatalf("Failed to execute stage 3: %v", err)
	}

	stage3File := os.NewFile(uintptr(stage3Pipe[1]), "stage3 IPC")
	if _, err = stage3File.Write(deliveriesJson); err != nil {
		log.Fatalf("Failed to execute stage 3: %v", err)
	}
	if _, err = stage3File.Write(payloadBytes); err != nil {
		log.Fatalf("Failed to execute stage 3: %v", err)
	}

	logger.Printf("Executing stage 3 to record %d sync deliveries and make "+
		"%d async deliveries (pid %d)", len(deliveries),
		len(dbinfo.AsyncWebhooks), pid)

M gitsrht-update-hook/stage-3.go => gitsrht-update-hook/stage-3.go +19 -2
@@ 4,6 4,7 @@ import (
	"database/sql"
	"encoding/json"
	"os"
	"strconv"

	_ "github.com/lib/pq"
)


@@ 30,10 31,26 @@ func stage3() {

	var subscriptions []WebhookSubscription
	var deliveries []WebhookDelivery
	if err := json.Unmarshal([]byte(os.Args[1]), &deliveries); err != nil {
	deliveriesJsonLen, err := strconv.Atoi(os.Args[1])
	if err != nil {
		logger.Fatalf("deliveriesJson length \"%v\": %v", string(os.Args[1]), err)
	}
	deliveriesJson := make([]byte, deliveriesJsonLen)
	if read, err := os.Stdin.Read(deliveriesJson); read != len(deliveriesJson) {
		logger.Fatalf("Failed to read deliveries: %v, %v", read, err)
	}
	if err := json.Unmarshal(deliveriesJson, &deliveries); err != nil {
		logger.Fatalf("Unable to unmarhsal delivery array: %v", err)
	}
	payload := []byte(os.Args[2])

	payloadLen, err := strconv.Atoi(os.Args[2])
	if err != nil {
		logger.Fatalf("payload length \"%v\": %v", string(os.Args[2]), err)
	}
	payload := make([]byte, payloadLen)
	if read, err := os.Stdin.Read(payload); read != len(payload) {
		logger.Fatalf("Failed to read payload: %v, %v", read, err)
	}

	var rows *sql.Rows
	if rows, err = db.Query(`