diff --git a/pkg/application/app.go b/pkg/application/app.go index b4ab54296..40b7d6ed3 100644 --- a/pkg/application/app.go +++ b/pkg/application/app.go @@ -47,7 +47,7 @@ func LoadFromFile(fileName string) (*Application, error) { _, err = os.Stat(fileName) if err != nil { if os.IsNotExist(err) { - return newApplication(nil, tm), nil + return nil, err } return nil, err } @@ -60,13 +60,36 @@ func LoadFromFile(fileName string) (*Application, error) { return app, app.Validate() } +// NewEmptyApplication new empty application, only set tm +func NewEmptyApplication() (*Application, error) { + tm, err := template.Load() + if err != nil { + return nil, err + } + return newApplication(nil, tm), nil +} + +// IsNotFound is application not found error +func IsNotFound(appName string, err error) bool { + return err != nil && err.Error() == fmt.Sprintf(`application "%s" not found`, appName) +} + // Load will load application with env and name from default vela home dir. func Load(envName, appName string) (*Application, error) { appDir, err := getApplicationDir(envName) if err != nil { return nil, fmt.Errorf("get app dir from env %s err %w", envName, err) } - return LoadFromFile(filepath.Join(appDir, appName+".yaml")) + app, err := LoadFromFile(filepath.Join(appDir, appName+".yaml")) + + if err != nil { + if os.IsNotExist(err) { + return nil, fmt.Errorf(`application "%s" not found`, appName) + } + return nil, err + } + + return app, nil } // Delete will delete an app along with it's appfile. diff --git a/pkg/application/app_test.go b/pkg/application/app_test.go index da279254a..3b3b80be5 100644 --- a/pkg/application/app_test.go +++ b/pkg/application/app_test.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "testing" + "time" "github.com/ghodss/yaml" "github.com/stretchr/testify/assert" @@ -136,3 +137,18 @@ services: assert.Equal(t, c.ExpTraits, traits, caseName) } } + +func TestLoadNotExistsApplication(t *testing.T) { + caseName := "load not exists application" + + now := time.Now().Unix() + appName := fmt.Sprintf("test-app-%d", now) + + app, err := Load(types.DefaultEnvName, appName) + + assert.Nil(t, app, caseName) + assert.Error(t, err, caseName) + + errString := fmt.Sprintf(`application "%s" not found`, appName) + assert.EqualError(t, err, errString, caseName) +} diff --git a/pkg/commands/exec.go b/pkg/commands/exec.go index b376d0657..a49b9a761 100644 --- a/pkg/commands/exec.go +++ b/pkg/commands/exec.go @@ -116,11 +116,11 @@ func (o *VelaExecOptions) Init(ctx context.Context, c *cobra.Command, argsIn []s if err != nil { return err } + o.Env = env app, err := application.Load(env.Name, o.Args[0]) if err != nil { return err } - o.Env = env o.App = app cf := genericclioptions.NewConfigFlags(true) diff --git a/pkg/commands/exec_test.go b/pkg/commands/exec_test.go index bcf9de85f..3fc4559c6 100644 --- a/pkg/commands/exec_test.go +++ b/pkg/commands/exec_test.go @@ -2,6 +2,7 @@ package commands import ( "context" + "fmt" "os" "testing" @@ -9,9 +10,11 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/kubernetes/fake" "k8s.io/kubectl/pkg/cmd/exec" cmdtesting "k8s.io/kubectl/pkg/cmd/testing" + k8scmdutil "k8s.io/kubectl/pkg/cmd/util" "github.com/oam-dev/kubevela/apis/types" "github.com/oam-dev/kubevela/pkg/appfile" @@ -47,7 +50,8 @@ func TestExecCommand(t *testing.T) { }), } err := o.Init(context.Background(), cmd, []string{"fakeApp"}) - assert.NoError(t, err) + errString := fmt.Sprintf(`application "%s" not found`, "fakeApp") + assert.EqualError(t, err, errString) fakeApp := &application.Application{ AppFile: &appfile.AppFile{ Name: "fakeApp", @@ -57,6 +61,10 @@ func TestExecCommand(t *testing.T) { }, } o.App = fakeApp + + cf := genericclioptions.NewConfigFlags(true) + cf.Namespace = &o.Env.Namespace + o.f = k8scmdutil.NewFactory(k8scmdutil.NewMatchVersionFlags(cf)) err = o.Complete() assert.NoError(t, err) } diff --git a/pkg/commands/portforward_test.go b/pkg/commands/portforward_test.go index 42cb0f8ac..a4224fec6 100644 --- a/pkg/commands/portforward_test.go +++ b/pkg/commands/portforward_test.go @@ -2,6 +2,7 @@ package commands import ( "context" + "fmt" "os" "testing" @@ -49,7 +50,8 @@ func TestPortForwardCommand(t *testing.T) { VelaC: fakeC, } err := o.Init(context.Background(), cmd, []string{"fakeApp", "8081:8080"}) - assert.NoError(t, err) + errString := fmt.Sprintf(`application "%s" not found`, "fakeApp") + assert.EqualError(t, err, errString) } func TestNewPortForwardCommandPersistentPreRunE(t *testing.T) { diff --git a/pkg/commands/trait.go b/pkg/commands/trait.go index 4cbcd51cc..8e3ddfb53 100644 --- a/pkg/commands/trait.go +++ b/pkg/commands/trait.go @@ -97,11 +97,11 @@ func (o *commandOptions) Prepare(cmd *cobra.Command, args []string) error { // get application app, err := application.Load(o.Env.Name, o.appName) if err != nil { + if application.IsNotFound(o.appName, err) { + return fmt.Errorf("the application %s doesn't exist in current env %s", o.appName, o.Env.Name) + } return err } - if len(app.Name) == 0 { - return fmt.Errorf("the application %s doesn't exist in current env %s", o.appName, o.Env.Name) - } // get service name serviceNames := app.GetComponents() diff --git a/pkg/serverlib/workload.go b/pkg/serverlib/workload.go index ceff2a226..d3961ec68 100644 --- a/pkg/serverlib/workload.go +++ b/pkg/serverlib/workload.go @@ -37,9 +37,19 @@ func LoadIfExist(envName string, workloadName string, appGroup string) (*applica appName = workloadName } app, err := application.Load(envName, appName) - if err != nil { + + // can't handle + if err != nil && !application.IsNotFound(appName, err) { return nil, err } + + // compatible application not found + if app == nil { + app, err = application.NewEmptyApplication() + if err != nil { + return nil, err + } + } app.Name = appName return app, nil