forked from mystiq/dex
93 lines
2.2 KiB
Go
93 lines
2.2 KiB
Go
|
// 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
|
||
|
}
|