Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: CRD synchronisation in the devbox #6008

Merged
merged 2 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion cmd/tcl/kubectl-testkube/devbox/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func NewDevBoxCommand() *cobra.Command {
pterm.Error.Printfln("Failed to load config file: %s", err.Error())
return
}
cfg.CloudContext.AgentUri = "https://agent-dev.testkube.dev"
cloud, err := devutils.NewCloud(cfg.CloudContext, cmd)
if err != nil {
pterm.Error.Printfln("Failed to connect to Cloud: %s", err.Error())
Expand Down Expand Up @@ -358,7 +359,7 @@ func NewDevBoxCommand() *cobra.Command {
if !termlink.SupportsHyperlinks() {
return name
}
return termlink.Link(name, cloud.DashboardUrl(env.Slug, fmt.Sprintf("dashboard/test-workflow-templates/%s", name)))
return name + " " + termlink.ColorLink("(open)", cloud.DashboardUrl(env.Slug, fmt.Sprintf("dashboard/test-workflow-templates/%s", name)), "magenta")
}

// Propagate changes from CRDSync to Cloud
Expand Down Expand Up @@ -450,6 +451,11 @@ func NewDevBoxCommand() *cobra.Command {
fmt.Println("Waiting for file changes...")

rebuild := func(ctx context.Context) {
select {
case <-ctx.Done():
return
case <-time.After(100 * time.Millisecond):
}
g, _ := errgroup.WithContext(ctx)
ts := time.Now()
fmt.Println(color.Yellow.Render("Rebuilding applications..."))
Expand Down
84 changes: 77 additions & 7 deletions cmd/tcl/kubectl-testkube/devbox/devutils/crdsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ package devutils
import (
"bytes"
"context"
"encoding/json"
"io"
"io/fs"
"os"
Expand Down Expand Up @@ -106,8 +105,18 @@ func (c *CRDSync) Next(ctx context.Context) (*CRDSyncUpdate, error) {
func (c *CRDSync) processWorkflow(sourcePath string, workflow testworkflowsv1.TestWorkflow) error {
for i := range c.workflows {
if c.workflows[i].Workflow.Name == workflow.Name {
v1, _ := json.Marshal(c.workflows[i].Workflow)
v2, _ := json.Marshal(workflow)
v1, _ := common.SerializeCRD(c.workflows[i].Workflow, common.SerializeOptions{
OmitCreationTimestamp: true,
CleanMeta: true,
Kind: "TestWorkflow",
GroupVersion: &testworkflowsv1.GroupVersion,
})
v2, _ := common.SerializeCRD(workflow, common.SerializeOptions{
OmitCreationTimestamp: true,
CleanMeta: true,
Kind: "TestWorkflow",
GroupVersion: &testworkflowsv1.GroupVersion,
})
c.workflows[i].SourcePath = sourcePath
if !bytes.Equal(v1, v2) {
c.workflows[i].Workflow = workflow
Expand All @@ -124,10 +133,20 @@ func (c *CRDSync) processWorkflow(sourcePath string, workflow testworkflowsv1.Te
func (c *CRDSync) processTemplate(sourcePath string, template testworkflowsv1.TestWorkflowTemplate) error {
for i := range c.templates {
if c.templates[i].Template.Name == template.Name {
v1, _ := json.Marshal(c.templates[i].Template)
v2, _ := json.Marshal(template)
v1, _ := common.SerializeCRD(c.templates[i].Template, common.SerializeOptions{
OmitCreationTimestamp: true,
CleanMeta: true,
Kind: "TestWorkflowTemplate",
GroupVersion: &testworkflowsv1.GroupVersion,
})
v2, _ := common.SerializeCRD(template, common.SerializeOptions{
OmitCreationTimestamp: true,
CleanMeta: true,
Kind: "TestWorkflowTemplate",
GroupVersion: &testworkflowsv1.GroupVersion,
})
c.templates[i].SourcePath = sourcePath
if !bytes.Equal(v1, v2) {
c.templates[i].SourcePath = sourcePath
c.templates[i].Template = template
c.updates = append(c.updates, CRDSyncUpdate{Template: &template, Op: CRDSyncUpdateOpUpdate})
return nil
Expand All @@ -139,6 +158,34 @@ func (c *CRDSync) processTemplate(sourcePath string, template testworkflowsv1.Te
return nil
}

func (c *CRDSync) deleteTemplate(name string) {
for i := 0; i < len(c.templates); i++ {
if c.templates[i].Template.Name == name {
c.updates = append(c.updates, CRDSyncUpdate{
Template: &testworkflowsv1.TestWorkflowTemplate{ObjectMeta: metav1.ObjectMeta{Name: c.templates[i].Template.Name}},
Op: CRDSyncUpdateOpDelete,
})
c.templates = append(c.templates[:i], c.templates[i+1:]...)
i--
return
}
}
}

func (c *CRDSync) deleteWorkflow(name string) {
for i := 0; i < len(c.workflows); i++ {
if c.workflows[i].Workflow.Name == name {
c.updates = append(c.updates, CRDSyncUpdate{
Workflow: &testworkflowsv1.TestWorkflow{ObjectMeta: metav1.ObjectMeta{Name: c.workflows[i].Workflow.Name}},
Op: CRDSyncUpdateOpDelete,
})
c.workflows = append(c.workflows[:i], c.workflows[i+1:]...)
i--
return
}
}
}

func (c *CRDSync) deleteFile(path string) error {
for i := 0; i < len(c.templates); i++ {
if c.templates[i].SourcePath == path {
Expand All @@ -153,7 +200,7 @@ func (c *CRDSync) deleteFile(path string) error {
for i := 0; i < len(c.workflows); i++ {
if c.workflows[i].SourcePath == path {
c.updates = append(c.updates, CRDSyncUpdate{
Template: &testworkflowsv1.TestWorkflowTemplate{ObjectMeta: metav1.ObjectMeta{Name: c.templates[i].Template.Name}},
Workflow: &testworkflowsv1.TestWorkflow{ObjectMeta: metav1.ObjectMeta{Name: c.workflows[i].Workflow.Name}},
Op: CRDSyncUpdateOpDelete,
})
c.workflows = append(c.workflows[:i], c.workflows[i+1:]...)
Expand All @@ -178,6 +225,19 @@ func (c *CRDSync) loadFile(path string) error {
return nil
}

prevTemplates := map[string]struct{}{}
for i := range c.templates {
if c.templates[i].SourcePath == path {
prevTemplates[c.templates[i].Template.Name] = struct{}{}
}
}
prevWorkflows := map[string]struct{}{}
for i := range c.workflows {
if c.workflows[i].SourcePath == path {
prevWorkflows[c.workflows[i].Workflow.Name] = struct{}{}
}
}

// TODO: Handle deleted entries
decoder := yaml.NewDecoder(file)
for {
Expand All @@ -204,6 +264,7 @@ func (c *CRDSync) loadFile(path string) error {
if err != nil {
continue
}
delete(prevWorkflows, tw.Name)
c.processWorkflow(path, tw)
} else if obj["kind"].(string) == "TestWorkflowTemplate" {
bytes, _ := yaml.Marshal(obj)
Expand All @@ -215,10 +276,19 @@ func (c *CRDSync) loadFile(path string) error {
if err != nil {
continue
}
delete(prevTemplates, tw.Name)
c.processTemplate(path, tw)
}
}
file.Close()

for t := range prevTemplates {
c.deleteTemplate(t)
}
for t := range prevWorkflows {
c.deleteWorkflow(t)
}

return nil
}

Expand Down
Loading