mirror of https://github.com/databricks/cli.git
95 lines
2.5 KiB
Go
95 lines
2.5 KiB
Go
package deploy
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"io/fs"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/databricks/cli/bundle"
|
|
"github.com/databricks/cli/libs/filer"
|
|
"github.com/databricks/databricks-sdk-go/client"
|
|
)
|
|
|
|
// FilerFactory is a function that returns a filer.Filer.
|
|
type FilerFactory func(b *bundle.Bundle) (filer.Filer, error)
|
|
|
|
type stateFiler struct {
|
|
filer filer.Filer
|
|
|
|
apiClient *client.DatabricksClient
|
|
root filer.WorkspaceRootPath
|
|
}
|
|
|
|
func (s stateFiler) Delete(ctx context.Context, path string, mode ...filer.DeleteMode) error {
|
|
return s.filer.Delete(ctx, path, mode...)
|
|
}
|
|
|
|
// Mkdir implements filer.Filer.
|
|
func (s stateFiler) Mkdir(ctx context.Context, path string) error {
|
|
return s.filer.Mkdir(ctx, path)
|
|
}
|
|
|
|
func (s stateFiler) Read(ctx context.Context, path string) (io.ReadCloser, error) {
|
|
absPath, err := s.root.Join(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
stat, err := s.Stat(ctx, path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if stat.IsDir() {
|
|
return nil, fmt.Errorf("not a file: %s", absPath)
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
urlPath := "/api/2.0/workspace-files/" + url.PathEscape(strings.TrimLeft(absPath, "/"))
|
|
err = s.apiClient.Do(ctx, http.MethodGet, urlPath, nil, nil, nil, &buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return io.NopCloser(&buf), nil
|
|
}
|
|
|
|
func (s stateFiler) ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) {
|
|
return s.filer.ReadDir(ctx, path)
|
|
}
|
|
|
|
func (s stateFiler) Stat(ctx context.Context, name string) (fs.FileInfo, error) {
|
|
return s.filer.Stat(ctx, name)
|
|
}
|
|
|
|
func (s stateFiler) Write(ctx context.Context, path string, reader io.Reader, mode ...filer.WriteMode) error {
|
|
return s.filer.Write(ctx, path, reader, mode...)
|
|
}
|
|
|
|
// StateFiler returns a filer.Filer that can be used to read/write state files.
|
|
// We use a custom workspace filer which uses workspace-files API to read state files.
|
|
// This API has a higher than 10 MB limits and allows to export large state files.
|
|
// We don't use the same API for read because it doesn't correct get the file content for notebooks and returns
|
|
// "File Not Found" error instead.
|
|
func StateFiler(b *bundle.Bundle) (filer.Filer, error) {
|
|
f, err := filer.NewWorkspaceFilesClient(b.WorkspaceClient(), b.Config.Workspace.StatePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
apiClient, err := client.New(b.WorkspaceClient().Config)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create API client: %w", err)
|
|
}
|
|
|
|
return stateFiler{
|
|
filer: f,
|
|
root: filer.NewWorkspaceRootPath(b.Config.Workspace.StatePath),
|
|
apiClient: apiClient,
|
|
}, nil
|
|
}
|