chore(ci): test protonvpn Wireguard with port forwarding

This commit is contained in:
Quentin McGaw
2026-05-03 02:20:24 +00:00
parent 4bada8f0cd
commit f8400c1b1c
5 changed files with 39 additions and 20 deletions
+4 -2
View File
@@ -97,8 +97,10 @@ jobs:
- name: Run Gluetun container with Mullvad configuration - name: Run Gluetun container with Mullvad configuration
run: echo -e "${{ secrets.MULLVAD_WIREGUARD_PRIVATE_KEY }}\n${{ secrets.MULLVAD_WIREGUARD_ADDRESS }}" | ./ci/runner mullvad run: echo -e "${{ secrets.MULLVAD_WIREGUARD_PRIVATE_KEY }}\n${{ secrets.MULLVAD_WIREGUARD_ADDRESS }}" | ./ci/runner mullvad
- name: Run Gluetun container with ProtonVPN configuration - name: Run Gluetun container with ProtonVPN Wireguard and port forwarding
run: echo -e "${{ secrets.PROTONVPN_WIREGUARD_PRIVATE_KEY }}" | ./ci/runner protonvpn configuration
run: echo -e "${{ secrets.PROTONVPN_WIREGUARD_PRIVATE_KEY }}" | ./ci/runner
protonvpn-wireguard-port-forwarding
codeql: codeql:
runs-on: ubuntu-latest runs-on: ubuntu-latest
+2 -2
View File
@@ -23,8 +23,8 @@ func main() {
switch os.Args[1] { switch os.Args[1] {
case "mullvad": case "mullvad":
err = internal.MullvadTest(ctx, logger) err = internal.MullvadTest(ctx, logger)
case "protonvpn": case "protonvpn-wireguard-port-forwarding":
err = internal.ProtonVPNTest(ctx, logger) err = internal.ProtonVPNWireguardPortForwardingTest(ctx, logger)
default: default:
err = fmt.Errorf("unknown command: %s", os.Args[1]) err = fmt.Errorf("unknown command: %s", os.Args[1])
} }
+4 -1
View File
@@ -3,6 +3,8 @@ package internal
import ( import (
"context" "context"
"fmt" "fmt"
"regexp"
"time"
) )
func MullvadTest(ctx context.Context, logger Logger) error { func MullvadTest(ctx context.Context, logger Logger) error {
@@ -23,5 +25,6 @@ func MullvadTest(ctx context.Context, logger Logger) error {
"WIREGUARD_PRIVATE_KEY=" + secrets[0], "WIREGUARD_PRIVATE_KEY=" + secrets[0],
"WIREGUARD_ADDRESSES=" + secrets[1], "WIREGUARD_ADDRESSES=" + secrets[1],
} }
return simpleTest(ctx, env, logger) const timeout = 60 * time.Second
return runContainerTest(ctx, env, []*regexp.Regexp{successRegexp}, timeout, logger)
} }
+6 -2
View File
@@ -3,9 +3,11 @@ package internal
import ( import (
"context" "context"
"fmt" "fmt"
"regexp"
"time"
) )
func ProtonVPNTest(ctx context.Context, logger Logger) error { func ProtonVPNWireguardPortForwardingTest(ctx context.Context, logger Logger) error {
expectedSecrets := []string{ expectedSecrets := []string{
"Wireguard private key", "Wireguard private key",
} }
@@ -20,6 +22,8 @@ func ProtonVPNTest(ctx context.Context, logger Logger) error {
"LOG_LEVEL=debug", "LOG_LEVEL=debug",
"SERVER_COUNTRIES=United States", "SERVER_COUNTRIES=United States",
"WIREGUARD_PRIVATE_KEY=" + secrets[0], "WIREGUARD_PRIVATE_KEY=" + secrets[0],
"VPN_PORT_FORWARDING=on",
} }
return simpleTest(ctx, env, logger) const timeout = 80 * time.Second
return runContainerTest(ctx, env, []*regexp.Regexp{successRegexp, portForwardingRegexp}, timeout, logger)
} }
+23 -13
View File
@@ -16,8 +16,14 @@ import (
func ptrTo[T any](v T) *T { return &v } func ptrTo[T any](v T) *T { return &v }
func simpleTest(ctx context.Context, env []string, logger Logger) error { var (
const timeout = 60 * time.Second successRegexp = regexp.MustCompile(`^.+Public IP address is .+$`)
portForwardingRegexp = regexp.MustCompile(`port forwarded is \d`)
)
func runContainerTest(ctx context.Context, env []string,
regexps []*regexp.Regexp, timeout time.Duration, logger Logger,
) error {
ctx, cancel := context.WithTimeout(ctx, timeout) ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
@@ -57,7 +63,7 @@ func simpleTest(ctx context.Context, env []string, logger Logger) error {
return fmt.Errorf("starting container: %w", err) return fmt.Errorf("starting container: %w", err)
} }
return waitForLogLine(ctx, client, containerID, beforeStartTime, logger) return waitForLogLines(ctx, client, containerID, beforeStartTime, regexps, logger)
} }
func stopContainer(client *client.Client, containerID string) { func stopContainer(client *client.Client, containerID string) {
@@ -71,10 +77,8 @@ func stopContainer(client *client.Client, containerID string) {
} }
} }
var successRegexp = regexp.MustCompile(`^.+Public IP address is .+$`) func waitForLogLines(ctx context.Context, client *client.Client, containerID string,
beforeStartTime time.Time, regexps []*regexp.Regexp, logger Logger,
func waitForLogLine(ctx context.Context, client *client.Client, containerID string,
beforeStartTime time.Time, logger Logger,
) error { ) error {
logOptions := container.LogsOptions{ logOptions := container.LogsOptions{
ShowStdout: true, ShowStdout: true,
@@ -88,6 +92,8 @@ func waitForLogLine(ctx context.Context, client *client.Client, containerID stri
} }
defer reader.Close() defer reader.Close()
regexpMatched := 0
var linesSeen []string var linesSeen []string
scanner := bufio.NewScanner(reader) scanner := bufio.NewScanner(reader)
for ctx.Err() == nil { for ctx.Err() == nil {
@@ -97,21 +103,25 @@ func waitForLogLine(ctx context.Context, client *client.Client, containerID stri
line = line[8:] line = line[8:]
} }
linesSeen = append(linesSeen, line) linesSeen = append(linesSeen, line)
if successRegexp.MatchString(line) { regex := regexps[regexpMatched]
fmt.Println("✅ Success line logged") if regex.MatchString(line) {
return nil fmt.Println("✅ Expected line logged:", line)
if regexpMatched == len(regexps)-1 {
return nil
}
regexpMatched++
} }
continue continue
} }
err := scanner.Err() err := scanner.Err()
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
logSeenLines(logger, linesSeen) logSeenLines(linesSeen)
return fmt.Errorf("reading log stream: %w", err) return fmt.Errorf("reading log stream: %w", err)
} }
// The scanner is either done or cannot read because of EOF // The scanner is either done or cannot read because of EOF
logger.Info("the log scanner stopped") logger.Info("the log scanner stopped")
logSeenLines(logger, linesSeen) logSeenLines(linesSeen)
// Check if the container is still running // Check if the container is still running
inspect, err := client.ContainerInspect(ctx, containerID) inspect, err := client.ContainerInspect(ctx, containerID)
@@ -126,7 +136,7 @@ func waitForLogLine(ctx context.Context, client *client.Client, containerID stri
return ctx.Err() return ctx.Err()
} }
func logSeenLines(logger Logger, lines []string) { func logSeenLines(lines []string) {
fmt.Println("Logs seen so far:") fmt.Println("Logs seen so far:")
for _, line := range lines { for _, line := range lines {
fmt.Println(" " + line) fmt.Println(" " + line)