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

implementation of a docker-compose-like cli for managing deployment of services simultaneously #1155

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
2 changes: 2 additions & 0 deletions grid-compose/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ bin/*
.pre-commit-config.yaml
out
full_example.yml
invalid
grid-compose.yml
86 changes: 79 additions & 7 deletions grid-compose/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Grid-Compose

is a tool for running multi-vm applications on TFGrid defined using a Yaml formatted file.
is a tool similar to docker-compose created for running multi-vm applications on TFGrid defined using a Yaml formatted file.

The yaml file's structure is defined in [docs/config](docs/config.md).

## Usage

Expand All @@ -13,7 +15,7 @@ is a tool for running multi-vm applications on TFGrid defined using a Yaml forma
grid-compose [OPTIONS] [COMMAND]

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

COMMANDS:
- version: shows the project version
Expand All @@ -22,7 +24,6 @@ COMMANDS:
- 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:
Expand Down Expand Up @@ -66,26 +67,97 @@ Refer to examples in the [examples](examples) directory to have a look at differ

OPTIONS:

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

### Example

```bash
./bin/grid-compose up
```

output:

```bash
3:40AM INF starting peer session=tf-848216 twin=8658
3:40AM INF deploying network... name=miaminet node_id=14
3:41AM INF deployed successfully
3:41AM INF deploying vm... name=database node_id=14
3:41AM INF deployed successfully
3:41AM INF deploying network... name=miaminet node_id=14
3:41AM INF deployed successfully
3:41AM INF deploying vm... name=server node_id=14
3:41AM INF deployed successfully
3:41AM INF all deployments deployed successfully
```

### down

The down command cancels all deployments on the grid.

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

OPTIONS:

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

### Example

```bash
./bin/grid-compose down
```

output:

```bash
3:45AM INF starting peer session=tf-854215 twin=8658
3:45AM INF canceling deployments projectName=compose/8658/net1
3:45AM INF canceling contracts project name=compose/8658/net1
3:45AM INF project is canceled project name=compose/8658/net1
```

### ps

The ps command lists all deployments on the grid.

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

OPTIONS:

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

### Example

```bash
./bin/grid-compose ps
```

output:

```bash
3:43AM INF starting peer session=tf-851312 twin=8658

Deployment Name | Node ID | Network | Services | Storage | State | IP Address
------------------------------------------------------------------------------------------------------------------------------------------------------
dl_database | 14 | miaminet | database | dbdata | ok | wireguard: 10.20.2.2
dl_server | 14 | miaminet | server | webdata | ok | wireguard: 10.20.2.3
```

FLAGS:

- `-v, --verbose`: show full details of each deployment
- `-o, --output`: redirects the output to a file given its path(in json format)

### version

The version command shows the project's current version.

```bash
./bin/grid-compose version
```

## Future Work

Refer to [docs/future_work.md](docs/future_work.md) for more information on the future work that is to be done on the grid-compose project.
10 changes: 6 additions & 4 deletions grid-compose/cmd/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package cmd
import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/grid-compose/internal/app"
)

var downCmd = &cobra.Command{
Use: "down",
Short: "cancel your project on the grid",
Run: func(cmd *cobra.Command, args []string) {
app, ok := cmd.Context().Value("app").(*app.App)
if !ok {
log.Fatal().Msg("app not found in context")
}

if err := app.Down(); err != nil {
log.Fatal().Err(err).Send()
}
},
}

func init() {
rootCmd.AddCommand(downCmd)
}
19 changes: 11 additions & 8 deletions grid-compose/cmd/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ package cmd
import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/grid-compose/internal/app"
)

var psCmd = &cobra.Command{
Use: "ps",
Short: "list deployments on the grid",
Run: func(cmd *cobra.Command, args []string) {
flags := cmd.Flags()
verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
log.Fatal().Err(err).Send()
}

app, ok := cmd.Context().Value("app").(*app.App)
if !ok {
log.Fatal().Msg("app not found in context")
}

if err := app.Ps(cmd.Context(), flags); err != nil {
if err := app.Ps(cmd.Context(), verbose); err != nil {
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")
rootCmd.AddCommand(psCmd)
}
34 changes: 20 additions & 14 deletions grid-compose/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
package cmd

import (
"context"
"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
network string
mnemonic string
"github.com/threefoldtech/tfgrid-sdk-go/grid-compose/internal/app"
)

func Execute() {
Expand All @@ -22,23 +16,35 @@ func Execute() {
}
}

// TODO: Validate command line arguments
// 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)
network := os.Getenv("NETWORK")
mnemonic := os.Getenv("MNEMONIC")
configPath, _ := cmd.Flags().GetString("file")

app, err := app.NewApp(network, mnemonic, configPath)

if err != nil {
log.Fatal().Err(err).Send()
}

ctx := context.WithValue(cmd.Context(), "app", app)
cmd.SetContext(ctx)
},
}

func init() {
network = os.Getenv("NETWORK")
mnemonic = os.Getenv("MNEMONIC")
rootCmd.PersistentFlags().StringVarP(&configPath, "file", "f", "./grid-compose.yaml", "the grid-compose configuration file")
rootCmd.PersistentFlags().StringP("file", "f", "./grid-compose.yml", "the grid-compose configuration file")

rootCmd.AddCommand(downCmd)
rootCmd.AddCommand(upCmd)
rootCmd.AddCommand(versionCmd)

psCmd.PersistentFlags().BoolP("verbose", "v", false, "all information about deployed services")
rootCmd.AddCommand(psCmd)

log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}
10 changes: 6 additions & 4 deletions grid-compose/cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package cmd
import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/grid-compose/internal/app"
)

var upCmd = &cobra.Command{
Use: "up",
Short: "deploy application on the grid",
Run: func(cmd *cobra.Command, args []string) {
app, ok := cmd.Context().Value("app").(*app.App)
if !ok {
log.Fatal().Msg("app not found in context")
}

if err := app.Up(cmd.Context()); err != nil {
log.Fatal().Err(err).Send()
}
},
}

func init() {
rootCmd.AddCommand(upCmd)
}
10 changes: 3 additions & 7 deletions grid-compose/cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package cmd

import (
"fmt"
"log"

"github.com/spf13/cobra"
)
Expand All @@ -16,11 +16,7 @@ var versionCmd = &cobra.Command{
Use: "version",
Short: "Get latest build tag",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version)
fmt.Println(commit)
log.Println(version)
log.Println(commit)
},
}

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

## Single Service

Expand All @@ -9,7 +9,7 @@ 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)
Refer to example [single_service_1.yml](/examples/single-service/single_service_1.yml)

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

Expand All @@ -19,14 +19,14 @@ Refer to example [single_service_1.yml](../examples/single_service_1.yml)
- 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)
Refer to example [single_service_2.yml](/examples/single-service/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)
Refer to example [single_service_3.yml](/examples/single-service/single_service_3.yml)

## Multiple Services

Expand Down Expand Up @@ -55,10 +55,29 @@ If no networks are defined, then all the services will use the **default generat

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)
- [two_services_same_network_1.yml](/examples/multiple-services/two_services_same_network_1.yml)
- [two_services_same_network_2.yml](/examples/multiple-services/two_services_same_network_2.yml)
- [two_services_same_network_3.yml](/examples/multiple-services/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).

Refer to examples

- [multiple_services_diff_network_1.yml](/examples/multiple-services/multiple_services_diff_network_1.yml)
- [multiple_services_diff_network_2.yml](/examples/multiple-services/multiple_services_diff_network_2.yml)
- [multiple_services_diff_network_3.yml](/examples/multiple-services/multiple_services_diff_network_3.yml)

## Dependencies

The tool supports deploying services that depend on each other. You can define dependencies in the yaml file by using the `depends_on` key, just like in docker-compose.

Refer to examples:

- deploying services that depend on each other on different networks:
- [diff_networks.yml](/examples/dependency/diff_networks.yml)
- deploying services that depend on each other on the same network:
- [same_network.yml](/examples/dependency/same_network.yml)
- a service that would depend on multiple services:
- [multiple_dependencies.yml](/examples/dependency/multiple_dependencies.yml)
Loading
Loading