blob: 82ba033b456f21522a99342ef7c7f49819609503 [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 }
58 logger.Info("Starting Smalltown Init")
59
60 // Set up bare minimum mounts
61 if err := os.Mkdir("/sys", 0755); err != nil {
62 panic(err)
63 }
64 if err := unix.Mount("sysfs", "/sys", "sysfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
65 panic(err)
66 }
67
68 if err := os.Mkdir("/proc", 0755); err != nil {
69 panic(err)
70 }
71 if err := unix.Mount("procfs", "/proc", "proc", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
72 panic(err)
73 }
74
75 signalChannel := make(chan os.Signal, 2)
76 signal.Notify(signalChannel)
77
Lorenz Brunae0d90d2019-09-05 17:53:56 +020078 if err := tpm.Initialize(logger.With(zap.String("component", "tpm"))); err != nil {
79 logger.Panic("Failed to initialize TPM 2.0", zap.Error(err))
80 }
81
Serge Bazanskicdb8c782020-02-17 12:34:02 +010082 storageManager, err := storage.Initialize(logger.With(zap.String("component", "storage")))
83 if err != nil {
84 panic(err)
85 }
86
Lorenz Brunf95909d2019-09-11 19:48:26 +020087 networkSvc, err := network.NewNetworkService(network.Config{}, logger.With(zap.String("component", "network")))
88 if err != nil {
89 panic(err)
90 }
Leopold Schabel68c58752019-11-14 21:00:59 +010091
92 if err := networkSvc.Start(); err != nil {
93 logger.Panic("Failed to start network service", zap.Error(err))
94 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020095
Serge Bazanskicdb8c782020-02-17 12:34:02 +010096 nodeInstance, err := node.NewSmalltownNode(logger, networkSvc, storageManager)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020097 if err != nil {
98 panic(err)
99 }
100
Serge Bazanskicdb8c782020-02-17 12:34:02 +0100101 err = nodeInstance.Start(ctx)
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200102 if err != nil {
103 panic(err)
104 }
105
106 // We're PID1, so orphaned processes get reparented to us to clean up
107 for {
108 sig := <-signalChannel
109 switch sig {
110 case unix.SIGCHLD:
111 var status unix.WaitStatus
112 var rusage unix.Rusage
113 for {
Lorenz Brunf95909d2019-09-11 19:48:26 +0200114 res, err := unix.Wait4(-1, &status, unix.WNOHANG, &rusage)
115 if err != nil && err != unix.ECHILD {
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200116 logger.Error("Failed to wait on orphaned child", zap.Error(err))
117 break
118 }
119 if res <= 0 {
120 break
121 }
122 }
123 // TODO(lorenz): We can probably get more than just SIGCHLD as init, but I can't think
124 // of any others right now, just log them in case we hit any of them.
125 default:
126 logger.Warn("Got unexpected signal", zap.String("signal", sig.String()))
127 }
128 }
129}