diff --git a/pkg/cmd/migrate/migrate.go b/pkg/cmd/migrate/migrate.go index 474a2957f0..632c77850f 100644 --- a/pkg/cmd/migrate/migrate.go +++ b/pkg/cmd/migrate/migrate.go @@ -25,12 +25,12 @@ func NewMigrateCommand(programName string) *cobra.Command { Short: "execute datastore schema migrations", Long: fmt.Sprintf("Executes datastore schema migrations for the datastore.\nThe special value \"%s\" can be used to migrate to the latest revision.", color.YellowString(migrate.Head)), PreRunE: cmdutil.DefaultPreRunE(programName), - Run: migrateRun, + RunE: migrateRun, Args: cobra.ExactArgs(1), } } -func migrateRun(cmd *cobra.Command, args []string) { +func migrateRun(cmd *cobra.Command, args []string) error { datastoreEngine := cobrautil.MustGetStringExpanded(cmd, "datastore-engine") dbURL := cobrautil.MustGetStringExpanded(cmd, "datastore-conn-uri") @@ -64,8 +64,10 @@ func migrateRun(cmd *cobra.Command, args []string) { log.Fatal().Err(err).Msg("unable to complete requested migrations") } } else { - log.Fatal().Str("datastore-engine", datastoreEngine).Msg("cannot migrate datastore engine type") + return fmt.Errorf("cannot migrate datastore engine type: %s", datastoreEngine) } + + return nil } func RegisterHeadFlags(cmd *cobra.Command) { @@ -77,12 +79,12 @@ func NewHeadCommand(programName string) *cobra.Command { Use: "head", Short: "compute the head database migration revision", PreRunE: cmdutil.DefaultPreRunE(programName), - Run: headRevisionRun, + RunE: headRevisionRun, Args: cobra.ExactArgs(0), } } -func headRevisionRun(cmd *cobra.Command, args []string) { +func headRevisionRun(cmd *cobra.Command, args []string) error { var ( engine = cobrautil.MustGetStringExpanded(cmd, "datastore-engine") headRevision string @@ -95,11 +97,12 @@ func headRevisionRun(cmd *cobra.Command, args []string) { case "postgres": headRevision, err = migrations.DatabaseMigrations.HeadRevision() default: - log.Fatal().Str("engine", engine).Msg("cannot migrate datastore engine type") + return fmt.Errorf("cannot migrate datastore engine type: %s", engine) } if err != nil { log.Fatal().Err(err).Msg("unable to compute head revision") } fmt.Println(headRevision) + return nil } diff --git a/pkg/cmd/serve/devtools.go b/pkg/cmd/serve/devtools.go index e2e9e2b57e..1154500e07 100644 --- a/pkg/cmd/serve/devtools.go +++ b/pkg/cmd/serve/devtools.go @@ -48,12 +48,12 @@ func NewDevtoolsCommand(programName string) *cobra.Command { Short: "runs the developer tools service", Long: "Serves the authzed.api.v0.DeveloperService which is used for development tooling such as the Authzed Playground", PreRunE: cmdutil.DefaultPreRunE(programName), - Run: runfunc, + RunE: runfunc, Args: cobra.ExactArgs(0), } } -func runfunc(cmd *cobra.Command, args []string) { +func runfunc(cmd *cobra.Command, args []string) error { grpcServer, err := cobrautil.GrpcServerFromFlags(cmd, "grpc", grpc.ChainUnaryInterceptor( grpclog.UnaryServerInterceptor(grpczerolog.InterceptorLogger(log.Logger)), otelgrpc.UnaryServerInterceptor(), @@ -100,6 +100,8 @@ func runfunc(cmd *cobra.Command, args []string) { if err := metricsSrv.Close(); err != nil { log.Fatal().Err(err).Msg("failed while shutting down metrics server") } + + return nil } func shareStoreFromCmd(cmd *cobra.Command) (v0svc.ShareStore, error) { diff --git a/pkg/cmd/serve/serve.go b/pkg/cmd/serve/serve.go index e70eeb70ea..7e48c2de29 100644 --- a/pkg/cmd/serve/serve.go +++ b/pkg/cmd/serve/serve.go @@ -2,6 +2,7 @@ package serve import ( "context" + "errors" "time" grpcauth "github.com/grpc-ecosystem/go-grpc-middleware/auth" @@ -81,21 +82,21 @@ func NewServeCommand(programName string, dsConfig *cmdutil.DatastoreConfig) *cob Short: "serve the permissions database", Long: "A database that stores, computes, and validates application permissions", PreRunE: cmdutil.DefaultPreRunE(programName), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { signalctx := cmdutil.SignalContextWithGracePeriod( context.Background(), cobrautil.MustGetDuration(cmd, "grpc-shutdown-grace-period"), ) - serveRun(signalctx, cmd, args, dsConfig) + return serveRun(signalctx, cmd, args, dsConfig) }, Example: cmdutil.ServeExample(programName), } } -func serveRun(ctx context.Context, cmd *cobra.Command, args []string, datastoreOpts *cmdutil.DatastoreConfig) { +func serveRun(ctx context.Context, cmd *cobra.Command, args []string, datastoreOpts *cmdutil.DatastoreConfig) error { token := cobrautil.MustGetStringExpanded(cmd, "grpc-preshared-key") if len(token) < 1 { - log.Fatal().Msg("a preshared key must be provided via --grpc-preshared-key to authenticate API requests") + return errors.New("a preshared key must be provided via --grpc-preshared-key to authenticate API requests") } ds, err := cmdutil.NewDatastore(datastoreOpts.ToOption()) @@ -122,7 +123,7 @@ func serveRun(ctx context.Context, cmd *cobra.Command, args []string, datastoreO log.Fatal().Err(err).Msg("failed to load bootstrap files") } } else { - log.Fatal().Err(err).Msg("cannot apply bootstrap data: schema or tuples already exist in the datastore. Delete existing data or set the flag --datastore-bootstrap-overwrite=true") + return errors.New("cannot apply bootstrap data: schema or tuples already exist in the datastore. Delete existing data or set the flag --datastore-bootstrap-overwrite=true") } } @@ -301,4 +302,6 @@ func serveRun(ctx context.Context, cmd *cobra.Command, args []string, datastoreO if err := dashboardSrv.Close(); err != nil { log.Fatal().Err(err).Msg("failed while shutting down dashboard") } + + return nil } diff --git a/pkg/cmd/serve/testing.go b/pkg/cmd/serve/testing.go index 9d084b58e1..6250fc771d 100644 --- a/pkg/cmd/serve/testing.go +++ b/pkg/cmd/serve/testing.go @@ -56,11 +56,11 @@ func NewTestingCommand(programName string) *cobra.Command { Short: "test server with an in-memory datastore", Long: "An in-memory spicedb server which serves completely isolated datastores per client-supplied auth token used.", PreRunE: cmdutil.DefaultPreRunE(programName), - Run: runTestServer, + RunE: runTestServer, } } -func runTestServer(cmd *cobra.Command, args []string) { +func runTestServer(cmd *cobra.Command, args []string) error { configFilePaths := cobrautil.MustGetStringSliceExpanded(cmd, "load-configs") backendMiddleware := &perTokenBackendMiddleware{ @@ -107,6 +107,8 @@ func runTestServer(cmd *cobra.Command, args []string) { log.Info().Msg("received interrupt") grpcServer.GracefulStop() readonlyServer.GracefulStop() + + return nil } type dummyBackend struct {