2023-08-30 12:21:39 +00:00
|
|
|
package mutator
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"path/filepath"
|
|
|
|
"text/template"
|
|
|
|
|
|
|
|
"github.com/databricks/cli/bundle"
|
2024-03-25 14:18:47 +00:00
|
|
|
"github.com/databricks/cli/libs/diag"
|
2023-08-30 12:21:39 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/jobs"
|
|
|
|
)
|
|
|
|
|
|
|
|
type TaskWithJobKey struct {
|
|
|
|
Task *jobs.Task
|
|
|
|
JobKey string
|
|
|
|
}
|
|
|
|
|
|
|
|
type TrampolineFunctions interface {
|
|
|
|
GetTemplateData(task *jobs.Task) (map[string]any, error)
|
|
|
|
GetTasks(b *bundle.Bundle) []TaskWithJobKey
|
|
|
|
CleanUp(task *jobs.Task) error
|
|
|
|
}
|
|
|
|
type trampoline struct {
|
|
|
|
name string
|
|
|
|
functions TrampolineFunctions
|
|
|
|
template string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTrampoline(
|
|
|
|
name string,
|
|
|
|
functions TrampolineFunctions,
|
|
|
|
template string,
|
|
|
|
) *trampoline {
|
|
|
|
return &trampoline{name, functions, template}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *trampoline) Name() string {
|
|
|
|
return fmt.Sprintf("trampoline(%s)", m.name)
|
|
|
|
}
|
|
|
|
|
2024-03-25 14:18:47 +00:00
|
|
|
func (m *trampoline) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
|
2023-08-30 12:21:39 +00:00
|
|
|
tasks := m.functions.GetTasks(b)
|
|
|
|
for _, task := range tasks {
|
2023-09-11 08:18:43 +00:00
|
|
|
err := m.generateNotebookWrapper(ctx, b, task)
|
2023-08-30 12:21:39 +00:00
|
|
|
if err != nil {
|
2024-03-25 14:18:47 +00:00
|
|
|
return diag.FromErr(err)
|
2023-08-30 12:21:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-11 08:18:43 +00:00
|
|
|
func (m *trampoline) generateNotebookWrapper(ctx context.Context, b *bundle.Bundle, task TaskWithJobKey) error {
|
|
|
|
internalDir, err := b.InternalDir(ctx)
|
2023-08-30 12:21:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
notebookName := fmt.Sprintf("notebook_%s_%s", task.JobKey, task.Task.TaskKey)
|
|
|
|
localNotebookPath := filepath.Join(internalDir, notebookName+".py")
|
|
|
|
|
|
|
|
err = os.MkdirAll(filepath.Dir(localNotebookPath), 0755)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
f, err := os.Create(localNotebookPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
data, err := m.functions.GetTemplateData(task.Task)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
t, err := template.New(notebookName).Parse(m.template)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-03-27 09:03:24 +00:00
|
|
|
internalDirRel, err := filepath.Rel(b.RootPath, internalDir)
|
2023-08-30 12:21:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = m.functions.CleanUp(task.Task)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-11-15 13:37:26 +00:00
|
|
|
remotePath := path.Join(b.Config.Workspace.FilePath, filepath.ToSlash(internalDirRel), notebookName)
|
2023-08-30 12:21:39 +00:00
|
|
|
|
|
|
|
task.Task.NotebookTask = &jobs.NotebookTask{
|
|
|
|
NotebookPath: remotePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
return t.Execute(f, data)
|
|
|
|
}
|