mirror of https://github.com/databricks/cli.git
chnaged to wait for deployment on start
This commit is contained in:
parent
79dd75a926
commit
d8f210a2ad
|
@ -16,7 +16,6 @@ import (
|
||||||
"github.com/databricks/cli/libs/filer"
|
"github.com/databricks/cli/libs/filer"
|
||||||
"github.com/databricks/databricks-sdk-go/service/apps"
|
"github.com/databricks/databricks-sdk-go/service/apps"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
@ -106,7 +105,7 @@ func (a *appRunner) start(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = wait.OnProgress(func(p *apps.App) {
|
startedApp, err := wait.OnProgress(func(p *apps.App) {
|
||||||
if p.AppStatus == nil {
|
if p.AppStatus == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -117,6 +116,26 @@ func (a *appRunner) start(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if startedApp.ActiveDeployment != nil &&
|
||||||
|
startedApp.ActiveDeployment.Status.State == apps.AppDeploymentStateInProgress {
|
||||||
|
logProgress(ctx, "Waiting for the active deployment to complete...")
|
||||||
|
_, err = w.Apps.WaitGetDeploymentAppSucceeded(ctx, app.Name, startedApp.ActiveDeployment.DeploymentId, 20*time.Minute, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logProgress(ctx, "Active deployment is completed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if startedApp.PendingDeployment != nil &&
|
||||||
|
startedApp.PendingDeployment.Status.State == apps.AppDeploymentStateInProgress {
|
||||||
|
logProgress(ctx, "Waiting for the pending deployment to complete...")
|
||||||
|
_, err = w.Apps.WaitGetDeploymentAppSucceeded(ctx, app.Name, startedApp.PendingDeployment.DeploymentId, 20*time.Minute, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logProgress(ctx, "Pending deployment is completed!")
|
||||||
|
}
|
||||||
|
|
||||||
logProgress(ctx, "App is started!")
|
logProgress(ctx, "App is started!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -162,25 +181,7 @@ func (a *appRunner) deploy(ctx context.Context) error {
|
||||||
|
|
||||||
// If deploy returns an error, then there's an active deployment in progress, wait for it to complete.
|
// If deploy returns an error, then there's an active deployment in progress, wait for it to complete.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logProgress(ctx, err.Error())
|
return err
|
||||||
err := a.waitForInProgressDeployments(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry the deployment.
|
|
||||||
wait, err = w.Apps.Deploy(ctx, apps.CreateAppDeploymentRequest{
|
|
||||||
AppName: app.Name,
|
|
||||||
AppDeployment: &apps.AppDeployment{
|
|
||||||
Mode: apps.AppDeploymentModeSnapshot,
|
|
||||||
SourceCodePath: app.SourceCodePath,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// If it still fails, return the error.
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = wait.OnProgress(func(ad *apps.AppDeployment) {
|
_, err = wait.OnProgress(func(ad *apps.AppDeployment) {
|
||||||
|
@ -197,37 +198,6 @@ func (a *appRunner) deploy(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appRunner) waitForInProgressDeployments(ctx context.Context) error {
|
|
||||||
app := a.app
|
|
||||||
b := a.bundle
|
|
||||||
w := b.WorkspaceClient()
|
|
||||||
|
|
||||||
allDeployments, err := w.Apps.ListDeploymentsAll(ctx, apps.ListAppDeploymentsRequest{AppName: app.Name})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
errGrp, ctx := errgroup.WithContext(ctx)
|
|
||||||
for _, deployment := range allDeployments {
|
|
||||||
if deployment.Status.State == apps.AppDeploymentStateInProgress {
|
|
||||||
id := deployment.DeploymentId
|
|
||||||
|
|
||||||
errGrp.Go(func() error {
|
|
||||||
logProgress(ctx, fmt.Sprintf("Waiting for deployment %s to complete", id))
|
|
||||||
d, err := w.Apps.WaitGetDeploymentAppSucceeded(ctx, app.Name, id, 20*time.Minute, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
logProgress(ctx, fmt.Sprintf("Deployment %s reached state %s", id, d.Status.State))
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errGrp.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *appRunner) Cancel(ctx context.Context) error {
|
func (a *appRunner) Cancel(ctx context.Context) error {
|
||||||
// We should cancel the app by stopping it.
|
// We should cancel the app by stopping it.
|
||||||
app := a.app
|
app := a.app
|
||||||
|
|
|
@ -3,7 +3,6 @@ package run
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -185,68 +184,23 @@ func TestAppRunWithAnActiveDeploymentInProgress(t *testing.T) {
|
||||||
ComputeStatus: &apps.ComputeStatus{
|
ComputeStatus: &apps.ComputeStatus{
|
||||||
State: apps.ComputeStateActive,
|
State: apps.ComputeStateActive,
|
||||||
},
|
},
|
||||||
|
ActiveDeployment: &apps.AppDeployment{
|
||||||
|
DeploymentId: "active_deployment_id",
|
||||||
|
Status: &apps.AppDeploymentStatus{
|
||||||
|
State: apps.AppDeploymentStateInProgress,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PendingDeployment: &apps.AppDeployment{
|
||||||
|
DeploymentId: "pending_deployment_id",
|
||||||
|
Status: &apps.AppDeploymentStatus{
|
||||||
|
State: apps.AppDeploymentStateCancelled,
|
||||||
|
},
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
// First unset existing deploy handlers
|
appsApi.EXPECT().WaitGetDeploymentAppSucceeded(mock.Anything, "my_app", "active_deployment_id", mock.Anything, mock.Anything).Return(nil, nil)
|
||||||
appsApi.EXPECT().Deploy(mock.Anything, apps.CreateAppDeploymentRequest{
|
|
||||||
AppName: "my_app",
|
|
||||||
AppDeployment: &apps.AppDeployment{
|
|
||||||
Mode: apps.AppDeploymentModeSnapshot,
|
|
||||||
SourceCodePath: "/Workspace/Users/foo@bar.com/files/my_app",
|
|
||||||
},
|
|
||||||
}).Unset()
|
|
||||||
|
|
||||||
// The first deploy call will return an error
|
|
||||||
appsApi.EXPECT().Deploy(mock.Anything, apps.CreateAppDeploymentRequest{
|
|
||||||
AppName: "my_app",
|
|
||||||
AppDeployment: &apps.AppDeployment{
|
|
||||||
Mode: apps.AppDeploymentModeSnapshot,
|
|
||||||
SourceCodePath: "/Workspace/Users/foo@bar.com/files/my_app",
|
|
||||||
},
|
|
||||||
}).Return(nil, fmt.Errorf("deployment in progress")).Once()
|
|
||||||
|
|
||||||
// We will then list deployments and find all in progress deployments.
|
|
||||||
appsApi.EXPECT().ListDeploymentsAll(mock.Anything, apps.ListAppDeploymentsRequest{
|
|
||||||
AppName: "my_app",
|
|
||||||
}).Return([]apps.AppDeployment{
|
|
||||||
{
|
|
||||||
DeploymentId: "deployment-1",
|
|
||||||
Status: &apps.AppDeploymentStatus{
|
|
||||||
State: apps.AppDeploymentStateInProgress,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
DeploymentId: "deployment-2",
|
|
||||||
Status: &apps.AppDeploymentStatus{
|
|
||||||
State: apps.AppDeploymentStateSucceeded,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
// Wait for the in progress deployment to complete
|
|
||||||
appsApi.EXPECT().WaitGetDeploymentAppSucceeded(mock.Anything, "my_app", "deployment-1", mock.Anything, mock.Anything).Return(&apps.AppDeployment{
|
|
||||||
DeploymentId: "deployment-1",
|
|
||||||
Status: &apps.AppDeploymentStatus{
|
|
||||||
State: apps.AppDeploymentStateSucceeded,
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
wait := &apps.WaitGetDeploymentAppSucceeded[apps.AppDeployment]{
|
|
||||||
Poll: func(_ time.Duration, _ func(*apps.AppDeployment)) (*apps.AppDeployment, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry the deployment
|
|
||||||
appsApi.EXPECT().Deploy(mock.Anything, apps.CreateAppDeploymentRequest{
|
|
||||||
AppName: "my_app",
|
|
||||||
AppDeployment: &apps.AppDeployment{
|
|
||||||
Mode: apps.AppDeploymentModeSnapshot,
|
|
||||||
SourceCodePath: "/Workspace/Users/foo@bar.com/files/my_app",
|
|
||||||
},
|
|
||||||
}).Return(wait, nil)
|
|
||||||
|
|
||||||
r.run(t)
|
r.run(t)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue