diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index 7e611e7a2eb..9339b06332a 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -21,6 +21,7 @@ import ( "log" "os" "os/exec" + "strings" "syscall" "time" @@ -29,7 +30,7 @@ import ( var ( ep = flag.String("entrypoint", "", "Original specified entrypoint to execute") - waitFile = flag.String("wait_file", "", "If specified, file to wait for") + waitFiles = flag.String("wait_file", "", "Comma-separated list of paths to wait for") waitFileContent = flag.Bool("wait_file_content", false, "If specified, expect wait_file to have content") postFile = flag.String("post_file", "", "If specified, file to write upon completion") @@ -41,7 +42,7 @@ func main() { e := entrypoint.Entrypointer{ Entrypoint: *ep, - WaitFile: *waitFile, + WaitFiles: strings.Split(*waitFiles, ","), WaitFileContent: *waitFileContent, PostFile: *postFile, Args: flag.Args(), diff --git a/pkg/entrypoint/entrypointer.go b/pkg/entrypoint/entrypointer.go index 845a0555fed..ac236fff51f 100644 --- a/pkg/entrypoint/entrypointer.go +++ b/pkg/entrypoint/entrypointer.go @@ -27,9 +27,9 @@ type Entrypointer struct { Entrypoint string // Args are the original specified args, if any. Args []string - // WaitFile is the file to wait for. If not specified, execution begins - // immediately. - WaitFile string + // WaitFiles is the set of files to wait for. If empty, execution + // begins immediately. + WaitFiles []string // WaitFileContent indicates the WaitFile should have non-zero size // before continuing with execution. WaitFileContent bool @@ -65,10 +65,10 @@ type PostWriter interface { // Go optionally waits for a file, runs the command, and writes a // post file. func (e Entrypointer) Go() error { - if e.WaitFile != "" { - if err := e.Waiter.Wait(e.WaitFile, e.WaitFileContent); err != nil { + for _, f := range e.WaitFiles { + if err := e.Waiter.Wait(f, e.WaitFileContent); err != nil { // An error happened while waiting, so we bail - // *but* we write postfile to make next steps bail too + // *but* we write postfile to make next steps bail too. e.WritePostFile(e.PostFile, err) return err } diff --git a/pkg/entrypoint/entrypointer_test.go b/pkg/entrypoint/entrypointer_test.go index 89e9e329838..bed8b099308 100644 --- a/pkg/entrypoint/entrypointer_test.go +++ b/pkg/entrypoint/entrypointer_test.go @@ -26,10 +26,11 @@ import ( func TestEntrypointerFailures(t *testing.T) { for _, c := range []struct { - desc, waitFile, postFile string - waiter Waiter - runner Runner - expectedError string + desc, postFile string + waitFiles []string + waiter Waiter + runner Runner + expectedError string }{{ desc: "failing runner with no postFile", runner: &fakeErrorRunner{}, @@ -41,12 +42,12 @@ func TestEntrypointerFailures(t *testing.T) { postFile: "foo", }, { desc: "failing waiter with no postFile", - waitFile: "foo", + waitFiles: []string{"foo"}, waiter: &fakeErrorWaiter{}, expectedError: "waiter failed", }, { desc: "failing waiter with postFile", - waitFile: "foo", + waitFiles: []string{"foo"}, waiter: &fakeErrorWaiter{}, expectedError: "waiter failed", postFile: "bar", @@ -63,7 +64,7 @@ func TestEntrypointerFailures(t *testing.T) { fpw := &fakePostWriter{} err := Entrypointer{ Entrypoint: "echo", - WaitFile: c.waitFile, + WaitFiles: c.waitFiles, PostFile: c.postFile, Args: []string{"some", "args"}, Waiter: fw, @@ -93,8 +94,8 @@ func TestEntrypointerFailures(t *testing.T) { func TestEntrypointer(t *testing.T) { for _, c := range []struct { - desc, entrypoint, waitFile, postFile string - args []string + desc, entrypoint, postFile string + waitFiles, args []string }{{ desc: "do nothing", }, { @@ -107,22 +108,25 @@ func TestEntrypointer(t *testing.T) { desc: "just args", args: []string{"just", "args"}, }, { - desc: "wait file", - waitFile: "waitforme", + desc: "wait file", + waitFiles: []string{"waitforme"}, }, { desc: "post file", postFile: "writeme", }, { desc: "all together now", entrypoint: "echo", args: []string{"some", "args"}, - waitFile: "waitforme", - postFile: "writeme", + waitFiles: []string{"waitforme"}, + postFile: "writeme", + }, { + desc: "multiple wait files", + waitFiles: []string{"waitforme", "metoo", "methree"}, }} { t.Run(c.desc, func(t *testing.T) { fw, fr, fpw := &fakeWaiter{}, &fakeRunner{}, &fakePostWriter{} err := Entrypointer{ Entrypoint: c.entrypoint, - WaitFile: c.waitFile, + WaitFiles: c.waitFiles, PostFile: c.postFile, Args: c.args, Waiter: fw, @@ -133,14 +137,14 @@ func TestEntrypointer(t *testing.T) { t.Fatalf("Entrypointer failed: %v", err) } - if c.waitFile != "" { + if len(c.waitFiles) > 0 { if fw.waited == nil { t.Error("Wanted waited file, got nil") - } else if *fw.waited != c.waitFile { - t.Errorf("Waited for %q, want %q", *fw.waited, c.waitFile) + } else if !reflect.DeepEqual(fw.waited, c.waitFiles) { + t.Errorf("Waited for %v, want %v", fw.waited, c.waitFiles) } } - if c.waitFile == "" && fw.waited != nil { + if len(c.waitFiles) == 0 && fw.waited != nil { t.Errorf("Waited for file when not required") } @@ -173,10 +177,10 @@ func TestEntrypointer(t *testing.T) { } } -type fakeWaiter struct{ waited *string } +type fakeWaiter struct{ waited []string } -func (f *fakeWaiter) Wait(file string, expectContent bool) error { - f.waited = &file +func (f *fakeWaiter) Wait(file string, _ bool) error { + f.waited = append(f.waited, file) return nil }