Skip to content

Commit

Permalink
Refactor entrypoint binary a bit in preparation for logging
Browse files Browse the repository at this point in the history
This PR splits the entrypoint bin in to separate files for the Runner,
Waiter and PostWriter types.

This is done because we're going to need to modify the Runner while
adding logging and I want to merge the refactoring noise separate from
the logic changes.
  • Loading branch information
Scott authored and tekton-robot committed Aug 5, 2019
1 parent 68dd5c9 commit 63b4873
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 77 deletions.
77 changes: 0 additions & 77 deletions cmd/entrypoint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"time"

"github.com/tektoncd/pipeline/pkg/entrypoint"
"golang.org/x/xerrors"
)

var (
Expand Down Expand Up @@ -70,79 +69,3 @@ func main() {
}
}
}

// TODO(jasonhall): Test that original exit code is propagated and that
// stdout/stderr are collected -- needs e2e tests.

// RealWaiter actually waits for files, by polling.
type RealWaiter struct{}

var _ entrypoint.Waiter = (*RealWaiter)(nil)

// Wait watches a file and returns when either a) the file exists and, if
// the expectContent argument is true, the file has non-zero size or b) there
// is an error polling the file.
//
// If the passed-in file is an empty string then this function returns
// immediately.
//
// If a file of the same name with a ".err" extension exists then this Wait
// will end with a skipError.
func (*RealWaiter) Wait(file string, expectContent bool) error {
if file == "" {
return nil
}
for ; ; time.Sleep(waitPollingInterval) {
if info, err := os.Stat(file); err == nil {
if !expectContent || info.Size() > 0 {
return nil
}
} else if !os.IsNotExist(err) {
return xerrors.Errorf("Waiting for %q: %w", file, err)
}
if _, err := os.Stat(file + ".err"); err == nil {
return skipError("error file present, bail and skip the step")
}
}
}

// RealRunner actually runs commands.
type RealRunner struct{}

var _ entrypoint.Runner = (*RealRunner)(nil)

func (*RealRunner) Run(args ...string) error {
if len(args) == 0 {
return nil
}
name, args := args[0], args[1:]

cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Run(); err != nil {
return err
}
return nil
}

// RealPostWriter actually writes files.
type RealPostWriter struct{}

var _ entrypoint.PostWriter = (*RealPostWriter)(nil)

func (*RealPostWriter) Write(file string) {
if file == "" {
return
}
if _, err := os.Create(file); err != nil {
log.Fatalf("Creating %q: %v", file, err)
}
}

type skipError string

func (e skipError) Error() string {
return string(e)
}
22 changes: 22 additions & 0 deletions cmd/entrypoint/post_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"log"
"os"

"github.com/tektoncd/pipeline/pkg/entrypoint"
)

// RealPostWriter actually writes files.
type RealPostWriter struct{}

var _ entrypoint.PostWriter = (*RealPostWriter)(nil)

func (*RealPostWriter) Write(file string) {
if file == "" {
return
}
if _, err := os.Create(file); err != nil {
log.Fatalf("Creating %q: %v", file, err)
}
}
32 changes: 32 additions & 0 deletions cmd/entrypoint/runner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"os"
"os/exec"

"github.com/tektoncd/pipeline/pkg/entrypoint"
)

// TODO(jasonhall): Test that original exit code is propagated and that
// stdout/stderr are collected -- needs e2e tests.

// RealRunner actually runs commands.
type RealRunner struct{}

var _ entrypoint.Runner = (*RealRunner)(nil)

func (*RealRunner) Run(args ...string) error {
if len(args) == 0 {
return nil
}
name, args := args[0], args[1:]

cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Run(); err != nil {
return err
}
return nil
}
47 changes: 47 additions & 0 deletions cmd/entrypoint/waiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

import (
"os"
"time"

"github.com/tektoncd/pipeline/pkg/entrypoint"
"golang.org/x/xerrors"
)

// RealWaiter actually waits for files, by polling.
type RealWaiter struct{}

var _ entrypoint.Waiter = (*RealWaiter)(nil)

// Wait watches a file and returns when either a) the file exists and, if
// the expectContent argument is true, the file has non-zero size or b) there
// is an error polling the file.
//
// If the passed-in file is an empty string then this function returns
// immediately.
//
// If a file of the same name with a ".err" extension exists then this Wait
// will end with a skipError.
func (*RealWaiter) Wait(file string, expectContent bool) error {
if file == "" {
return nil
}
for ; ; time.Sleep(waitPollingInterval) {
if info, err := os.Stat(file); err == nil {
if !expectContent || info.Size() > 0 {
return nil
}
} else if !os.IsNotExist(err) {
return xerrors.Errorf("Waiting for %q: %w", file, err)
}
if _, err := os.Stat(file + ".err"); err == nil {
return skipError("error file present, bail and skip the step")
}
}
}

type skipError string

func (e skipError) Error() string {
return string(e)
}
File renamed without changes.

0 comments on commit 63b4873

Please sign in to comment.