blob: d1e2f876a0fde63ba05dca15d203e7d6c710866a [file] [log] [blame]
Lorenz Brunae0d90d2019-09-05 17:53:56 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package main
18
19import (
Serge Bazanskicdb8c782020-02-17 12:34:02 +010020 "context"
Lorenz Brundd8c80e2019-10-07 16:19:49 +020021 "fmt"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020022 "os"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020023 "os/signal"
Lorenz Brunf95909d2019-09-11 19:48:26 +020024 "runtime/debug"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020025
Serge Bazanskib1b742f2020-03-24 13:58:19 +010026 "git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
Lorenz Brunaa6b7342019-12-12 02:55:02 +010027 "git.monogon.dev/source/nexantic.git/core/internal/network"
28 "git.monogon.dev/source/nexantic.git/core/internal/node"
Serge Bazanskicdb8c782020-02-17 12:34:02 +010029 "git.monogon.dev/source/nexantic.git/core/internal/storage"
Lorenz Brunaa6b7342019-12-12 02:55:02 +010030 "git.monogon.dev/source/nexantic.git/core/pkg/tpm"
31
Lorenz Brunae0d90d2019-09-05 17:53:56 +020032 "go.uber.org/zap"
33 "golang.org/x/sys/unix"
34)
35
Leopold Schabela4516f92019-12-04 20:27:05 +000036const (
37 apiPort = 7833
38 consensusPort = 7834
39)
40
Lorenz Brunae0d90d2019-09-05 17:53:56 +020041func main() {
Lorenz Brunf95909d2019-09-11 19:48:26 +020042 defer func() {
43 if r := recover(); r != nil {
44 fmt.Println("Init panicked:", r)
45 debug.PrintStack()
46 }
47 unix.Sync()
Leopold Schabel68c58752019-11-14 21:00:59 +010048 // TODO(lorenz): Switch this to Reboot when init panics are less likely
49 // Best effort, nothing we can do if this fails except printing the error to the console.
50 if err := unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF); err != nil {
51 panic(fmt.Sprintf("failed to halt node: %v\n", err))
52 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020053 }()
Lorenz Brunae0d90d2019-09-05 17:53:56 +020054 logger, err := zap.NewDevelopment()
55 if err != nil {
56 panic(err)
57 }
Serge Bazanski581b0bd2020-03-12 13:36:43 +010058
59 // Remount onto a tmpfs and re-exec if needed. Otherwise, keep running.
60 err = switchRoot(logger)
61 if err != nil {
62 panic(fmt.Errorf("could not remount root: %w", err))
63 }
64
Lorenz Brunae0d90d2019-09-05 17:53:56 +020065 logger.Info("Starting Smalltown Init")
66
Lorenz Brunae0d90d2019-09-05 17:53:56 +020067 signalChannel := make(chan os.Signal, 2)
68 signal.Notify(signalChannel)
69
Lorenz Brunae0d90d2019-09-05 17:53:56 +020070 if err := tpm.Initialize(logger.With(zap.String("component", "tpm"))); err != nil {
71 logger.Panic("Failed to initialize TPM 2.0", zap.Error(err))
72 }
73
Serge Bazanskicdb8c782020-02-17 12:34:02 +010074 storageManager, err := storage.Initialize(logger.With(zap.String("component", "storage")))
75 if err != nil {
Serge Bazanski581b0bd2020-03-12 13:36:43 +010076 panic(fmt.Errorf("could not initialize storage: %w", err))
Serge Bazanskicdb8c782020-02-17 12:34:02 +010077 }
78
Serge Bazanskib1b742f2020-03-24 13:58:19 +010079 networkSvc := network.New(network.Config{})
Lorenz Brunf95909d2019-09-11 19:48:26 +020080 if err != nil {
81 panic(err)
82 }
Leopold Schabel68c58752019-11-14 21:00:59 +010083
Serge Bazanskib1b742f2020-03-24 13:58:19 +010084 supervisor.New(context.Background(), logger, func(ctx context.Context) error {
85 if err := supervisor.Run(ctx, "network", networkSvc.Run); err != nil {
86 return err
87 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020088
Serge Bazanskib1b742f2020-03-24 13:58:19 +010089 // TODO(q3k): convert node code to supervisor
90 nodeInstance, err := node.NewSmalltownNode(logger, networkSvc, storageManager)
91 if err != nil {
92 panic(err)
93 }
Lorenz Brunae0d90d2019-09-05 17:53:56 +020094
Serge Bazanskib1b742f2020-03-24 13:58:19 +010095 err = nodeInstance.Start(ctx)
96 if err != nil {
97 panic(err)
98 }
Lorenz Brunae0d90d2019-09-05 17:53:56 +020099
Serge Bazanskib1b742f2020-03-24 13:58:19 +0100100 supervisor.Signal(ctx, supervisor.SignalHealthy)
101
102 // We're PID1, so orphaned processes get reparented to us to clean up
103 for {
104 select {
105 case <-ctx.Done():
106 return ctx.Err()
107 case sig := <-signalChannel:
108 switch sig {
109 case unix.SIGCHLD:
110 var status unix.WaitStatus
111 var rusage unix.Rusage
112 for {
113 res, err := unix.Wait4(-1, &status, unix.WNOHANG, &rusage)
114 if err != nil && err != unix.ECHILD {
115 logger.Error("Failed to wait on orphaned child", zap.Error(err))
116 break
117 }
118 if res <= 0 {
119 break
120 }
121 }
122 // TODO(lorenz): We can probably get more than just SIGCHLD as init, but I can't think
123 // of any others right now, just log them in case we hit any of them.
124 default:
125 logger.Warn("Got unexpected signal", zap.String("signal", sig.String()))
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200126 }
127 }
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200128 }
Serge Bazanskib1b742f2020-03-24 13:58:19 +0100129 })
130 select {}
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200131}