Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transparent init #5186

Merged
merged 7 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func doBuild(ctx context.Context, out io.Writer) error {
buildOut = ioutil.Discard
}

return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
bRes, err := r.Build(ctx, buildOut, targetArtifacts(opts, configs))

if quietFlag || buildOutputFlag != "" {
Expand Down
12 changes: 6 additions & 6 deletions cmd/skaffold/app/cmd/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (r *mockRunner) Stop() error {
}

func TestTagFlag(t *testing.T) {
mockCreateRunner := func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
mockCreateRunner := func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return &mockRunner{}, []*latest.SkaffoldConfig{{}}, nil
}

Expand All @@ -68,7 +68,7 @@ func TestTagFlag(t *testing.T) {
}

func TestQuietFlag(t *testing.T) {
mockCreateRunner := func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
mockCreateRunner := func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return &mockRunner{}, []*latest.SkaffoldConfig{{}}, nil
}

Expand Down Expand Up @@ -114,7 +114,7 @@ func TestQuietFlag(t *testing.T) {
}

func TestFileOutputFlag(t *testing.T) {
mockCreateRunner := func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
mockCreateRunner := func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return &mockRunner{}, []*latest.SkaffoldConfig{{}}, nil
}

Expand Down Expand Up @@ -177,16 +177,16 @@ func TestFileOutputFlag(t *testing.T) {
}

func TestRunBuild(t *testing.T) {
errRunner := func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
errRunner := func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return nil, nil, errors.New("some error")
}
mockCreateRunner := func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
mockCreateRunner := func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return &mockRunner{}, []*latest.SkaffoldConfig{{}}, nil
}

tests := []struct {
description string
mock func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error)
mock func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error)
shouldErr bool
}{
{
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestNewCmdDebug(t *testing.T) {
func TestDebugIndependentFromDev(t *testing.T) {
mockRunner := &mockDevRunner{}
testutil.Run(t, "DevDebug", func(t *testutil.T) {
t.Override(&createRunner, func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
t.Override(&createRunner, func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return mockRunner, []*latest.SkaffoldConfig{{}}, nil
})
t.Override(&opts, config.SkaffoldOptions{})
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func NewCmdDelete() *cobra.Command {
}

func doDelete(ctx context.Context, out io.Writer) error {
return withRunner(ctx, func(r runner.Runner, _ []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, _ []*latest.SkaffoldConfig) error {
return r.Cleanup(ctx, out)
})
}
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func NewCmdDeploy() *cobra.Command {
}

func doDeploy(ctx context.Context, out io.Writer) error {
return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
if opts.SkipRender {
return r.DeployAndLog(ctx, out, []build.Artifact{})
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func runDev(ctx context.Context, out io.Writer) error {
case <-ctx.Done():
return nil
default:
err := withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
err := withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
var artifacts []*latest.Artifact
for _, cfg := range configs {
artifacts = append(artifacts, cfg.Build.Artifacts...)
Expand Down
4 changes: 2 additions & 2 deletions cmd/skaffold/app/cmd/dev_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestDoDev(t *testing.T) {
hasDeployed: test.hasDeployed,
errDev: context.Canceled,
}
t.Override(&createRunner, func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
t.Override(&createRunner, func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return mockRunner, []*latest.SkaffoldConfig{{}}, nil
})
t.Override(&opts, config.SkaffoldOptions{
Expand Down Expand Up @@ -145,7 +145,7 @@ func TestDevConfigChange(t *testing.T) {
testutil.Run(t, "test config change", func(t *testutil.T) {
mockRunner := &mockConfigChangeRunner{}

t.Override(&createRunner, func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
t.Override(&createRunner, func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return mockRunner, []*latest.SkaffoldConfig{{}}, nil
})
t.Override(&opts, config.SkaffoldOptions{
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func NewCmdDiagnose() *cobra.Command {
}

func doDiagnose(ctx context.Context, out io.Writer) error {
runCtx, configs, err := runContext(opts)
runCtx, configs, err := runContext(out, opts)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func NewCmdFilter() *cobra.Command {
// runFilter loads the Kubernetes manifests from stdin and applies the debug transformations.
// Unlike `skaffold debug`, this filtering affects all images and not just the built artifacts.
func runFilter(ctx context.Context, out io.Writer, debuggingFilters bool, buildArtifacts []build.Artifact) error {
return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
manifestList, err := manifest.Load(os.Stdin)
if err != nil {
return fmt.Errorf("loading manifests: %w", err)
Expand Down
16 changes: 16 additions & 0 deletions cmd/skaffold/app/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,22 @@ var flagRegistry = []Flag{
FlagAddMethod: "Var",
DefinedOn: []string{"test", "deploy"},
},
{
Name: "try-transparent-init",
MarlonGamez marked this conversation as resolved.
Show resolved Hide resolved
Usage: "If true, skaffold will try to create a config for the user's run if it doesn't find one",
Value: &opts.TryTransparentInit,
DefValue: true,
FlagAddMethod: "BoolVar",
DefinedOn: []string{"debug", "dev", "run"},
},
{
Name: "skip-confirmation",
MarlonGamez marked this conversation as resolved.
Show resolved Hide resolved
Usage: "If true, skaffold will skip yes/no confirmation from the user and default to yes",
Value: &opts.SkipConfirmation,
DefValue: false,
FlagAddMethod: "BoolVar",
DefinedOn: []string{"debug", "dev", "run"},
},
}

func methodNameByType(v reflect.Value) string {
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/generate_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func NewCmdGeneratePipeline() *cobra.Command {
}

func doGeneratePipeline(ctx context.Context, out io.Writer) error {
return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
if err := r.GeneratePipeline(ctx, out, configs, configFiles, "pipeline.yaml"); err != nil {
return fmt.Errorf("generating : %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func doRender(ctx context.Context, out io.Writer) error {
buildOut = out
}

return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
var bRes []build.Artifact

if renderFromBuildOutputFile.String() != "" {
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func NewCmdRun() *cobra.Command {
}

func doRun(ctx context.Context, out io.Writer) error {
return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
bRes, err := r.Build(ctx, out, targetArtifacts(opts, configs))
if err != nil {
return fmt.Errorf("failed to build: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (r *mockRunRunner) DeployAndLog(context.Context, io.Writer, []build.Artifac
func TestBuildImageFlag(t *testing.T) {
testutil.Run(t, "", func(t *testutil.T) {
mockRunner := &mockRunRunner{}
t.Override(&createRunner, func(config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
t.Override(&createRunner, func(io.Writer, config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
return mockRunner, []*latest.SkaffoldConfig{{
Pipeline: latest.Pipeline{
Build: latest.BuildConfig{
Expand Down
93 changes: 61 additions & 32 deletions cmd/skaffold/app/cmd/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ import (
"context"
"errors"
"fmt"
"io"
"os"

"github.com/sirupsen/logrus"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/color"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
sErrors "github.com/GoogleContainerTools/skaffold/pkg/skaffold/errors"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/event"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/initializer"
initConfig "github.com/GoogleContainerTools/skaffold/pkg/skaffold/initializer/config"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/instrumentation"
kubectx "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/context"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner"
Expand All @@ -42,8 +46,8 @@ import (
// For tests
var createRunner = createNewRunner

func withRunner(ctx context.Context, action func(runner.Runner, []*latest.SkaffoldConfig) error) error {
runner, config, err := createRunner(opts)
func withRunner(ctx context.Context, out io.Writer, action func(runner.Runner, []*latest.SkaffoldConfig) error) error {
runner, config, err := createRunner(out, opts)
sErrors.SetSkaffoldOptions(opts)
if err != nil {
return err
Expand All @@ -55,8 +59,8 @@ func withRunner(ctx context.Context, action func(runner.Runner, []*latest.Skaffo
}

// createNewRunner creates a Runner and returns the SkaffoldConfig associated with it.
func createNewRunner(opts config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
runCtx, configs, err := runContext(opts)
func createNewRunner(out io.Writer, opts config.SkaffoldOptions) (runner.Runner, []*latest.SkaffoldConfig, error) {
runCtx, configs, err := runContext(out, opts)
if err != nil {
return nil, nil, err
}
Expand All @@ -71,10 +75,61 @@ func createNewRunner(opts config.SkaffoldOptions) (runner.Runner, []*latest.Skaf
return runner, configs, nil
}

func runContext(opts config.SkaffoldOptions) (*runcontext.RunContext, []*latest.SkaffoldConfig, error) {
func runContext(out io.Writer, opts config.SkaffoldOptions) (*runcontext.RunContext, []*latest.SkaffoldConfig, error) {
configs, pipelines, err := skaffoldConfig(out, opts)
if err != nil {
return nil, nil, err
}

// TODO: Should support per-config kubecontext. Right now we constrain all configs to define the same kubecontext.
kubectx.ConfigureKubeConfig(opts.KubeConfig, opts.KubeContext, configs[0].Deploy.KubeContext)

if err := validation.Process(configs); err != nil {
return nil, nil, fmt.Errorf("invalid skaffold config: %w", err)
}

runCtx, err := runcontext.GetRunContext(opts, pipelines)
if err != nil {
return nil, nil, fmt.Errorf("getting run context: %w", err)
}

if err := validation.ProcessWithRunContext(runCtx); err != nil {
return nil, nil, fmt.Errorf("invalid skaffold config: %w", err)
}

return runCtx, configs, nil
}

func setDefaultDeployer(configs []util.VersionedConfig) bool {
// set the default deployer only if no deployer is explicitly specified in any config
for _, cfg := range configs {
if cfg.(*latest.SkaffoldConfig).Deploy.DeployType != (latest.DeployType{}) {
return false
}
}
return true
}

// skaffoldConfig will try to parse the given opts.ConfigurationFile. If not found, it will try to automatically generate a config for the user
func skaffoldConfig(out io.Writer, opts config.SkaffoldOptions) ([]*latest.SkaffoldConfig, []latest.Pipeline, error) {
parsed, err := schema.ParseConfigAndUpgrade(opts.ConfigurationFile, latest.Version)
if err != nil {
if os.IsNotExist(errors.Unwrap(err)) {
if opts.TryTransparentInit && initializer.ValidCmd(opts) {
color.Default.Fprintf(out, "Skaffold config file %s not found - Trying to create one for you...\n", opts.ConfigurationFile)
config, err := initializer.Transparent(context.Background(), out, initConfig.Config{Opts: opts})
if err != nil {
return nil, nil, fmt.Errorf("unable to generate skaffold config file automatically - try running `skaffold init`: %w", err)
}
if config == nil {
return nil, nil, fmt.Errorf("user not continuing")
}

defaults.Set(config, true)

return []*latest.SkaffoldConfig{config}, []latest.Pipeline{config.Pipeline}, nil
}

return nil, nil, fmt.Errorf("skaffold config file %s not found - check your current working directory, or try running `skaffold init`", opts.ConfigurationFile)
}

Expand Down Expand Up @@ -105,33 +160,7 @@ func runContext(opts config.SkaffoldOptions) (*runcontext.RunContext, []*latest.
configs = append(configs, config)
}

// TODO: Should support per-config kubecontext. Right now we constrain all configs to define the same kubecontext.
kubectx.ConfigureKubeConfig(opts.KubeConfig, opts.KubeContext, configs[0].Deploy.KubeContext)

if err := validation.Process(configs); err != nil {
return nil, nil, fmt.Errorf("invalid skaffold config: %w", err)
}

runCtx, err := runcontext.GetRunContext(opts, pipelines)
if err != nil {
return nil, nil, fmt.Errorf("getting run context: %w", err)
}

if err := validation.ProcessWithRunContext(runCtx); err != nil {
return nil, nil, fmt.Errorf("invalid skaffold config: %w", err)
}

return runCtx, configs, nil
}

func setDefaultDeployer(configs []util.VersionedConfig) bool {
// set the default deployer only if no deployer is explicitly specified in any config
for _, cfg := range configs {
if cfg.(*latest.SkaffoldConfig).Deploy.DeployType != (latest.DeployType{}) {
return false
}
}
return true
return configs, pipelines, nil
}

func warnIfUpdateIsAvailable() {
Expand Down
3 changes: 2 additions & 1 deletion cmd/skaffold/app/cmd/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package cmd

import (
"fmt"
"io/ioutil"
"testing"

"github.com/blang/semver"
Expand Down Expand Up @@ -98,7 +99,7 @@ func TestCreateNewRunner(t *testing.T) {
Write("skaffold.yaml", fmt.Sprintf("apiVersion: %s\nkind: Config\n%s", latest.Version, test.config)).
Chdir()

_, _, err := createNewRunner(test.options)
_, _, err := createNewRunner(ioutil.Discard, test.options)

t.CheckError(test.shouldErr, err)
if test.expectedError != "" {
Expand Down
2 changes: 1 addition & 1 deletion cmd/skaffold/app/cmd/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func NewCmdTest() *cobra.Command {
}

func doTest(ctx context.Context, out io.Writer) error {
return withRunner(ctx, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
return withRunner(ctx, out, func(r runner.Runner, configs []*latest.SkaffoldConfig) error {
var artifacts []*latest.Artifact
for _, c := range configs {
artifacts = append(artifacts, c.Build.Artifacts...)
Expand Down