diff --git a/internal/cli/daemon/daemon.go b/internal/cli/daemon/daemon.go index 839738b8999..ea9476a2ec7 100644 --- a/internal/cli/daemon/daemon.go +++ b/internal/cli/daemon/daemon.go @@ -34,16 +34,14 @@ import ( "google.golang.org/grpc" ) -var ( - daemonize bool - debug bool - debugFile string - debugFilters []string -) - // NewCommand created a new `daemon` command func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) *cobra.Command { + var daemonize bool + var debug bool + var debugFile string + var debugFiltersArg []string var daemonPort string + var maxGRPCRecvMsgSize int daemonCommand := &cobra.Command{ Use: "daemon", Short: i18n.Tr("Run the Arduino CLI as a gRPC daemon."), @@ -63,9 +61,14 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) * panic("Failed to set default value for directories.builtin.libraries: " + err.Error()) } } + + // Validate the maxGRPCRecvMsgSize flag + if maxGRPCRecvMsgSize < 1024 { + feedback.Fatal(i18n.Tr("%s must be >= 1024", "--max-grpc-recv-message-size"), feedback.ErrBadArgument) + } }, Run: func(cmd *cobra.Command, args []string) { - runDaemonCommand(srv, daemonPort) + runDaemonCommand(srv, daemonPort, debugFile, debug, daemonize, debugFiltersArg, maxGRPCRecvMsgSize) }, } defaultDaemonPort := settings.GetDaemon().GetPort() @@ -82,13 +85,16 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) * daemonCommand.Flags().StringVar(&debugFile, "debug-file", "", i18n.Tr("Append debug logging to the specified file")) - daemonCommand.Flags().StringSliceVar(&debugFilters, + daemonCommand.Flags().StringSliceVar(&debugFiltersArg, "debug-filter", []string{}, i18n.Tr("Display only the provided gRPC calls")) + daemonCommand.Flags().IntVar(&maxGRPCRecvMsgSize, + "max-grpc-recv-message-size", 16*1024*1024, + i18n.Tr("Sets the maximum message size in bytes the daemon can receive")) return daemonCommand } -func runDaemonCommand(srv rpc.ArduinoCoreServiceServer, daemonPort string) { +func runDaemonCommand(srv rpc.ArduinoCoreServiceServer, daemonPort, debugFile string, debug, daemonize bool, debugFiltersArg []string, maxGRPCRecvMsgSize int) { logrus.Info("Executing `arduino-cli daemon`") gRPCOptions := []grpc.ServerOption{} @@ -113,11 +119,13 @@ func runDaemonCommand(srv rpc.ArduinoCoreServiceServer, daemonPort string) { debugStdOut = out } } + debugFilters = debugFiltersArg gRPCOptions = append(gRPCOptions, grpc.UnaryInterceptor(unaryLoggerInterceptor), grpc.StreamInterceptor(streamLoggerInterceptor), ) } + gRPCOptions = append(gRPCOptions, grpc.MaxRecvMsgSize(maxGRPCRecvMsgSize)) s := grpc.NewServer(gRPCOptions...) // register the commands service diff --git a/internal/cli/daemon/interceptors.go b/internal/cli/daemon/interceptors.go index 0da2307b1aa..242d7610609 100644 --- a/internal/cli/daemon/interceptors.go +++ b/internal/cli/daemon/interceptors.go @@ -28,6 +28,7 @@ import ( var debugStdOut io.Writer var debugSeq uint32 +var debugFilters []string func log(isRequest bool, seq uint32, msg interface{}) { prefix := fmt.Sprint(seq, " | ")