blob: 2219a35814b80a1990020c2de547257783fecacc [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 (
Lorenz Brundd8c80e2019-10-07 16:19:49 +020020 "fmt"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020021 "os"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020022 "os/signal"
Lorenz Brunf95909d2019-09-11 19:48:26 +020023 "runtime/debug"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020024
Lorenz Brunaa6b7342019-12-12 02:55:02 +010025 "git.monogon.dev/source/nexantic.git/core/internal/network"
26 "git.monogon.dev/source/nexantic.git/core/internal/node"
27 "git.monogon.dev/source/nexantic.git/core/pkg/tpm"
28
Lorenz Brunae0d90d2019-09-05 17:53:56 +020029 "go.uber.org/zap"
30 "golang.org/x/sys/unix"
31)
32
Leopold Schabela4516f92019-12-04 20:27:05 +000033const (
34 apiPort = 7833
35 consensusPort = 7834
36)
37
Lorenz Brunae0d90d2019-09-05 17:53:56 +020038func main() {
Lorenz Brunf95909d2019-09-11 19:48:26 +020039 defer func() {
40 if r := recover(); r != nil {
41 fmt.Println("Init panicked:", r)
42 debug.PrintStack()
43 }
44 unix.Sync()
Leopold Schabel68c58752019-11-14 21:00:59 +010045 // TODO(lorenz): Switch this to Reboot when init panics are less likely
46 // Best effort, nothing we can do if this fails except printing the error to the console.
47 if err := unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF); err != nil {
48 panic(fmt.Sprintf("failed to halt node: %v\n", err))
49 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020050 }()
Lorenz Brunae0d90d2019-09-05 17:53:56 +020051 logger, err := zap.NewDevelopment()
52 if err != nil {
53 panic(err)
54 }
55 logger.Info("Starting Smalltown Init")
56
57 // Set up bare minimum mounts
58 if err := os.Mkdir("/sys", 0755); err != nil {
59 panic(err)
60 }
61 if err := unix.Mount("sysfs", "/sys", "sysfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
62 panic(err)
63 }
64
65 if err := os.Mkdir("/proc", 0755); err != nil {
66 panic(err)
67 }
68 if err := unix.Mount("procfs", "/proc", "proc", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
69 panic(err)
70 }
71
72 signalChannel := make(chan os.Signal, 2)
73 signal.Notify(signalChannel)
74
Lorenz Brunae0d90d2019-09-05 17:53:56 +020075 if err := tpm.Initialize(logger.With(zap.String("component", "tpm"))); err != nil {
76 logger.Panic("Failed to initialize TPM 2.0", zap.Error(err))
77 }
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
Lorenz Brunaa6b7342019-12-12 02:55:02 +010088 nodeInstance, err := node.NewSmalltownNode(logger)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020089 if err != nil {
90 panic(err)
91 }
92
Lorenz Brundd8c80e2019-10-07 16:19:49 +020093 err = nodeInstance.Start()
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}