// Package main provides a utility program to launch the Dex container process with an optional // templating step (provided by gomplate). // // This was originally written as a shell script, but we rewrote it as a Go program so that it could // run as a raw binary in a distroless container. package main import ( "fmt" "os" "os/exec" "strings" "syscall" ) func main() { // Note that this docker-entrypoint program is args[0], and it is provided with the true process // args. args := os.Args[1:] if err := run(args, realExec, realWhich); err != nil { fmt.Println("error:", err.Error()) os.Exit(1) } } func realExec(fork bool, args ...string) error { if fork { if output, err := exec.Command(args[0], args[1:]...).CombinedOutput(); err != nil { return fmt.Errorf("cannot fork/exec command %s: %w (output: %q)", args, err, string(output)) } return nil } argv0, err := exec.LookPath(args[0]) if err != nil { return fmt.Errorf("cannot lookup path for command %s: %w", args[0], err) } if err := syscall.Exec(argv0, args, os.Environ()); err != nil { return fmt.Errorf("cannot exec command %s (%q): %w", args, argv0, err) } return nil } func realWhich(path string) string { fullPath, err := exec.LookPath(path) if err != nil { return "" } return fullPath } func run(args []string, execFunc func(bool, ...string) error, whichFunc func(string) string) error { if args[0] != "dex" && args[0] != whichFunc("dex") { return execFunc(false, args...) } if args[1] != "serve" { return execFunc(false, args...) } newArgs := []string{} for _, tplCandidate := range args { if hasSuffixes(tplCandidate, ".tpl", ".tmpl", ".yaml") { tmpFile, err := os.CreateTemp("/tmp", "dex.config.yaml-*") if err != nil { return fmt.Errorf("cannot create temp file: %w", err) } if err := execFunc(true, "gomplate", "-f", tplCandidate, "-o", tmpFile.Name()); err != nil { return err } newArgs = append(newArgs, tmpFile.Name()) } else { newArgs = append(newArgs, tplCandidate) } } return execFunc(false, newArgs...) } func hasSuffixes(s string, suffixes ...string) bool { for _, suffix := range suffixes { if strings.HasSuffix(s, suffix) { return true } } return false }