blob: f4ff871598ed3df69fab36a0c14a19c7822d458f [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
Lorenz Brunaa6b7342019-12-12 02:55:02 +010026 "git.monogon.dev/source/nexantic.git/core/internal/network"
27 "git.monogon.dev/source/nexantic.git/core/internal/node"
Serge Bazanskicdb8c782020-02-17 12:34:02 +010028 "git.monogon.dev/source/nexantic.git/core/internal/storage"
Lorenz Brunaa6b7342019-12-12 02:55:02 +010029 "git.monogon.dev/source/nexantic.git/core/pkg/tpm"
30
Lorenz Brunae0d90d2019-09-05 17:53:56 +020031 "go.uber.org/zap"
32 "golang.org/x/sys/unix"
33)
34
Leopold Schabela4516f92019-12-04 20:27:05 +000035const (
36 apiPort = 7833
37 consensusPort = 7834
38)
39
Lorenz Brunae0d90d2019-09-05 17:53:56 +020040func main() {
Serge Bazanskicdb8c782020-02-17 12:34:02 +010041 ctx := context.Background()
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
Lorenz Brunf95909d2019-09-11 19:48:26 +020079 networkSvc, err := network.NewNetworkService(network.Config{}, logger.With(zap.String("component", "network")))
80 if err != nil {
81 panic(err)
82 }
Leopold Schabel68c58752019-11-14 21:00:59 +010083
84 if err := networkSvc.Start(); err != nil {
85 logger.Panic("Failed to start network service", zap.Error(err))
86 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020087
Serge Bazanskicdb8c782020-02-17 12:34:02 +010088 nodeInstance, err := node.NewSmalltownNode(logger, networkSvc, storageManager)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020089 if err != nil {
90 panic(err)
91 }
92
Serge Bazanskicdb8c782020-02-17 12:34:02 +010093 err = nodeInstance.Start(ctx)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020094 if err != nil {
95 panic(err)
96 }
97
98 // We're PID1, so orphaned processes get reparented to us to clean up
99 for {
100 sig := <-signalChannel
101 switch sig {
102 case unix.SIGCHLD:
103 var status unix.WaitStatus
104 var rusage unix.Rusage
105 for {
Lorenz Brunf95909d2019-09-11 19:48:26 +0200106 res, err := unix.Wait4(-1, &status, unix.WNOHANG, &rusage)
107 if err != nil && err != unix.ECHILD {
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200108 logger.Error("Failed to wait on orphaned child", zap.Error(err))
109 break
110 }
111 if res <= 0 {
112 break
113 }
114 }
115 // TODO(lorenz): We can probably get more than just SIGCHLD as init, but I can't think
116 // of any others right now, just log them in case we hit any of them.
117 default:
118 logger.Warn("Got unexpected signal", zap.String("signal", sig.String()))
119 }
120 }
121}