mirror of https://github.com/dapr/cli.git
229 lines
6.9 KiB
Go
229 lines
6.9 KiB
Go
// ------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
// ------------------------------------------------------------
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/dapr/cli/pkg/kubernetes"
|
|
"github.com/dapr/cli/pkg/print"
|
|
"github.com/dapr/cli/pkg/rundata"
|
|
"github.com/dapr/cli/pkg/standalone"
|
|
"github.com/google/uuid"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
var appPort int
|
|
var profilePort int
|
|
var appID string
|
|
var configFile string
|
|
var port int
|
|
var grpcPort int
|
|
var maxConcurrency int
|
|
var image string
|
|
var enableProfiling bool
|
|
var logLevel string
|
|
var protocol string
|
|
|
|
var RunCmd = &cobra.Command{
|
|
Use: "run",
|
|
Short: "Launches Dapr and your app side by side",
|
|
Args: cobra.MinimumNArgs(1),
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
viper.BindPFlag("placement-host", cmd.Flags().Lookup("placement-host"))
|
|
viper.BindPFlag("redis-host", cmd.Flags().Lookup("redis-host"))
|
|
},
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
uuid, err := uuid.NewRandom()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, err.Error())
|
|
return
|
|
}
|
|
|
|
daprRunID := uuid.String()
|
|
|
|
if kubernetesMode {
|
|
output, err := kubernetes.Run(&kubernetes.RunConfig{
|
|
AppID: appID,
|
|
AppPort: appPort,
|
|
GRPCPort: grpcPort,
|
|
HTTPPort: port,
|
|
Arguments: args,
|
|
Image: image,
|
|
CodeDirectory: args[0],
|
|
})
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, err.Error())
|
|
return
|
|
}
|
|
|
|
print.InfoStatusEvent(os.Stdout, output.Message)
|
|
} else {
|
|
output, err := standalone.Run(&standalone.RunConfig{
|
|
AppID: appID,
|
|
AppPort: appPort,
|
|
HTTPPort: port,
|
|
GRPCPort: grpcPort,
|
|
ConfigFile: configFile,
|
|
Arguments: args,
|
|
EnableProfiling: enableProfiling,
|
|
ProfilePort: profilePort,
|
|
LogLevel: logLevel,
|
|
MaxConcurrency: maxConcurrency,
|
|
Protocol: protocol,
|
|
RedisHost: viper.GetString("redis-host"),
|
|
PlacementHost: viper.GetString("placement-host"),
|
|
})
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, err.Error())
|
|
return
|
|
}
|
|
|
|
var sigCh = make(chan os.Signal)
|
|
signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT)
|
|
|
|
daprRunning := make(chan bool, 1)
|
|
appRunning := make(chan bool, 1)
|
|
daprRunCreatedTime := time.Now()
|
|
|
|
go func() {
|
|
print.InfoStatusEvent(os.Stdout, fmt.Sprintf("Starting Dapr with id %s. HTTP Port: %v. gRPC Port: %v", output.AppID, output.DaprHTTPPort, output.DaprGRPCPort))
|
|
|
|
stdErrPipe, err := output.DaprCMD.StderrPipe()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("Error creating stderr for Dapr: %s", err.Error()))
|
|
os.Exit(1)
|
|
}
|
|
|
|
stdOutPipe, err := output.DaprCMD.StdoutPipe()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("Error creating stdout for Dapr: %s", err.Error()))
|
|
os.Exit(1)
|
|
}
|
|
|
|
errScanner := bufio.NewScanner(stdErrPipe)
|
|
outScanner := bufio.NewScanner(stdOutPipe)
|
|
go func() {
|
|
for errScanner.Scan() {
|
|
fmt.Printf(print.Yellow(fmt.Sprintf("== DAPR == %s\n", errScanner.Text())))
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
for outScanner.Scan() {
|
|
fmt.Printf(print.Yellow(fmt.Sprintf("== DAPR == %s\n", outScanner.Text())))
|
|
}
|
|
}()
|
|
|
|
err = output.DaprCMD.Start()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, err.Error())
|
|
os.Exit(1)
|
|
}
|
|
|
|
daprRunning <- true
|
|
}()
|
|
|
|
<-daprRunning
|
|
|
|
go func() {
|
|
stdErrPipe, err := output.AppCMD.StderrPipe()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("Error creating stderr for App: %s", err.Error()))
|
|
os.Exit(1)
|
|
}
|
|
|
|
stdOutPipe, err := output.AppCMD.StdoutPipe()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("Error creating stdout for App: %s", err.Error()))
|
|
os.Exit(1)
|
|
}
|
|
|
|
errScanner := bufio.NewScanner(stdErrPipe)
|
|
outScanner := bufio.NewScanner(stdOutPipe)
|
|
go func() {
|
|
for errScanner.Scan() {
|
|
fmt.Printf(print.Blue(fmt.Sprintf("== APP == %s\n", errScanner.Text())))
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
for outScanner.Scan() {
|
|
fmt.Printf(print.Blue(fmt.Sprintf("== APP == %s\n", outScanner.Text())))
|
|
}
|
|
}()
|
|
|
|
err = output.AppCMD.Start()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, err.Error())
|
|
os.Exit(1)
|
|
}
|
|
|
|
appRunning <- true
|
|
}()
|
|
|
|
<-appRunning
|
|
|
|
rundata.AppendRunData(&rundata.RunData{
|
|
DaprRunId: daprRunID,
|
|
AppId: output.AppID,
|
|
DaprHTTPPort: output.DaprHTTPPort,
|
|
DaprGRPCPort: output.DaprGRPCPort,
|
|
AppPort: appPort,
|
|
Command: strings.Join(args, " "),
|
|
Created: daprRunCreatedTime,
|
|
PID: os.Getpid(),
|
|
})
|
|
|
|
print.SuccessStatusEvent(os.Stdout, "You're up and running! Both Dapr and your app logs will appear here.\n")
|
|
|
|
<-sigCh
|
|
print.InfoStatusEvent(os.Stdout, "\nterminated signal received: shutting down")
|
|
|
|
rundata.ClearRunData(daprRunID)
|
|
|
|
err = output.DaprCMD.Process.Kill()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("Error exiting Dapr: %s", err))
|
|
} else {
|
|
print.SuccessStatusEvent(os.Stdout, "Exited Dapr successfully")
|
|
}
|
|
|
|
err = output.AppCMD.Process.Kill()
|
|
if err != nil {
|
|
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("Error exiting App: %s", err))
|
|
} else {
|
|
print.SuccessStatusEvent(os.Stdout, "Exited App successfully")
|
|
}
|
|
}
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
RunCmd.Flags().IntVarP(&appPort, "app-port", "", -1, "the port your application is listening on")
|
|
RunCmd.Flags().StringVarP(&appID, "app-id", "", "", "an id for your application, used for service discovery")
|
|
RunCmd.Flags().StringVarP(&configFile, "config", "", "", "Dapr configuration file")
|
|
RunCmd.Flags().IntVarP(&port, "port", "p", -1, "the HTTP port for Dapr to listen on")
|
|
RunCmd.Flags().IntVarP(&grpcPort, "grpc-port", "", -1, "the gRPC port for Dapr to listen on")
|
|
RunCmd.Flags().StringVarP(&image, "image", "", "", "the image to build the code in. input is repository/image")
|
|
RunCmd.Flags().BoolVar(&enableProfiling, "enable-profiling", false, "Enable pprof profiling via an HTTP endpoint")
|
|
RunCmd.Flags().IntVarP(&profilePort, "profile-port", "", -1, "the port for the profile server to listen on")
|
|
RunCmd.Flags().StringVarP(&logLevel, "log-level", "", "info", "Sets the log verbosity. Valid values are: debug, info, warning, error, fatal, or panic. Default is info")
|
|
RunCmd.Flags().IntVarP(&maxConcurrency, "max-concurrency", "", -1, "controls the concurrency level of the app. Default is unlimited")
|
|
RunCmd.Flags().StringVarP(&protocol, "protocol", "", "http", "tells Dapr to use HTTP or gRPC to talk to the app. Default is http")
|
|
RunCmd.Flags().String("redis-host", "localhost", "the host on which the Redis service resides")
|
|
RunCmd.Flags().String("placement-host", "localhost", "the host on which the placement service resides")
|
|
|
|
RootCmd.AddCommand(RunCmd)
|
|
}
|