Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
538504f
initial work on margo integration
Haishi2016 May 10, 2024
cf3db36
margo support
Haishi2016 May 23, 2024
beff07c
update doc site from folder
Haishi2016 Oct 16, 2024
f2a8fe5
Merge branch 'main' of github.com:eclipse-symphony/symphony into main
Haishi2016 Oct 16, 2024
86a4f53
Merge branch 'main' of github.com:eclipse-symphony/symphony into main
Haishi2016 Oct 16, 2024
44d3287
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Oct 23, 2024
fbd8777
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Nov 5, 2024
4de599e
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Nov 7, 2024
ff809f7
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Nov 8, 2024
50a850d
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Nov 9, 2024
c338f8c
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Nov 14, 2024
bd868e5
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Nov 20, 2024
aaf8bf7
merge conflicts
Haishi2016 Dec 10, 2024
930c1bd
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Jan 6, 2025
ef29453
Merge branch 'main' of github.com:eclipse-symphony/symphony
Haishi2016 Jan 29, 2025
7356aa8
merge main
Haishi2016 Jan 29, 2025
37458d3
margo update to use solution container
Haishi2016 Jan 29, 2025
fcd0229
merge main
Haishi2016 Mar 5, 2025
651970c
update modules
Haishi2016 Mar 5, 2025
a5a6bbe
submodule
Haishi2016 Mar 5, 2025
c27af96
update version
Haishi2016 Mar 5, 2025
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
2 changes: 1 addition & 1 deletion .github/version/versions.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.48.34
0.48-margo.34
10 changes: 5 additions & 5 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[submodule "landing/public"]
path = landing/public
url = https://github.com/eclipse-symphony/symphony-website.git
branch = main
[submodule "docs-site/public"]
path = docs-site/public
url = https://github.com/eclipse-symphony/docs.git
[submodule "docs-site/themes/docsy"]
path = docs-site/themes/docsy
url = https://github.com/google/docsy.git
url = https://github.com/google/docsy.git
[submodule "landing/public"]
path = landing/public
url = https://github.com/eclipse-symphony/symphony-website.git
branch = main
156 changes: 156 additions & 0 deletions cli/cmd/margo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
* SPDX-License-Identifier: MIT
*/

package cmd

import (
"encoding/json"
"fmt"

"github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model"
"github.com/eclipse-symphony/symphony/cli/config"
"github.com/eclipse-symphony/symphony/cli/utils"
"github.com/eclipse-symphony/symphony/hydra"
"github.com/eclipse-symphony/symphony/hydra/margo/v0"
"github.com/spf13/cobra"
)

var (
appPackagePath string
)

var MargoCmd = &cobra.Command{
Use: "margo",
Short: "Margo commands",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("\n%sPlease use either 'margo run' or 'margo list'%s\n\n", utils.ColorRed(), utils.ColorReset())
},
}

var MargoRunCmd = &cobra.Command{
Use: "run",
Short: "run a Margo application package",
Run: func(cmd *cobra.Command, args []string) {
//check context
c := config.GetMaestroConfig(configFile)
ctx := c.DefaultContext
if configContext != "" {
ctx = configContext
}

if ctx == "" {
ctx = "default"
}
//check target
targets, err := utils.Get(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "targets", "", "", target)
if err != nil && targets != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
if len(targets) == 0 {
fmt.Printf("\n%s Target '%s' is not found%s\n\n", utils.ColorRed(), target, utils.ColorReset())
return
}
reader := margo.MargoSolutionReader{}
solution, err := reader.Parse(hydra.AppPackageDescription{
Path: appPackagePath,
Type: "margo",
Version: "v0",
})
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
solutionContainerName := solution.ObjectMeta.Name

solutionContainers, err := utils.Get(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "solutioncontainers", "", "", solutionContainerName)
if err != nil && solutionContainers != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
if len(solutionContainers) != 0 {
fmt.Printf("\n%s Solution '%s' already exists%s\n\n", utils.ColorRed(), solutionContainerName, utils.ColorReset())
return
}

//create solution container
solutionContainer := model.SolutionContainerState{
ObjectMeta: model.ObjectMeta{
Name: solutionContainerName,
},
Spec: &model.SolutionContainerSpec{},
}
solutionContainerData, err := json.Marshal(solutionContainer)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
err = utils.Upsert(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "solution-containers", solutionContainerName, solutionContainerData)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
solutionName := solutionContainerName + "-v-v1"
solution.ObjectMeta.Name = solutionName
solution.Spec.RootResource = solutionContainerName

//create solution
solutionData, err := json.Marshal(solution)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
err = utils.Upsert(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "solutions", solutionName, solutionData)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}

instanceName := solutionName + "-instance"
//check instance
instances, err := utils.Get(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "instances", "", "", instanceName)
if err != nil && instances != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
if len(instances) > 0 {
fmt.Printf("\n%s Solution instance '%s' already exists%s\n\n", utils.ColorRed(), instanceName, utils.ColorReset())
return
}
//create instance
instance := Instance{
Metadata: model.ObjectMeta{
Name: instanceName,
},
Spec: model.InstanceSpec{
Solution: solutionContainerName + ":v1",
Target: model.TargetSelector{
Name: target,
},
},
}
instanceData, err := json.Marshal(instance)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
err = utils.Upsert(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "instances", instanceName, instanceData)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
fmt.Printf("\n%s Solution instance created successfully%s\n\n", utils.ColorGreen(), utils.ColorReset())
},
}

func init() {
MargoRunCmd.Flags().StringVarP(&appPackagePath, "package", "p", "", "Margo application package definition path")
MargoRunCmd.Flags().StringVarP(&target, "target", "t", "", "Target to run the solution on")
MargoRunCmd.MarkFlagRequired("package")
MargoRunCmd.MarkFlagRequired("target")
MargoCmd.AddCommand(MargoRunCmd)
RootCmd.AddCommand(MargoCmd)
}
123 changes: 123 additions & 0 deletions cli/cmd/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
* SPDX-License-Identifier: MIT
*/

package cmd

import (
"encoding/json"
"fmt"

"github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model"
"github.com/eclipse-symphony/symphony/cli/config"
"github.com/eclipse-symphony/symphony/cli/utils"
"github.com/spf13/cobra"
)

var (
solutionPath string
target string
instanceName string
)

var RunCmd = &cobra.Command{
Use: "run",
Short: "run a Margo application package",
Run: func(cmd *cobra.Command, args []string) {
//check context
c := config.GetMaestroConfig(configFile)
ctx := c.DefaultContext
if configContext != "" {
ctx = configContext
}

if ctx == "" {
ctx = "default"
}
//check target
targets, err := utils.Get(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "targets", "", "", target)
if err != nil && targets != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
if len(targets) == 0 {
fmt.Printf("\n%s Target '%s' is not found%s\n\n", utils.ColorRed(), target, utils.ColorReset())
return
}
//check instance
instances, err := utils.Get(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "instances", "", "", instanceName)
if err != nil && instances != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
if len(instances) > 0 {
fmt.Printf("\n%s Solution instance '%s' already exists%s\n\n", utils.ColorRed(), instanceName, utils.ColorReset())
return
}
//check solution
solutionData, err := utils.GetArtifactFile(solutionPath)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
var solution Solution
err = json.Unmarshal(solutionData, &solution)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
solutionName := solution.Metadata.Name
solutions, err := utils.Get(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "solutions", "", "", solutionName)
if err != nil && solutions != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
if len(solutions) != 0 {
fmt.Printf("\n%s Solution '%s' already exists%s\n\n", utils.ColorRed(), solutionName, utils.ColorReset())
return
}
//create solution
err = utils.Upsert(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "solutions", solutionName, solutionData)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
//create instance
instance := Instance{
Metadata: model.ObjectMeta{
Name: instanceName,
},
Spec: model.InstanceSpec{
Solution: solutionName,
Target: model.TargetSelector{
Name: target,
},
},
}
instanceData, err := json.Marshal(instance)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
err = utils.Upsert(c.Contexts[ctx].Url, c.Contexts[ctx].User, c.Contexts[ctx].Secret, "instances", instanceName, instanceData)
if err != nil {
fmt.Printf("\n%s %s%s\n\n", utils.ColorRed(), err.Error(), utils.ColorReset())
return
}
fmt.Printf("\n%s Solution instance created successfully%s\n\n", utils.ColorGreen(), utils.ColorReset())
},
}

func init() {
RunCmd.Flags().StringVarP(&solutionPath, "solution", "s", "", "Symphony solution file path")
RunCmd.Flags().StringVarP(&target, "target", "t", "", "Target to run the solution on")
RunCmd.Flags().StringVarP(&instanceName, "name", "n", "", "Name of the solution instance")
RunCmd.Flags().StringVarP(&configFile, "config", "c", "", "Maestro CLI config file")
RunCmd.Flags().StringVarP(&configContext, "context", "", "", "Maestro CLI configuration context")
RunCmd.MarkFlagRequired("solution")
RunCmd.MarkFlagRequired("target")
RunCmd.MarkFlagRequired("name")
RootCmd.AddCommand(RunCmd)
}
10 changes: 5 additions & 5 deletions cli/cmd/samples.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ var DescribeCmd = &cobra.Command{
},
}

var RunCmd = &cobra.Command{
var SampleRunCmd = &cobra.Command{
Use: "run",
Short: "run a Symphony sample",
Run: func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -339,14 +339,14 @@ var RemoveCmd = &cobra.Command{
}

func init() {
RunCmd.Flags().StringArrayVarP(&setSwitches, "set", "s", nil, "set sample parameter as key=value")
RunCmd.Flags().StringVarP(&sampleConfigFile, "config", "c", "", "Maestro CLI config file")
RunCmd.Flags().StringVarP(&sampleConfigContext, "context", "", "", "Maestro CLI configuration context")
SampleRunCmd.Flags().StringArrayVarP(&setSwitches, "set", "s", nil, "set sample parameter as key=value")
SampleRunCmd.Flags().StringVarP(&sampleConfigFile, "config", "c", "", "Maestro CLI config file")
SampleRunCmd.Flags().StringVarP(&sampleConfigContext, "context", "", "", "Maestro CLI configuration context")
RemoveCmd.Flags().StringVarP(&sampleConfigFile, "config", "c", "", "Maestro CLI config file")
RemoveCmd.Flags().StringVarP(&sampleConfigContext, "context", "", "", "Maestro CLI configuration context")
DescribeCmd.Flags().StringVarP(&sampleConfigFile, "config", "c", "", "Maestro CLI config file")
DescribeCmd.Flags().StringVarP(&sampleConfigContext, "context", "", "", "Maestro CLI configuration context")
SamplesCmd.AddCommand(RunCmd)
SamplesCmd.AddCommand(SampleRunCmd)
SamplesCmd.AddCommand(RemoveCmd)
SamplesCmd.AddCommand(DescribeCmd)
SamplesCmd.AddCommand(ListCmd)
Expand Down
3 changes: 3 additions & 0 deletions cli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ replace github.com/eclipse-symphony/symphony/api => ../api

replace github.com/eclipse-symphony/symphony/coa => ../coa

replace github.com/eclipse-symphony/symphony/hydra => ../hydra

require github.com/spf13/cobra v1.8.1

require (
Expand Down Expand Up @@ -48,6 +50,7 @@ require (

require (
github.com/eclipse-symphony/symphony/api v0.0.0
github.com/eclipse-symphony/symphony/hydra v0.0.0
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jedib0t/go-pretty/v6 v6.4.2
github.com/mattn/go-runewidth v0.0.15 // indirect
Expand Down
20 changes: 20 additions & 0 deletions cli/utils/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"fmt"
"io"
"net/http"
"os"

"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -100,6 +101,25 @@ func yamlToJson(payload []byte) ([]byte, error) {
return json.Marshal(o)
}

func GetArtifactFile(filePath string) ([]byte, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}

// Try to unmarshal as JSON first
var jsonObj interface{}
if err = json.Unmarshal(data, &jsonObj); err == nil {
return data, nil // It's already JSON, return it
}

// If it's not JSON, try to unmarshal as YAML
if err = yaml.Unmarshal(data, &jsonObj); err == nil {
return yamlToJson(data) // Convert YAML to JSON and return it
}

return nil, errors.New("file is neither valid JSON nor valid YAML")
}
func Get(url string, username string, password string, objType string, path string, docType string, objName string) ([]interface{}, error) {
token, err := Login(url, username, password)
if err != nil {
Expand Down
Loading
Loading