-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2378 from ankeesler/akeesler/distroless
distroless: Dockerfile works with distroless base image
- Loading branch information
Showing
5 changed files
with
223 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// 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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package main | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
) | ||
|
||
type execArgs struct { | ||
fork bool | ||
argPrefixes []string | ||
} | ||
|
||
func TestRun(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
args []string | ||
execReturns error | ||
whichReturns string | ||
wantExecArgs []execArgs | ||
wantErr error | ||
}{ | ||
{ | ||
name: "executable not dex", | ||
args: []string{"tuna", "fish"}, | ||
wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"tuna", "fish"}}}, | ||
}, | ||
{ | ||
name: "executable is full path to dex", | ||
args: []string{"/usr/local/bin/dex", "marshmallow", "zelda"}, | ||
whichReturns: "/usr/local/bin/dex", | ||
wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"/usr/local/bin/dex", "marshmallow", "zelda"}}}, | ||
}, | ||
{ | ||
name: "command is not serve", | ||
args: []string{"dex", "marshmallow", "zelda"}, | ||
wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"dex", "marshmallow", "zelda"}}}, | ||
}, | ||
{ | ||
name: "no templates", | ||
args: []string{"dex", "serve", "config.yaml.not-a-template"}, | ||
wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"dex", "serve", "config.yaml.not-a-template"}}}, | ||
}, | ||
{ | ||
name: "no templates", | ||
args: []string{"dex", "serve", "config.yaml.not-a-template"}, | ||
wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"dex", "serve", "config.yaml.not-a-template"}}}, | ||
}, | ||
{ | ||
name: ".tpl template", | ||
args: []string{"dex", "serve", "config.tpl"}, | ||
wantExecArgs: []execArgs{ | ||
{fork: true, argPrefixes: []string{"gomplate", "-f", "config.tpl", "-o", "/tmp/dex.config.yaml-"}}, | ||
{fork: false, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, | ||
}, | ||
}, | ||
{ | ||
name: ".tmpl template", | ||
args: []string{"dex", "serve", "config.tmpl"}, | ||
wantExecArgs: []execArgs{ | ||
{fork: true, argPrefixes: []string{"gomplate", "-f", "config.tmpl", "-o", "/tmp/dex.config.yaml-"}}, | ||
{fork: false, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, | ||
}, | ||
}, | ||
{ | ||
name: ".yaml template", | ||
args: []string{"dex", "serve", "some/path/config.yaml"}, | ||
wantExecArgs: []execArgs{ | ||
{fork: true, argPrefixes: []string{"gomplate", "-f", "some/path/config.yaml", "-o", "/tmp/dex.config.yaml-"}}, | ||
{fork: false, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, | ||
}, | ||
}, | ||
} | ||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
var gotExecForks []bool | ||
var gotExecArgs [][]string | ||
fakeExec := func(fork bool, args ...string) error { | ||
gotExecForks = append(gotExecForks, fork) | ||
gotExecArgs = append(gotExecArgs, args) | ||
return test.execReturns | ||
} | ||
|
||
fakeWhich := func(_ string) string { return test.whichReturns } | ||
|
||
gotErr := run(test.args, fakeExec, fakeWhich) | ||
if (test.wantErr == nil) != (gotErr == nil) { | ||
t.Errorf("wanted error %s, got %s", test.wantErr, gotErr) | ||
} | ||
if !execArgsMatch(test.wantExecArgs, gotExecForks, gotExecArgs) { | ||
t.Errorf("wanted exec args %+v, got %+v %+v", test.wantExecArgs, gotExecForks, gotExecArgs) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func execArgsMatch(wantExecArgs []execArgs, gotForks []bool, gotExecArgs [][]string) bool { | ||
if len(wantExecArgs) != len(gotForks) { | ||
return false | ||
} | ||
|
||
for i := range wantExecArgs { | ||
if wantExecArgs[i].fork != gotForks[i] { | ||
return false | ||
} | ||
for j := range wantExecArgs[i].argPrefixes { | ||
if !strings.HasPrefix(gotExecArgs[i][j], wantExecArgs[i].argPrefixes[j]) { | ||
return false | ||
} | ||
} | ||
} | ||
|
||
return true | ||
} |
This file was deleted.
Oops, something went wrong.