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

implement grid-compose #1130

Open
wants to merge 22 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7503ba9
init grid-compose
Omarabdul3ziz Jun 25, 2024
84cbd10
add network support
Omarabdul3ziz Jun 25, 2024
7f0d28b
use yaml.v3 to fix the custom unmarshal
Omarabdul3ziz Jun 26, 2024
9e70865
feat: implement init logic for ps command
eyad-hussein Jul 24, 2024
7d3cff0
enhance: implement logic to parse env vars and disks for up command
eyad-hussein Aug 3, 2024
905394b
refactor: refactor ps command implementation
eyad-hussein Aug 3, 2024
40e67a2
refactor: refactor up and ps commands
eyad-hussein Aug 4, 2024
9fcedd2
feat: implement deployment of two or more services on same network
eyad-hussein Aug 4, 2024
09d55e2
exmple: add more example files to cover test cases
eyad-hussein Aug 6, 2024
3b095a7
refactor: refactor logic for all commands to comply with cases and co…
eyad-hussein Aug 13, 2024
9e227e1
docs: edit readme file
eyad-hussein Aug 13, 2024
b0f3b22
docs: add supported cases for deployment, update readme
eyad-hussein Aug 13, 2024
4bf7aaf
feat: add support for depends_on optoin(dependency resolution)
eyad-hussein Aug 17, 2024
352ef37
feat: add support for health check option
eyad-hussein Aug 18, 2024
de9f63a
docs: add future work file
eyad-hussein Aug 18, 2024
07c5da9
refactor: refactor project structure and code
eyad-hussein Aug 21, 2024
124fe56
fix: add check for app type assertion, refactor: remove deploy packag…
eyad-hussein Aug 22, 2024
bd2aa64
Merge pull request #1155 from threefoldtech/development_compose_init_…
Omarabdul3ziz Aug 22, 2024
8ddab7b
Merge branch 'development' of github.com:threefoldtech/tfgrid-sdk-go …
eyad-hussein Aug 22, 2024
deb6275
feat: add support for different storage units for service resources
eyad-hussein Aug 24, 2024
f21cf97
fix: fix storage parser
eyad-hussein Aug 26, 2024
bf550b0
fix: change project name so type becomes Micro Virtual Machine in das…
eyad-hussein Aug 31, 2024
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
3 changes: 2 additions & 1 deletion go.work
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
go 1.21
go 1.21.0

use (
./activation-service
Expand All @@ -12,4 +12,5 @@ use (
./tfrobot
./tools/relay-cache-warmer
./user-contracts-mon
./grid-compose
)
4 changes: 4 additions & 0 deletions grid-compose/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bin/*
.pre-commit-config.yaml
out
full_example.yml
21 changes: 21 additions & 0 deletions grid-compose/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
test:
@echo "Running Tests"
go test -v ./...

clean:
rm ./bin -rf

getverifiers:
@echo "Installing golangci-lint" && go install github.com/golangci/golangci-lint/cmd/golangci-lint
go mod tidy

lint:
@echo "Running $@"
golangci-lint run -c ../.golangci.yml

build:
@echo "Running $@"
@go build -ldflags=\
"-X 'github.com/threefoldtech/tfgrid-sdk-go/grid-compose/cmd.commit=$(shell git rev-parse HEAD)'\
-X 'github.com/threefoldtech/tfgrid-sdk-go/grid-compose/cmd.version=$(shell git tag --sort=-version:refname | head -n 1)'"\
-o bin/grid-compose main.go
91 changes: 91 additions & 0 deletions grid-compose/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Grid-Compose

is a tool for running multi-vm applications on TFGrid defined using a Yaml formatted file.

## Usage

`REQUIRED` EnvVars:

- `MNEMONIC`: your secret words
- `NETWORK`: one of (dev, qa, test, main)

```bash
grid-compose [OPTIONS] [COMMAND]

OPTIONS:
-f, --file: path to yaml file, default is ./grid-compose.yaml

COMMANDS:
- version: shows the project version
- up: deploy the app
- down: cancel all deployments
- ps: list deployments on the grid
OPTIONS:
- -v, --verbose: show full details of each deployment
- -o, --output: redirects the output to a file given its path
```

Export env vars using:

```bash
export MNEMONIC=your_mnemonics
export NETWORK=working_network
```

Run:

```bash
make build
```

To use any of the commands, run:

```bash
./bin/grid-compose [COMMAND]
```

For example:

```bash
./bin/grid-compose ps -f example/multiple_services_diff_network_3.yml
```

## Usage For Each Command

### up

The up command deploys the services defined in the yaml file to the grid.

Refer to the [cases](docs/cases.md) for more information on the cases supported.

Refer to examples in the [examples](examples) directory to have a look at different possible configurations.

```bash
./bin/grid-compose up [OPTIONS]
```

OPTIONS:

- `-f, --file`: path to the yaml file, default is `./grid-compose.yaml`

### down

```bash
./bin/grid-compose down [OPTIONS]
```

OPTIONS:

- `-f, --file`: path to the yaml file, default is `./grid-compose.yaml`

### ps

```bash
./bin/grid-compose ps [FLAGS] [OPTIONS]
```

OPTIONS:

- `-f, --file`: path to the yaml file, default is `./grid-compose.yaml`
- `-v, --verbose`: show full details of each deployment
- `-o, --output`: redirects the output to a file given its path(in json format)
20 changes: 20 additions & 0 deletions grid-compose/cmd/down.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cmd

import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var downCmd = &cobra.Command{
Use: "down",
Short: "cancel your project on the grid",
Run: func(cmd *cobra.Command, args []string) {
if err := app.Down(); err != nil {
log.Fatal().Err(err).Send()
}
},
}

func init() {
Copy link
Contributor

@Omarabdul3ziz Omarabdul3ziz Aug 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move registering commands to the init() in root.go

rootCmd.AddCommand(downCmd)
}
24 changes: 24 additions & 0 deletions grid-compose/cmd/ps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cmd

import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var psCmd = &cobra.Command{
Use: "ps",
Short: "list deployments on the grid",
Run: func(cmd *cobra.Command, args []string) {
flags := cmd.Flags()

if err := app.Ps(cmd.Context(), flags); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invoke the flags here, and pass to the method only the values it needs

log.Fatal().Err(err).Send()
}
},
}

func init() {
psCmd.PersistentFlags().BoolP("verbose", "v", false, "all information about deployed services")
psCmd.PersistentFlags().StringP("output", "o", "", "output result to a file")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can drop this and simply use bash redirecting. grid-compose ps > dep.json

rootCmd.AddCommand(psCmd)
}
44 changes: 44 additions & 0 deletions grid-compose/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package cmd

import (
"os"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/grid-compose/internal"
)

var (
app *internal.App
configPath string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to avoid the global variable, we could add the app to the context. it will shared between the commands

network string
mnemonic string
)

func Execute() {
if err := rootCmd.Execute(); err != nil {
log.Fatal().Err(err).Send()
}
}

// TODO: Validate command line arguments
var rootCmd = &cobra.Command{
Use: "grid-compose",
Short: "Grid-Compose is a tool for running multi-vm applications on TFGrid defined using a Yaml formatted file.",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
var err error
app, err = internal.NewApp(network, mnemonic, configPath)
if err != nil {
log.Fatal().Err(err).Send()
}
},
}

func init() {
network = os.Getenv("NETWORK")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move getting the env to the Run in rootCmd

mnemonic = os.Getenv("MNEMONIC")
rootCmd.PersistentFlags().StringVarP(&configPath, "file", "f", "./grid-compose.yaml", "the grid-compose configuration file")

log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}
20 changes: 20 additions & 0 deletions grid-compose/cmd/up.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cmd

import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var upCmd = &cobra.Command{
Use: "up",
Short: "deploy application on the grid",
Run: func(cmd *cobra.Command, args []string) {
if err := app.Up(cmd.Context()); err != nil {
log.Fatal().Err(err).Send()
}
},
}

func init() {
rootCmd.AddCommand(upCmd)
}
26 changes: 26 additions & 0 deletions grid-compose/cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Package cmd for parsing command line arguments
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

// set at build time
var commit string
var version string

// versionCmd represents the version command
var versionCmd = &cobra.Command{
Use: "version",
Short: "Get latest build tag",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version)
fmt.Println(commit)
},
}

func init() {
rootCmd.AddCommand(versionCmd)
}
64 changes: 64 additions & 0 deletions grid-compose/docs/cases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
These are most if not all the cases supported by the grid compose cli when deploying one or more service to the grid.

## Single Service

### Case 1 - Node ID Not Given + No Assigned Network

This is probably the simplest case there is.

- Filter the nodes based on the resources given to the service and choose a random one.
- Generate a default network and assign it to the deployment.

Refer to example [single_service_1.yml](../examples/single_service_1.yml)

### Case 2 - Node ID Given + No Assigned Network

- Simply use the the node id given to deploy the service.
- (**CURRENT BEHAVIOR**) Return an error if node is not available
- (**TODO BEHAVIOR**) If the available resources in the given node are less than what the service needs, filter the nodes and check if there is one that can be used.
- If there is a node available, prompt the user if they would like to use it instead.
- Generate a default network and assign it to the deployment.

Refer to example [single_service_2.yml](../examples/single_service_2.yml)

### Case 3 - Assigned Network

- Either use the assigned node id or filter the nodes for an available node if no node id given.
- Use the network assigned to the service when deploying.

Refer to example [single_service_3.yml](../examples/single_service_3.yml)

## Multiple Services

Dealing with multiple services will depend on the networks assigned to each service. In a nutshell, it is assumed that **if two services are assigned the same network they are going to be in the same deployment, which means in the same node,** so failing to stick to this assumption will yield errors and no service will be deployed.

### Same Network/No Network

This is a common general case: Laying down services a user needs to deploy in the same node using a defined network or not defining any network at all.

#### Case 1 - Node ID Given

Essentially what is required is that at least one service is assigned a node id and automatically all the other services assigned to the same network will be deployed using this node.

It is also possible to assign a node id to some of the services or even all of them, but keep in mind that **if two services running on the same network and each one is assigned a different node id, this will cause an error and nothing will be deployed.**

#### Case 2 - No Node ID Given

This is a more common case, the user mostly probably will not care to provide any node ids. In that case:

- The node id will be filtered based on the total resources for the services provided.

<br />
If all the services are assigned a network, then all of them will be deployed using that network.

If no networks are defined, then all the services will use the **default generated network**.

Refer to examples

- [two_services_same_network_1.yml](../examples/two_services_same_network_1.yml)
- [two_services_same_network_2.yml](../examples/two_services_same_network_2.yml)
- [two_services_same_network_3.yml](../examples/two_services_same_network_3.yml)

### Different Networks

Simple divide the services into groups having the same network(given or generated) and deal with each group using the approached described in the previous [section](#same-networkno-network).
Loading
Loading