Skip to content

Commit

Permalink
Retrieve error handling (#453)
Browse files Browse the repository at this point in the history
* Add errgroup dependency

Signed-off-by: liz <liz@heptio.com>

* client.Retrieve now returns an error channel instead of error

sonobuoy retrieve now has better, more user-friendly error handling

closes #407

Signed-off-by: liz <liz@heptio.com>
  • Loading branch information
liztio authored and timothysc committed Jul 9, 2018
1 parent 87cf469 commit 3d46d23
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 23 deletions.
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@
[[constraint]]
branch = "release-8.0"
name = "k8s.io/client-go"

[[constraint]]
branch = "master"
name = "golang.org/x/sync"
19 changes: 15 additions & 4 deletions cmd/sonobuoy/app/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ limitations under the License.
package app

import (
"fmt"
"os"
"path/filepath"

"github.com/heptio/sonobuoy/pkg/client"
"github.com/heptio/sonobuoy/pkg/errlog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
"k8s.io/client-go/util/exec"
)

var (
Expand Down Expand Up @@ -70,15 +73,23 @@ func retrieveResults(cmd *cobra.Command, args []string) {
}

// Get a reader that contains the tar output of the results directory.
reader, err := sbc.RetrieveResults(&client.RetrieveConfig{Namespace: rcvFlags.namespace})
reader, ec := sbc.RetrieveResults(&client.RetrieveConfig{Namespace: rcvFlags.namespace})
if err != nil {
errlog.LogError(err)
os.Exit(1)
}

// Extract the tar output into a local directory under the prefix.
err = client.UntarAll(reader, outDir, prefix)
if err != nil {
eg := &errgroup.Group{}
eg.Go(func() error { return <-ec })
eg.Go(func() error { return client.UntarAll(reader, outDir, prefix) })

err = eg.Wait()
if _, ok := err.(exec.CodeExitError); ok {
fmt.Fprintln(os.Stderr, "Results not ready yet. Check `sonobuoy status` for status.")
os.Exit(1)

} else if err != nil {
fmt.Fprintf(os.Stderr, "error retrieving results: %v\n", err)
os.Exit(2)
}
}
2 changes: 1 addition & 1 deletion pkg/client/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ type Interface interface {
// GenerateManifest fills in a template with a Sonobuoy config
GenerateManifest(cfg *GenConfig) ([]byte, error)
// RetrieveResults copies results from a sonobuoy run into a Reader in tar format.
RetrieveResults(cfg *RetrieveConfig) (io.Reader, error)
RetrieveResults(cfg *RetrieveConfig) (io.Reader, <-chan error)
// GetStatus determines the status of the sonobuoy run in order to assist the user.
GetStatus(namespace string) (*aggregation.Status, error)
// LogReader returns a reader that contains a merged stream of sonobuoy logs.
Expand Down
37 changes: 20 additions & 17 deletions pkg/client/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import (
"path"
"path/filepath"

"github.com/sirupsen/logrus"

"github.com/heptio/sonobuoy/pkg/config"
"github.com/pkg/errors"

Expand All @@ -34,10 +32,19 @@ import (
"k8s.io/client-go/tools/remotecommand"
)

func (c *SonobuoyClient) RetrieveResults(cfg *RetrieveConfig) (io.Reader, error) {
var tarCommand = []string{
"/usr/bin/env",
"bash",
"-c",
fmt.Sprintf("tar cf - %s/*.tar.gz", config.MasterResultsPath),
}

func (c *SonobuoyClient) RetrieveResults(cfg *RetrieveConfig) (io.Reader, <-chan error) {
ec := make(chan error, 1)
client, err := c.Client()
if err != nil {
return nil, err
ec <- err
return nil, ec
}
restClient := client.CoreV1().RESTClient()
req := restClient.Post().
Expand All @@ -48,34 +55,30 @@ func (c *SonobuoyClient) RetrieveResults(cfg *RetrieveConfig) (io.Reader, error)
Param("container", config.MasterContainerName)
req.VersionedParams(&corev1.PodExecOptions{
Container: config.MasterContainerName,
Command: []string{"tar", "cf", "-", config.MasterResultsPath},
Command: tarCommand,
Stdin: false,
Stdout: true,
Stderr: true,
Stderr: false,
}, scheme.ParameterCodec)
executor, err := remotecommand.NewSPDYExecutor(c.RestConfig, "POST", req.URL())
if err != nil {
return nil, err
ec <- err
return nil, ec
}
reader, writer := io.Pipe()
go func(writer *io.PipeWriter) {
go func(writer *io.PipeWriter, ec chan error) {
defer writer.Close()
defer close(ec)
err = executor.Stream(remotecommand.StreamOptions{
Stdout: writer,
Stderr: os.Stderr,
Tty: false,
})
if err != nil {
// Since this function returns an io.Reader to the consumer and does
// not buffer the entire (potentially large) output, RetrieveResults
// has to return the reader first to be read from. This means we
// either lose this error (easy) or provide a significantly more
// complex error mechanism for the consumer (hard).
logrus.Error(err)
ec <- err
}
}(writer)
}(writer, ec)

return reader, nil
return reader, ec
}

/** Everything below this marker has been copy/pasta'd from k8s/k8s. The only modification is exporting UntarAll **/
Expand Down
3 changes: 3 additions & 0 deletions vendor/golang.org/x/sync/AUTHORS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/golang.org/x/sync/CONTRIBUTORS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions vendor/golang.org/x/sync/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions vendor/golang.org/x/sync/PATENTS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 67 additions & 0 deletions vendor/golang.org/x/sync/errgroup/errgroup.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3d46d23

Please sign in to comment.