Skip to content

Instantly share code, notes, and snippets.

@kmtr
Created March 4, 2019 14:29
Show Gist options
  • Save kmtr/1c81d5ed6dcac8d130afcd6866bd3f19 to your computer and use it in GitHub Desktop.
Save kmtr/1c81d5ed6dcac8d130afcd6866bd3f19 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"log"
"os"
"os/exec"
"strings"
"sync"
)
func runDockerPs(ctx context.Context) (string, error) {
cmd := exec.CommandContext(ctx, "docker", "ps", `--format`, `"{{.Ports}}"`)
out, err := cmd.Output()
return string(out), err
}
func runSocat(ctx context.Context, port string) error {
xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
cmdCatDockerPid := exec.Command("cat", fmt.Sprintf("%s/docker.pid", xdgRuntimeDir))
pid, err := cmdCatDockerPid.Output()
if err != nil {
return err
}
cmd := exec.CommandContext(ctx, "socat",
`-t`,
`--`,
fmt.Sprintf(`TCP-LISTEN:%s,reuseaddr,fork`, port),
fmt.Sprintf(`EXEC:"nsenter -U -n -t %s socat -t -- STDIN TCP4\:127.0.0.1\:%s"`, pid, port),
)
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func filterPort(out string) []string {
portSet := map[string]bool{}
ports := []string{}
lines := strings.Split(out, "\n")
for _, line := range lines {
fwds := strings.Split(line, ",")
for _, fwd := range fwds {
hostContainer := strings.Split(fwd, "->")
if len(hostContainer) == 2 {
host := hostContainer[0]
urlPort := strings.Split(host, ":")
port := urlPort[1]
if !portSet[port] {
portSet[port] = true
ports = append(ports, port)
}
}
}
}
return ports
}
func main() {
ctx := context.Background()
out, err := runDockerPs(ctx)
if err != nil {
log.Print(err)
return
}
ports := filterPort(out)
log.Print(ports)
wg := &sync.WaitGroup{}
for _, port := range ports {
log.Printf("socat: %s", port)
wg.Add(1)
go func(port string) {
if err = runSocat(context.Background(), port); err != nil {
log.Print(err)
}
}(port)
}
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment