-
Notifications
You must be signed in to change notification settings - Fork 402
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Yifei Feng <[email protected]>
- Loading branch information
1 parent
2ddaba6
commit 3cd3009
Showing
28 changed files
with
2,072 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# KubeRay CLI | ||
|
||
[![Build Status](https://github.com/ray-project/kuberay/workflows/Go-build-and-test/badge.svg)](https://github.com/ray-project/kuberay/actions) | ||
[![Go Report Card](https://goreportcard.com/badge/github.com/ray-project/kuberay)](https://goreportcard.com/report/github.com/ray-project/kuberay) | ||
|
||
# Overview | ||
KubeRay CLI provides the ability to manage kuberay resources (ray clusters, compute templates etc) through command line interface. | ||
|
||
# Implementation | ||
- Kuberay CLI uses [Cobra framework](https://github.com/spf13/cobra) for the CLI application. | ||
- Kuberay CLI depends on kuberay apiserver to manage these resources by sending grpc requests to the kuberay apiserver. | ||
|
||
# Installation | ||
TBD | ||
|
||
# Prerequisites | ||
- Kuberay apiserver needs to be running and accessible. | ||
|
||
# Build | ||
`cd kuberay/cli` | ||
`go build -o kuberay -a main.go` | ||
|
||
# Use | ||
## Connect to kuberay apiserver | ||
- Default kuberay apiserver endpoint: `127.0.0.1:8887`. | ||
- If kuberay apiserver is not run locally, this must be set in order to manage ray clusters and ray compute templates. | ||
### Read current kuberay apiserver endpoint | ||
`./kuberay config get endpoint` | ||
### Reset kuberay apiserver endpoint to default (`127.0.0.1:8887`) | ||
`./kuberay config reset endpoint` | ||
### Set kuberay apiserver endpoint | ||
`./kuberay config set endpoint <kuberay apiserver endpoint>` | ||
## Manage Ray Clusters | ||
### Create a Ray Cluster | ||
```` | ||
Usage: | ||
kuberay cluster create [flags] | ||
Flags: | ||
--environment string environment of the cluster (valid values: DEV, TESTING, STAGING, PRODUCTION) (default "DEV") | ||
--head-compute-tempalte string compuate template name for ray head | ||
--head-image string ray head image | ||
--head-service-type string ray head service type (ClusterIP, NodePort, LoadBalancer) (default "ClusterIP") | ||
--name string name of the cluster | ||
--namespace string kubernetes namespace where the cluster will be (default "ray-system") | ||
--user string SSO username of ray cluster creator | ||
--version string version of the ray cluster (default "1.9.0") | ||
--worker-compute-template string compute template name of worker in the first worker group | ||
--worker-group-name string first worker group name | ||
--worker-image string image of worker in the first worker group | ||
--worker-replicas uint32 pod replicas of workers in the first worker group (default 1) | ||
```` | ||
- Limitation: Currently only one worker compute template is supported during creation. | ||
### Get a Ray Cluster | ||
`./kuberay cluster get <cluster name>` | ||
### List Ray Clusters | ||
`./kuberay cluster list` | ||
### Delete a Ray Cluster | ||
`./kuberay cluster delete <cluster name>` | ||
## Manage Ray Compute Template | ||
### Create a Compute Template | ||
```` | ||
Usage: | ||
kuberay template compute create [flags] | ||
Flags: | ||
--cpu uint32 ray pod CPU (default 1) | ||
--gpu uint32 ray head GPU | ||
--gpu-accelerator string GPU Accelerator type | ||
--memory uint32 ray pod memory in GB (default 1) | ||
--name string name of the compute template | ||
```` | ||
### Get a Ray Compute Template | ||
`./kuberay template compute get <compute template name>` | ||
### List Ray Compute Templates | ||
`./kuberay template compute list` | ||
### Delete a Ray Compute Template | ||
`./kuberay template compute delete <compute template name>` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
"time" | ||
|
||
"github.com/ray-project/kuberay/cli/pkg/cmd/cluster" | ||
"github.com/ray-project/kuberay/cli/pkg/cmd/config" | ||
"github.com/ray-project/kuberay/cli/pkg/cmd/info" | ||
"github.com/ray-project/kuberay/cli/pkg/cmd/template" | ||
"github.com/ray-project/kuberay/cli/pkg/cmd/version" | ||
"github.com/ray-project/kuberay/cli/pkg/cmdutil" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/fatih/color" | ||
"github.com/kris-nova/logger" | ||
lol "github.com/kris-nova/lolgopher" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
var cfgFile string | ||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "kuberay", | ||
Short: "kuberay offers life cycle management of ray clusters", | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
cobra.CheckErr(rootCmd.Execute()) | ||
} | ||
|
||
func init() { | ||
loggerLevel := rootCmd.PersistentFlags().IntP("log-level", "l", 3, "set log level, use 0 to silence, 4 for debugging and 5 for debugging with AWS debug logging") | ||
colorValue := rootCmd.PersistentFlags().StringP("color", "C", "true", "toggle colorized logs (valid options: true, false, fabulous)") | ||
cobra.OnInitialize(initConfig, func() { | ||
initLogger(*loggerLevel, *colorValue) | ||
}) | ||
|
||
// Here you will define your flags and configuration settings. | ||
// Cobra supports persistent flags, which, if defined here, | ||
// will be global for your application. | ||
|
||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.kuberay.yaml)") | ||
|
||
// Cobra also supports local flags, which will only run | ||
// when this action is called directly. | ||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") | ||
|
||
rootCmd.PersistentFlags().BoolP("help", "h", false, "help for this command") | ||
rootCmd.AddCommand(info.NewCmdInfo()) | ||
rootCmd.AddCommand(version.NewCmdVersion()) | ||
rootCmd.AddCommand(cluster.NewCmdCluster()) | ||
rootCmd.AddCommand(template.NewCmdTemplate()) | ||
rootCmd.AddCommand(config.NewCmdConfig()) | ||
} | ||
|
||
// initConfig reads in config file and ENV variables if set. | ||
func initConfig() { | ||
if cfgFile != "" { | ||
// Use config file from the flag. | ||
viper.SetConfigFile(cfgFile) | ||
} else { | ||
// Find home directory. | ||
home, err := os.UserHomeDir() | ||
cobra.CheckErr(err) | ||
|
||
// Search config in home directory with name ".cli" (without extension). | ||
viper.AddConfigPath(home) | ||
viper.SetConfigType("yaml") | ||
viper.SetConfigName(".kuberay") | ||
|
||
viper.SetDefault("endpoint", fmt.Sprintf("%s:%s", cmdutil.DefaultRpcAddress, cmdutil.DefaultRpcPort)) | ||
// Do not write to file system if it already exists | ||
viper.SafeWriteConfig() | ||
} | ||
|
||
viper.AutomaticEnv() // read in environment variables that match | ||
|
||
viper.ReadInConfig() | ||
} | ||
|
||
func initLogger(level int, colorValue string) { | ||
logger.Layout = "2021-01-02 15:04:05" | ||
|
||
var bitwiseLevel int | ||
switch level { | ||
case 4: | ||
bitwiseLevel = logger.LogDeprecated | logger.LogAlways | logger.LogSuccess | logger.LogCritical | logger.LogWarning | logger.LogInfo | logger.LogDebug | ||
case 3: | ||
bitwiseLevel = logger.LogDeprecated | logger.LogAlways | logger.LogSuccess | logger.LogCritical | logger.LogWarning | logger.LogInfo | ||
case 2: | ||
bitwiseLevel = logger.LogDeprecated | logger.LogAlways | logger.LogSuccess | logger.LogCritical | logger.LogWarning | ||
case 1: | ||
bitwiseLevel = logger.LogDeprecated | logger.LogAlways | logger.LogSuccess | logger.LogCritical | ||
case 0: | ||
bitwiseLevel = logger.LogDeprecated | logger.LogAlways | logger.LogSuccess | ||
default: | ||
bitwiseLevel = logger.LogDeprecated | logger.LogEverything | ||
} | ||
logger.BitwiseLevel = bitwiseLevel | ||
|
||
switch colorValue { | ||
case "fabulous": | ||
logger.Writer = lol.NewLolWriter() | ||
case "true": | ||
logger.Writer = color.Output | ||
} | ||
|
||
logger.Line = func(prefix, format string, a ...interface{}) string { | ||
if !strings.Contains(format, "\n") { | ||
format = fmt.Sprintf("%s%s", format, "\n") | ||
} | ||
now := time.Now() | ||
fNow := now.Format(logger.Layout) | ||
var colorize func(format string, a ...interface{}) string | ||
var icon string | ||
switch prefix { | ||
case logger.PreAlways: | ||
icon = "✿" | ||
colorize = color.GreenString | ||
case logger.PreCritical: | ||
icon = "✖" | ||
colorize = color.RedString | ||
case logger.PreInfo: | ||
icon = "ℹ" | ||
colorize = color.CyanString | ||
case logger.PreDebug: | ||
icon = "▶" | ||
colorize = color.GreenString | ||
case logger.PreSuccess: | ||
icon = "✔" | ||
colorize = color.CyanString | ||
case logger.PreWarning: | ||
icon = "!" | ||
colorize = color.GreenString | ||
default: | ||
icon = "ℹ" | ||
colorize = color.CyanString | ||
} | ||
|
||
out := fmt.Sprintf(format, a...) | ||
out = fmt.Sprintf("%s [%s] %s", fNow, icon, out) | ||
if colorValue == "true" { | ||
out = colorize(out) | ||
} | ||
|
||
return out | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
module github.com/ray-project/kuberay/cli | ||
|
||
go 1.17 | ||
|
||
require ( | ||
github.com/fatih/color v1.13.0 | ||
github.com/kris-nova/logger v0.2.2 | ||
github.com/kris-nova/lolgopher v0.0.0-20210112022122-73f0047e8b65 | ||
github.com/olekukonko/tablewriter v0.0.5 | ||
github.com/ray-project/kuberay/proto v0.0.0-20220119062608-4054f1bf1765 | ||
github.com/spf13/cobra v1.3.0 | ||
github.com/spf13/viper v1.10.1 | ||
google.golang.org/grpc v1.43.0 | ||
) | ||
|
||
require ( | ||
github.com/fsnotify/fsnotify v1.5.1 // indirect | ||
github.com/golang/protobuf v1.5.2 // indirect | ||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect | ||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 // indirect | ||
github.com/hashicorp/hcl v1.0.0 // indirect | ||
github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||
github.com/magiconair/properties v1.8.5 // indirect | ||
github.com/mattn/go-colorable v0.1.12 // indirect | ||
github.com/mattn/go-isatty v0.0.14 // indirect | ||
github.com/mattn/go-runewidth v0.0.13 // indirect | ||
github.com/mitchellh/mapstructure v1.4.3 // indirect | ||
github.com/pelletier/go-toml v1.9.4 // indirect | ||
github.com/rivo/uniseg v0.2.0 // indirect | ||
github.com/spf13/afero v1.6.0 // indirect | ||
github.com/spf13/cast v1.4.1 // indirect | ||
github.com/spf13/jwalterweatherman v1.1.0 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
github.com/subosito/gotenv v1.2.0 // indirect | ||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect | ||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect | ||
golang.org/x/text v0.3.7 // indirect | ||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect | ||
google.golang.org/protobuf v1.27.1 // indirect | ||
gopkg.in/ini.v1 v1.66.2 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
) |
Oops, something went wrong.