From 203b23cec12723fd78809f2276d929db2fb3d8ed Mon Sep 17 00:00:00 2001 From: Nithish Date: Fri, 1 Jul 2022 16:02:33 +0530 Subject: [PATCH] refactor: Make the process faster Signed-off-by: Nithish --- utils/kubernetes/kompose/composefile.go | 57 ++++++++++++++++++------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/utils/kubernetes/kompose/composefile.go b/utils/kubernetes/kompose/composefile.go index 5ff26443..18b61d36 100644 --- a/utils/kubernetes/kompose/composefile.go +++ b/utils/kubernetes/kompose/composefile.go @@ -4,46 +4,71 @@ import ( "context" "io" "os" + "path/filepath" "cuelang.org/go/cmd/cue/cmd" + "cuelang.org/go/cue/cuecontext" + "cuelang.org/go/encoding/yaml" "github.com/layer5io/meshkit/utils" ) type DockerComposeFile []byte -func (dc *DockerComposeFile) Validate(schema []byte) error { - err := utils.CreateFile(schema, "compose-spec.json", "./") +// TODO: This should be dynamic +// once we move to using encoding/jsonschema, this will be removed +var ( + DefaultSpecDirectory = filepath.Join(utils.GetHome(), ".meshery", "cue") + DefaultSpecPath = filepath.Join(DefaultSpecDirectory, "compose-spec.cue") +) + +func generateCueSchema(jsonSchema []byte, dir string) error { + err := os.MkdirAll(dir, os.ModePerm) if err != nil { - ErrValidateDockerComposeFile(err) + return ErrValidateDockerComposeFile(err) } + err = utils.CreateFile(jsonSchema, "compose-spec.json", dir) + if err != nil { + return ErrValidateDockerComposeFile(err) + } + defer os.Remove(filepath.Join(DefaultSpecDirectory, "compose-spec.json")) //load and parse the schema - importCmd, err := cmd.New([]string{"import", "-f", "-l", "#ComposeSpec:", "-o", "schema.cue", "compose-spec.json"}) + // NOTE: this approach makes the process slow and is not recommended + // TODO: use encoding/jsonschema. + importCmd, err := cmd.New([]string{"import", "-f", "--files", filepath.Join(DefaultSpecDirectory, "compose-spec.json")}) if err != nil { - ErrValidateDockerComposeFile(err) + return ErrValidateDockerComposeFile(err) } // no need for logs importCmd.SetOut(io.Discard) - defer os.Remove("composefile.yaml") - defer os.Remove("schema.cue") err = importCmd.Run(context.TODO()) if err != nil { return ErrValidateDockerComposeFile(err) } - //persist composefile in FS - err = os.WriteFile("composefile.yaml", *dc, 0644) - if err != nil { - return ErrValidateDockerComposeFile(err) + return nil +} + +func (dc *DockerComposeFile) Validate(schema []byte) error { + cueCtx := cuecontext.New() + // check if the spec is already present + if _, err := os.Stat(DefaultSpecPath); err != nil { + // if not, create the spec + err = generateCueSchema(schema, DefaultSpecDirectory) + if err != nil { + return ErrValidateDockerComposeFile(err) + } } - // validate using cue vet - vetCmd, err := cmd.New([]string{"vet", "-d", "#ComposeSpec", "composefile.yaml", "schema.cue"}) + + cueSchema, err := utils.ReadLocalFile(DefaultSpecPath) if err != nil { return ErrValidateDockerComposeFile(err) } - vetCmd.SetOut(io.Discard) - err = vetCmd.Run(context.TODO()) + sv := cueCtx.CompileString(cueSchema) + if sv.Err() != nil { + return ErrValidateDockerComposeFile(sv.Err()) + } + err = yaml.Validate(*dc, sv) if err != nil { return ErrValidateDockerComposeFile(err) } - return nil }