2020-07-10 17:17:51 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-01-12 14:05:08 +03:00
|
|
|
"context"
|
2020-09-16 10:45:08 +03:00
|
|
|
"flag"
|
2021-05-31 08:11:23 +03:00
|
|
|
"fmt"
|
2020-08-21 18:01:59 +03:00
|
|
|
"log"
|
2021-07-06 16:24:18 +03:00
|
|
|
"os"
|
2020-08-21 18:01:59 +03:00
|
|
|
|
2023-03-07 16:38:26 +03:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
2023-04-12 17:35:10 +03:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
2023-03-07 16:38:26 +03:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/misc"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
2021-01-12 14:05:08 +03:00
|
|
|
"go.uber.org/zap"
|
2020-07-10 17:17:51 +03:00
|
|
|
)
|
|
|
|
|
2021-07-06 16:24:18 +03:00
|
|
|
const (
|
2022-10-17 15:03:55 +03:00
|
|
|
// SuccessReturnCode returns when application closed without panic.
|
2021-07-06 16:24:18 +03:00
|
|
|
SuccessReturnCode = 0
|
|
|
|
)
|
|
|
|
|
2021-05-31 08:11:23 +03:00
|
|
|
// prints err to standard logger and calls os.Exit(1).
|
2020-08-21 18:01:59 +03:00
|
|
|
func fatalOnErr(err error) {
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-31 08:11:23 +03:00
|
|
|
// prints err with details to standard logger and calls os.Exit(1).
|
|
|
|
func fatalOnErrDetails(details string, err error) {
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(fmt.Errorf("%s: %w", details, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 17:17:51 +03:00
|
|
|
func main() {
|
2020-09-16 10:45:08 +03:00
|
|
|
configFile := flag.String("config", "", "path to config")
|
2023-02-06 16:53:16 +03:00
|
|
|
configDir := flag.String("config-dir", "", "path to config directory")
|
2022-12-23 20:35:35 +03:00
|
|
|
versionFlag := flag.Bool("version", false, "frostfs node version")
|
2022-09-20 16:29:09 +03:00
|
|
|
dryRunFlag := flag.Bool("check", false, "validate configuration and exit")
|
2020-09-16 10:45:08 +03:00
|
|
|
flag.Parse()
|
|
|
|
|
2021-07-06 16:24:18 +03:00
|
|
|
if *versionFlag {
|
2023-01-27 13:41:03 +03:00
|
|
|
fmt.Print(misc.BuildInfo("FrostFS Storage node"))
|
2021-07-06 16:24:18 +03:00
|
|
|
|
|
|
|
os.Exit(SuccessReturnCode)
|
|
|
|
}
|
|
|
|
|
2023-04-25 10:04:26 +03:00
|
|
|
appCfg := config.New(*configFile, *configDir, config.EnvPrefix)
|
2022-09-20 16:20:45 +03:00
|
|
|
|
|
|
|
err := validateConfig(appCfg)
|
|
|
|
fatalOnErr(err)
|
|
|
|
|
2022-09-20 16:29:09 +03:00
|
|
|
if *dryRunFlag {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-09-20 16:20:45 +03:00
|
|
|
c := initCfg(appCfg)
|
2020-08-21 18:01:59 +03:00
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
|
|
|
|
initApp(ctx, c)
|
2020-08-24 12:40:32 +03:00
|
|
|
|
2021-01-15 13:28:37 +03:00
|
|
|
c.setHealthStatus(control.HealthStatus_STARTING)
|
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
bootUp(ctx, c)
|
2020-08-24 12:40:32 +03:00
|
|
|
|
2021-01-15 13:28:37 +03:00
|
|
|
c.setHealthStatus(control.HealthStatus_READY)
|
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
wait(c, cancel)
|
2020-08-24 12:40:32 +03:00
|
|
|
}
|
|
|
|
|
2022-05-25 19:18:36 +03:00
|
|
|
func initAndLog(c *cfg, name string, initializer func(*cfg)) {
|
|
|
|
c.log.Info(fmt.Sprintf("initializing %s service...", name))
|
|
|
|
initializer(c)
|
|
|
|
c.log.Info(fmt.Sprintf("%s service has been successfully initialized", name))
|
|
|
|
}
|
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
func initApp(ctx context.Context, c *cfg) {
|
2023-01-27 18:12:03 +03:00
|
|
|
c.wg.Add(1)
|
|
|
|
go func() {
|
2023-03-23 17:59:14 +03:00
|
|
|
c.signalWatcher(ctx)
|
2023-01-27 18:12:03 +03:00
|
|
|
c.wg.Done()
|
|
|
|
}()
|
2022-09-26 16:26:41 +03:00
|
|
|
|
2022-11-24 14:36:49 +03:00
|
|
|
metrics, _ := metricsComponent(c)
|
2023-02-01 10:21:17 +03:00
|
|
|
initAndLog(c, "profiler", initProfilerService)
|
2022-11-24 14:36:49 +03:00
|
|
|
initAndLog(c, metrics.name, metrics.init)
|
2023-03-13 14:01:43 +03:00
|
|
|
|
|
|
|
initAndLog(c, "tracing", func(c *cfg) { initTracing(ctx, c) })
|
2023-01-27 18:12:03 +03:00
|
|
|
|
|
|
|
initLocalStorage(c)
|
2020-08-21 18:01:59 +03:00
|
|
|
|
2022-06-29 18:33:02 +03:00
|
|
|
initAndLog(c, "storage engine", func(c *cfg) {
|
|
|
|
fatalOnErr(c.cfgObject.cfgLocalStorage.localStorage.Open())
|
2023-03-23 17:59:14 +03:00
|
|
|
fatalOnErr(c.cfgObject.cfgLocalStorage.localStorage.Init(ctx))
|
2022-06-29 18:33:02 +03:00
|
|
|
})
|
|
|
|
|
2022-05-25 19:18:36 +03:00
|
|
|
initAndLog(c, "gRPC", initGRPC)
|
2023-04-05 16:58:32 +03:00
|
|
|
initAndLog(c, "netmap", func(c *cfg) { initNetmapService(ctx, c) })
|
|
|
|
initAndLog(c, "accounting", func(c *cfg) { initAccountingService(ctx, c) })
|
2023-04-05 16:28:09 +03:00
|
|
|
initAndLog(c, "container", func(c *cfg) { initContainerService(ctx, c) })
|
2022-05-25 19:18:36 +03:00
|
|
|
initAndLog(c, "session", initSessionService)
|
2023-03-13 14:37:35 +03:00
|
|
|
initAndLog(c, "notification", func(c *cfg) { initNotifications(ctx, c) })
|
2022-05-25 19:18:36 +03:00
|
|
|
initAndLog(c, "object", initObjectService)
|
2022-04-22 16:30:20 +03:00
|
|
|
initAndLog(c, "tree", initTreeService)
|
2022-05-17 12:09:18 +03:00
|
|
|
initAndLog(c, "control", initControlService)
|
2022-05-25 19:18:36 +03:00
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
initAndLog(c, "morph notifications", func(c *cfg) { listenMorphNotifications(ctx, c) })
|
2022-05-25 19:18:36 +03:00
|
|
|
}
|
2020-10-21 12:26:16 +03:00
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
func runAndLog(ctx context.Context, c *cfg, name string, logSuccess bool, starter func(context.Context, *cfg)) {
|
2022-05-25 19:18:36 +03:00
|
|
|
c.log.Info(fmt.Sprintf("starting %s service...", name))
|
2023-03-23 17:59:14 +03:00
|
|
|
starter(ctx, c)
|
2020-11-30 18:35:37 +03:00
|
|
|
|
2022-05-25 19:18:36 +03:00
|
|
|
if logSuccess {
|
|
|
|
c.log.Info(fmt.Sprintf("%s service started successfully", name))
|
|
|
|
}
|
2020-08-24 12:40:32 +03:00
|
|
|
}
|
|
|
|
|
2022-11-24 14:36:49 +03:00
|
|
|
func stopAndLog(c *cfg, name string, stopper func() error) {
|
|
|
|
c.log.Debug(fmt.Sprintf("shutting down %s service", name))
|
|
|
|
|
|
|
|
err := stopper()
|
|
|
|
if err != nil {
|
|
|
|
c.log.Debug(fmt.Sprintf("could not shutdown %s server", name),
|
|
|
|
zap.String("error", err.Error()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.log.Debug(fmt.Sprintf("%s service has been stopped", name))
|
|
|
|
}
|
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
func bootUp(ctx context.Context, c *cfg) {
|
|
|
|
runAndLog(ctx, c, "NATS", true, connectNats)
|
|
|
|
runAndLog(ctx, c, "gRPC", false, func(_ context.Context, c *cfg) { serveGRPC(c) })
|
|
|
|
runAndLog(ctx, c, "notary", true, makeAndWaitNotaryDeposit)
|
2022-05-25 19:18:36 +03:00
|
|
|
|
2021-09-09 14:57:55 +03:00
|
|
|
bootstrapNode(c)
|
2023-03-23 17:59:14 +03:00
|
|
|
startWorkers(ctx, c)
|
2020-08-24 12:40:32 +03:00
|
|
|
}
|
2020-07-10 17:17:51 +03:00
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
func wait(c *cfg, cancel func()) {
|
2023-04-12 17:35:10 +03:00
|
|
|
c.log.Info(logs.CommonApplicationStarted,
|
2022-07-13 17:45:33 +03:00
|
|
|
zap.String("version", misc.Version))
|
2020-09-25 15:34:17 +03:00
|
|
|
|
2023-03-23 17:59:14 +03:00
|
|
|
<-c.done // graceful shutdown
|
|
|
|
|
|
|
|
cancel()
|
2020-08-22 14:03:45 +03:00
|
|
|
|
2023-04-12 17:35:10 +03:00
|
|
|
c.log.Debug(logs.FrostFSNodeWaitingForAllProcessesToStop)
|
2021-08-04 17:44:37 +03:00
|
|
|
|
2020-08-22 14:03:45 +03:00
|
|
|
c.wg.Wait()
|
2020-07-10 17:17:51 +03:00
|
|
|
}
|
2021-01-18 11:56:14 +03:00
|
|
|
|
|
|
|
func (c *cfg) onShutdown(f func()) {
|
2022-11-24 14:36:49 +03:00
|
|
|
c.closers = append(c.closers, closer{"", f})
|
2021-01-18 11:56:14 +03:00
|
|
|
}
|