Signed-off-by: Hongchao Deng <hongchaodeng1@gmail.com>
This commit is contained in:
Hongchao Deng
2020-10-30 00:08:15 -07:00
parent 2451236791
commit 629ceee307
9 changed files with 248 additions and 143 deletions
+82 -16
View File
@@ -8,8 +8,7 @@ In this tutorial, we will build and deploy an example NodeJS app under [examples
## Prerequisites
- [docker](https://docs.docker.com/get-docker/) installed on the host
- [vela](../../install.md) installed
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) installed
- [vela](../../install.md) installed and configured
## 1. Download test app code
@@ -24,9 +23,10 @@ The example contains NodeJS app code, Dockerfile to build the app.
## 2. Deploy app in one command
[vela.yaml](../../../examples/testapp/vela.yaml) is an appfile format supported by Vela.
In the directory there is a [vela.yaml](../../../examples/testapp/vela.yaml) which follows Appfile format supported by Vela.
We are going to use it to build and deploy the app.
You need to change this line to the image that you can push to on your host:
ATTENTION: change the image field in vela.yaml to something you can push to on your host:
> Or you may try the local kind cluster option which will be introduced in the following section.
@@ -34,28 +34,94 @@ You need to change this line to the image that you can push to on your host:
image: oamdev/testapp:v1
```
Deploy vela.yaml:
Run the following command:
```console
$ vela up
Parsing vela.yaml ...
Loading templates ...
Building service (express-server)...
Sending build context to Docker daemon 71.68kB
Step 1/10 : FROM mhart/alpine-node:12
---> 9d88359808c3
...
pushing image (oamdev/testapp:v1)...
...
Rendering configs for service (express-server)...
writing deploy config to (.vela/deploy.yaml)
Applying deploy configs ...
Checking if app has been deployed...
app has not been deployed, creating a new deployment...
app has been deployed 🚀🚀🚀
Port forward: vela port-forward testapp <port>
SSH: vela exec testapp
Logging: vela logs testapp
```
Now the app has been rendered and deployed.
## 3. Check rendered manifests and deployment
By default, Vela renders the final manifests in `.vela/deploy.yaml`:
```console
$ cat .vela/deploy.yaml
```
Now the app deployment has been rendered and run.
Check the status of the application deployment:
```console
$ vela app status testapp
$ vela svc status express-server [0:06:32]
Showing status of service(type: webservice) express-server deployed in Environment default
Service express-server Status: HEALTHY Ready: 1/1
scaler: replica=1
scaler: replica=1
$ vela svc status express-server
Last Deployment:
Created at: 2020-10-30 00:06:10 -0700 PDT
Updated at: 2020-10-30T00:06:10-07:00
```
## 3. Check rendered manifests
By default, Vela renders the final manifests in `.vela/deploy.yaml`:
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: ApplicationConfiguration
metadata:
name: testapp
namespace: default
spec:
components:
- componentName: express-server
traits:
- trait:
apiVersion: core.oam.dev/v1alpha2
kind: ManualScalerTrait
...
- trait:
apiVersion: standard.oam.dev/v1alpha1
kind: Route
...
---
apiVersion: core.oam.dev/v1alpha2
kind: Component
metadata:
name: express-server
namespace: default
spec:
workload:
apiVersion: apps/v1
kind: Deployment
metadata:
name: express-server
...
---
apiVersion: core.oam.dev/v1alpha2
kind: HealthScope
metadata:
name: testapp-default-health
namespace: default
spec:
...
```
## [Optional] Configure "task" workload type
+2 -2
View File
@@ -13,8 +13,8 @@ services:
context: .
# Uncomment the following to push to local kind cluster
# push:
# local: kind
push:
local: kind
# type: webservice (default) | worker | task
+52 -7
View File
@@ -5,9 +5,12 @@ import (
"io/ioutil"
"time"
"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/crossplane/oam-kubernetes-runtime/pkg/oam"
"github.com/ghodss/yaml"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/oam-dev/kubevela/pkg/appfile/template"
cmdutil "github.com/oam-dev/kubevela/pkg/commands/util"
@@ -57,18 +60,18 @@ func LoadFromFile(filename string) (*AppFile, error) {
// BuildOAM renders Appfile into AppConfig, Components. It also builds images for services if defined.
func (app *AppFile) BuildOAM(ns string, io cmdutil.IOStreams, tm template.Manager, slience bool) (
[]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, error) {
[]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, []oam.Object, error) {
return app.buildOAM(ns, io, true, tm, slience)
}
// RenderOAM renders Appfile into AppConfig, Components.
func (app *AppFile) RenderOAM(ns string, io cmdutil.IOStreams, tm template.Manager, slience bool) (
[]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, error) {
[]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, []oam.Object, error) {
return app.buildOAM(ns, io, false, tm, slience)
}
func (app *AppFile) buildOAM(ns string, io cmdutil.IOStreams, buildImage bool, tm template.Manager, slience bool) (
[]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, error) {
[]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, []oam.Object, error) {
appConfig := &v1alpha2.ApplicationConfiguration{
ObjectMeta: metav1.ObjectMeta{
@@ -88,12 +91,12 @@ func (app *AppFile) buildOAM(ns string, io cmdutil.IOStreams, buildImage bool, t
if b := svc.GetBuild(); b != nil {
if image == "" {
return nil, nil, ErrImageNotDefined
return nil, nil, nil, ErrImageNotDefined
}
if buildImage {
io.Infof("\nBuilding service (%s)...\n", sname)
if err := b.BuildImage(io, image); err != nil {
return nil, nil, err
return nil, nil, nil, err
}
}
}
@@ -102,11 +105,53 @@ func (app *AppFile) buildOAM(ns string, io cmdutil.IOStreams, buildImage bool, t
}
acComp, comp, err := svc.RenderService(tm, sname, ns, app.configGetter)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
appConfig.Spec.Components = append(appConfig.Spec.Components, *acComp)
comps = append(comps, comp)
}
return comps, appConfig, nil
addWorkloadTypeLabel(comps, app.Services)
health := addHealthScope(appConfig)
return comps, appConfig, []oam.Object{health}, nil
}
func addWorkloadTypeLabel(comps []*v1alpha2.Component, services map[string]Service) {
for _, comp := range comps {
workloadType := services[comp.Name].GetType()
workloadObject := comp.Spec.Workload.Object.(*unstructured.Unstructured)
labels := workloadObject.GetLabels()
if labels == nil {
labels = map[string]string{oam.WorkloadTypeLabel: workloadType}
} else {
labels[oam.WorkloadTypeLabel] = workloadType
}
workloadObject.SetLabels(labels)
}
}
func addHealthScope(appConfig *v1alpha2.ApplicationConfiguration) *v1alpha2.HealthScope {
health := &v1alpha2.HealthScope{
TypeMeta: metav1.TypeMeta{
APIVersion: v1alpha2.HealthScopeGroupVersionKind.GroupVersion().String(),
Kind: v1alpha2.HealthScopeKind,
},
}
health.Name = FormatDefaultHealthScopeName(appConfig.Name)
health.Namespace = appConfig.Namespace
health.Spec.WorkloadReferences = make([]v1alpha1.TypedReference, 0)
for i := range appConfig.Spec.Components {
// TODO(wonderflow): Temporarily we add health scope here, should change to use scope framework
appConfig.Spec.Components[i].Scopes = append(appConfig.Spec.Components[i].Scopes, v1alpha2.ComponentScope{
ScopeReference: v1alpha1.TypedReference{
APIVersion: v1alpha2.SchemeGroupVersion.String(),
Kind: v1alpha2.HealthScopeKind,
Name: health.Name,
},
})
}
return health
}
func FormatDefaultHealthScopeName(appName string) string {
return appName + "-default-health"
}
+73 -3
View File
@@ -4,10 +4,12 @@ import (
"os"
"testing"
"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@@ -162,6 +164,13 @@ outputs: ingress: {
Spec: v1alpha2.ApplicationConfigurationSpec{
Components: []v1alpha2.ApplicationConfigurationComponent{{
ComponentName: "express-server",
Scopes: []v1alpha2.ComponentScope{{
ScopeReference: v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "myapp-default-health",
},
}},
Traits: []v1alpha2.ComponentTrait{{
Trait: runtime.RawExtension{
Object: &unstructured.Unstructured{
@@ -220,6 +229,13 @@ outputs: ingress: {
ac2.Spec.Components = append(ac2.Spec.Components, v1alpha2.ApplicationConfigurationComponent{
ComponentName: "mongodb",
Traits: []v1alpha2.ComponentTrait{},
Scopes: []v1alpha2.ComponentScope{{
ScopeReference: v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "myapp-default-health",
},
}},
})
comp1 := &v1alpha2.Component{
@@ -233,7 +249,12 @@ outputs: ingress: {
Object: map[string]interface{}{
"apiVersion": "test.oam.dev/v1",
"kind": "WebService",
"metadata": map[string]interface{}{"name": "express-server"},
"metadata": map[string]interface{}{
"name": "express-server",
"labels": map[string]interface{}{
"workload.oam.dev/type": "webservice",
},
},
"spec": map[string]interface{}{
"image": "oamdev/testapp:v1",
"command": []interface{}{"node", "server.js"},
@@ -255,7 +276,12 @@ outputs: ingress: {
Object: map[string]interface{}{
"apiVersion": "test.oam.dev/v1",
"kind": "Worker",
"metadata": map[string]interface{}{"name": "mongodb"},
"metadata": map[string]interface{}{
"name": "mongodb",
"labels": map[string]interface{}{
"workload.oam.dev/type": "backend",
},
},
"spec": map[string]interface{}{
"image": "bitnami/mongodb:3.6.20",
"command": []interface{}{"mongodb"},
@@ -281,6 +307,8 @@ outputs: ingress: {
fakeConfigData, "spec", "env"); err != nil {
t.Fatal(err)
}
compWithConfig.Spec.Workload.Object.(*unstructured.Unstructured).SetLabels(
map[string]string{"workload.oam.dev/type": "withconfig"})
type args struct {
appfileData string
@@ -377,7 +405,7 @@ outputs: ingress: {
}
}
comps, ac, err := app.RenderOAM("default", io, tm, false)
comps, ac, _, err := app.RenderOAM("default", io, tm, false)
if err != nil {
assert.Equal(t, c.want.err, err)
return
@@ -416,3 +444,45 @@ outputs: ingress: {
})
}
}
func TestAddWorkloadTypeLabel(t *testing.T) {
tests := map[string]struct {
comps []*v1alpha2.Component
services map[string]Service
expect []*v1alpha2.Component
}{
"empty case": {
comps: []*v1alpha2.Component{},
services: map[string]Service{},
expect: []*v1alpha2.Component{},
},
"add type to labels normal case": {
comps: []*v1alpha2.Component{
{
ObjectMeta: v1.ObjectMeta{Name: "mycomp"},
Spec: v1alpha2.ComponentSpec{Workload: runtime.RawExtension{Object: &unstructured.Unstructured{Object: map[string]interface{}{}}}},
},
},
services: map[string]Service{
"mycomp": {"type": "kubewatch"},
},
expect: []*v1alpha2.Component{
{
ObjectMeta: v1.ObjectMeta{Name: "mycomp"},
Spec: v1alpha2.ComponentSpec{
Workload: runtime.RawExtension{
Object: &unstructured.Unstructured{Object: map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"workload.oam.dev/type": "kubewatch",
}}}}},
},
},
},
},
}
for key, ca := range tests {
addWorkloadTypeLabel(ca.comps, ca.services)
assert.Equal(t, ca.expect, ca.comps, key)
}
}
+2 -42
View File
@@ -11,11 +11,9 @@ import (
"strings"
"time"
"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/crossplane/oam-kubernetes-runtime/pkg/oam"
"github.com/ghodss/yaml"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/oam-dev/kubevela/api/types"
"github.com/oam-dev/kubevela/pkg/appfile"
@@ -222,51 +220,13 @@ func (app *Application) GetTraitsByType(componentName, traitType string) (map[st
return t.(map[string]interface{}), nil
}
func FormatDefaultHealthScopeName(appName string) string {
return appName + "-default-health"
}
// TODO(wonderflow) add scope support here
func (app *Application) OAM(env *types.EnvMeta, io cmdutil.IOStreams, slience bool) ([]*v1alpha2.Component, *v1alpha2.ApplicationConfiguration, []oam.Object, error) {
comps, appConfig, err := app.RenderOAM(env.Namespace, io, app.tm, slience)
comps, appConfig, scopes, err := app.RenderOAM(env.Namespace, io, app.tm, slience)
if err != nil {
return nil, nil, nil, err
}
addWorkloadTypeLabel(comps, app.Services)
health := addHealthScope(appConfig)
return comps, appConfig, []oam.Object{health}, nil
}
func addWorkloadTypeLabel(comps []*v1alpha2.Component, services map[string]appfile.Service) {
for _, comp := range comps {
workloadType := services[comp.Name].GetType()
workloadObject := comp.Spec.Workload.Object.(*unstructured.Unstructured)
labels := workloadObject.GetLabels()
if labels == nil {
labels = map[string]string{oam.WorkloadTypeLabel: workloadType}
} else {
labels[oam.WorkloadTypeLabel] = workloadType
}
workloadObject.SetLabels(labels)
}
}
func addHealthScope(appConfig *v1alpha2.ApplicationConfiguration) *v1alpha2.HealthScope {
health := &v1alpha2.HealthScope{}
health.Name = FormatDefaultHealthScopeName(appConfig.Name)
health.Namespace = appConfig.Namespace
health.Spec.WorkloadReferences = make([]v1alpha1.TypedReference, 0)
for i := range appConfig.Spec.Components {
// TODO(wonderflow): Temporarily we add health scope here, should change to use scope framework
appConfig.Spec.Components[i].Scopes = append(appConfig.Spec.Components[i].Scopes, v1alpha2.ComponentScope{
ScopeReference: v1alpha1.TypedReference{
APIVersion: v1alpha2.SchemeGroupVersion.String(),
Kind: v1alpha2.HealthScopeKind,
Name: health.Name,
},
})
}
return health
return comps, appConfig, scopes, nil
}
func getApplicationDir(envName string) (string, error) {
-49
View File
@@ -5,13 +5,6 @@ import (
"fmt"
"testing"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
@@ -143,45 +136,3 @@ services:
assert.Equal(t, c.ExpTraits, traits, caseName)
}
}
func TestAddWorkloadTypeLabel(t *testing.T) {
tests := map[string]struct {
comps []*v1alpha2.Component
services map[string]appfile.Service
expect []*v1alpha2.Component
}{
"empty case": {
comps: []*v1alpha2.Component{},
services: map[string]appfile.Service{},
expect: []*v1alpha2.Component{},
},
"add type to labels normal case": {
comps: []*v1alpha2.Component{
{
ObjectMeta: v1.ObjectMeta{Name: "mycomp"},
Spec: v1alpha2.ComponentSpec{Workload: runtime.RawExtension{Object: &unstructured.Unstructured{Object: map[string]interface{}{}}}},
},
},
services: map[string]appfile.Service{
"mycomp": {"type": "kubewatch"},
},
expect: []*v1alpha2.Component{
{
ObjectMeta: v1.ObjectMeta{Name: "mycomp"},
Spec: v1alpha2.ComponentSpec{
Workload: runtime.RawExtension{
Object: &unstructured.Unstructured{Object: map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"workload.oam.dev/type": "kubewatch",
}}}}},
},
},
},
},
}
for key, ca := range tests {
addWorkloadTypeLabel(ca.comps, ca.services)
assert.Equal(t, ca.expect, ca.comps, key)
}
}
+3 -2
View File
@@ -21,6 +21,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/api/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/application"
cmdutil "github.com/oam-dev/kubevela/pkg/commands/util"
oam2 "github.com/oam-dev/kubevela/pkg/oam"
@@ -73,7 +74,7 @@ const (
const (
ErrNotLoadAppConfig = "cannot load the application"
ErrFmtNotInitialized = "initializing service: %s failed"
ErrFmtNotInitialized = "service: %s not ready"
ErrServiceNotFound = "service %s not found in app"
)
@@ -195,7 +196,7 @@ func printAppStatus(ctx context.Context, c client.Client, ioStreams cmdutil.IOSt
func getWorkloadHealthConditions(ctx context.Context, c client.Client, app *application.Application, ns string) (map[string]*WorkloadHealthCondition, error) {
hs := &v1alpha2.HealthScope{}
// only use default health scope
hsName := application.FormatDefaultHealthScopeName(app.Name)
hsName := appfile.FormatDefaultHealthScopeName(app.Name)
if err := c.Get(ctx, client.ObjectKey{Namespace: ns, Name: hsName}, hs); err != nil {
return nil, err
}
+32 -21
View File
@@ -9,12 +9,12 @@ import (
"path/filepath"
"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/ghodss/yaml"
"github.com/kyokomi/emoji"
"github.com/crossplane/oam-kubernetes-runtime/pkg/oam"
"github.com/pkg/errors"
"github.com/spf13/cobra"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json"
apitypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -27,7 +27,6 @@ import (
var (
appFilePath string
emojiRocket = emoji.Sprint(":rocket")
)
func NewUpCommand(c types.Args, ioStream cmdutil.IOStreams) *cobra.Command {
@@ -93,36 +92,43 @@ func (o *appfileOptions) Run(filePath string) error {
return err
}
comps, appConfig, err := app.BuildOAM(o.Env.Namespace, o.IO, tm, false)
comps, appConfig, scopes, err := app.BuildOAM(o.Env.Namespace, o.IO, tm, false)
if err != nil {
return err
}
var cfg bytes.Buffer
var w bytes.Buffer
enc := k8sjson.NewYAMLSerializer(k8sjson.DefaultMetaFactory, nil, nil)
appConfig.TypeMeta = metav1.TypeMeta{
APIVersion: v1alpha2.ApplicationConfigurationGroupVersionKind.GroupVersion().String(),
Kind: v1alpha2.ApplicationConfigurationKind,
}
b, err := yaml.Marshal(appConfig)
err = enc.Encode(appConfig, &w)
if err != nil {
return fmt.Errorf("marshal AppConfig failed: %w", err)
return fmt.Errorf("yaml encode AppConfig failed: %w", err)
}
cfg.Write(b)
cfg.WriteByte('\n')
w.WriteByte('\n')
for _, comp := range comps {
cfg.WriteString("---\n")
w.WriteString("---\n")
comp.TypeMeta = metav1.TypeMeta{
APIVersion: v1alpha2.ComponentGroupVersionKind.GroupVersion().String(),
Kind: v1alpha2.ComponentKind,
}
b, err := yaml.Marshal(comp)
err = enc.Encode(comp, &w)
if err != nil {
return fmt.Errorf("marshal service (%s) failed: %w", comp.Name, err)
return fmt.Errorf("yaml encode service (%s) failed: %w", comp.Name, err)
}
cfg.Write(b)
cfg.WriteByte('\n')
w.WriteByte('\n')
}
for _, scope := range scopes {
w.WriteString("---\n")
err = enc.Encode(scope, &w)
if err != nil {
return fmt.Errorf("yaml encode scope (%s) failed: %w", scope.GetName(), err)
}
w.WriteByte('\n')
}
deployFilePath := ".vela/deploy.yaml"
@@ -130,7 +136,7 @@ func (o *appfileOptions) Run(filePath string) error {
if err := os.MkdirAll(filepath.Dir(deployFilePath), 0700); err != nil {
return err
}
if err := ioutil.WriteFile(deployFilePath, cfg.Bytes(), 0600); err != nil {
if err := ioutil.WriteFile(deployFilePath, w.Bytes(), 0600); err != nil {
return errors.Wrap(err, "write deploy config manifests failed")
}
@@ -139,7 +145,7 @@ func (o *appfileOptions) Run(filePath string) error {
}
o.IO.Infof("\nApplying deploy configs ...\n")
return o.ApplyAppConfig(appConfig, comps)
return o.ApplyAppConfig(appConfig, comps, scopes)
}
func (o *appfileOptions) saveToAppDir(f *appfile.AppFile) error {
@@ -152,7 +158,7 @@ func (o *appfileOptions) saveToAppDir(f *appfile.AppFile) error {
// - for create, it displays app status along with information of url, metrics, ssh, logging.
// - for update, it rolls out a canary deployment and prints its information. User can verify the canary deployment.
// This will wait for user approval. If approved, it continues upgrading the whole; otherwise, it would rollback.
func (o *appfileOptions) ApplyAppConfig(ac *v1alpha2.ApplicationConfiguration, comps []*v1alpha2.Component) error {
func (o *appfileOptions) ApplyAppConfig(ac *v1alpha2.ApplicationConfiguration, comps []*v1alpha2.Component, scopes []oam.Object) error {
key := apitypes.NamespacedName{
Namespace: ac.Namespace,
Name: ac.Name,
@@ -168,25 +174,30 @@ func (o *appfileOptions) ApplyAppConfig(ac *v1alpha2.ApplicationConfiguration, c
default:
return err
}
if err := o.apply(ac, comps); err != nil {
if err := o.apply(ac, comps, scopes); err != nil {
return err
}
o.info(ac.Name)
return nil
}
func (o *appfileOptions) apply(ac *v1alpha2.ApplicationConfiguration, comps []*v1alpha2.Component) error {
func (o *appfileOptions) apply(ac *v1alpha2.ApplicationConfiguration, comps []*v1alpha2.Component, scopes []oam.Object) error {
for _, comp := range comps {
if err := application.CreateOrUpdateComponent(context.TODO(), o.Kubecli, comp); err != nil {
return err
}
}
if err := application.CreateScopes(context.TODO(), o.Kubecli, scopes); err != nil {
return err
}
return application.CreateOrUpdateAppConfig(context.TODO(), o.Kubecli, ac)
}
func (o *appfileOptions) info(appName string) {
o.IO.Infof("app has been deployed %s%s%s\n", emojiRocket, emojiRocket, emojiRocket)
o.IO.Infof("\tPort forward: vela port-forward %s <port>\n", appName)
o.IO.Infof("app has been deployed 🚀🚀🚀\n")
o.IO.Infof("\tPort forward: vela port-forward %s\n", appName)
o.IO.Infof("\tSSH: vela exec %s\n", appName)
o.IO.Infof("\tLogging: vela logs %s\n", appName)
// TODO: print status
}
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"sort"
"github.com/oam-dev/kubevela/api/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/application"
cmdutil "github.com/oam-dev/kubevela/pkg/commands/util"
"github.com/oam-dev/kubevela/pkg/server/apis"
@@ -182,7 +183,7 @@ func (o *DeleteOptions) DeleteApp() (string, error) {
return "", fmt.Errorf("delete application err %s", err)
}
var healthScope corev1alpha2.HealthScope
healthScope.Name = application.FormatDefaultHealthScopeName(o.AppName)
healthScope.Name = appfile.FormatDefaultHealthScopeName(o.AppName)
healthScope.Namespace = o.Env.Namespace
err = o.Client.Delete(ctx, &healthScope)
if err != nil && !apierrors.IsNotFound(err) {