feat(vpn): VPN_UP_COMMAND and VPN_DOWN_COMMAND options

This commit is contained in:
Quentin McGaw
2026-03-08 16:06:16 +00:00
parent c0af198155
commit 57c53bc19e
14 changed files with 152 additions and 68 deletions
+1 -41
View File
@@ -3,10 +3,7 @@ package service
import (
"context"
"fmt"
"os/exec"
"strings"
"github.com/qdm12/gluetun/internal/command"
)
func runCommand(ctx context.Context, cmder Cmder, logger Logger,
@@ -20,42 +17,5 @@ func runCommand(ctx context.Context, cmder Cmder, logger Logger,
commandString := strings.ReplaceAll(commandTemplate, "{{PORTS}}", portsString)
commandString = strings.ReplaceAll(commandString, "{{PORT}}", portStrings[0])
commandString = strings.ReplaceAll(commandString, "{{VPN_INTERFACE}}", vpnInterface)
args, err := command.Split(commandString)
if err != nil {
return fmt.Errorf("parsing command: %w", err)
}
cmd := exec.CommandContext(ctx, args[0], args[1:]...) // #nosec G204
stdout, stderr, waitError, err := cmder.Start(cmd)
if err != nil {
return err
}
streamCtx, streamCancel := context.WithCancel(context.Background())
streamDone := make(chan struct{})
go streamLines(streamCtx, streamDone, logger, stdout, stderr)
err = <-waitError
streamCancel()
<-streamDone
return err
}
func streamLines(ctx context.Context, done chan<- struct{},
logger Logger, stdout, stderr <-chan string,
) {
defer close(done)
var line string
for {
select {
case <-ctx.Done():
return
case line = <-stdout:
logger.Info(line)
case line = <-stderr:
logger.Error(line)
}
}
return cmder.RunAndLog(ctx, commandString, logger)
}
+2 -3
View File
@@ -3,8 +3,8 @@ package service
import (
"context"
"net/netip"
"os/exec"
"github.com/qdm12/gluetun/internal/command"
"github.com/qdm12/gluetun/internal/provider/utils"
)
@@ -35,6 +35,5 @@ type PortForwarder interface {
}
type Cmder interface {
Start(cmd *exec.Cmd) (stdoutLines, stderrLines <-chan string,
waitError <-chan error, startErr error)
RunAndLog(ctx context.Context, command string, logger command.Logger) (err error)
}