blob: 76a5cf2b0edde0e4b2d31722420fda357df72dc3 [file] [log] [blame]
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +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 node
18
19import (
20 "flag"
21 "git.monogon.dev/source/nexantic.git/core/internal/api"
22 "git.monogon.dev/source/nexantic.git/core/internal/common"
23 "git.monogon.dev/source/nexantic.git/core/internal/consensus"
24 "git.monogon.dev/source/nexantic.git/core/internal/storage"
Leopold Schabel68c58752019-11-14 21:00:59 +010025 "os"
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020026
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020027 "github.com/google/uuid"
28 "go.uber.org/zap"
29)
30
31type (
32 SmalltownNode struct {
33 Api *api.Server
34 Consensus *consensus.Service
35 Storage *storage.Manager
36
37 logger *zap.Logger
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020038 state common.SmalltownState
39 joinToken string
Leopold Schabel68c58752019-11-14 21:00:59 +010040 hostname string
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020041 }
42)
43
44func NewSmalltownNode(logger *zap.Logger, apiPort, consensusPort uint16) (*SmalltownNode, error) {
45 flag.Parse()
46 logger.Info("Creating Smalltown node")
47
Leopold Schabel68c58752019-11-14 21:00:59 +010048 hostname, err := os.Hostname()
49 if err != nil {
50 panic(err)
51 }
52
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020053 storageManager, err := storage.Initialize(logger.With(zap.String("component", "storage")))
54 if err != nil {
55 logger.Error("Failed to initialize storage manager", zap.Error(err))
56 return nil, err
57 }
58
59 consensusService, err := consensus.NewConsensusService(consensus.Config{
Leopold Schabel68c58752019-11-14 21:00:59 +010060 Name: hostname,
61 ListenPort: consensusPort,
62 ListenHost: "0.0.0.0",
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020063 }, logger.With(zap.String("module", "consensus")))
64 if err != nil {
65 return nil, err
66 }
67
68 s := &SmalltownNode{
69 Consensus: consensusService,
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020070 Storage: storageManager,
Leopold Schabel68c58752019-11-14 21:00:59 +010071 logger: logger,
72 hostname: hostname,
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020073 }
74
75 apiService, err := api.NewApiServer(&api.Config{
76 Port: apiPort,
77 }, logger.With(zap.String("module", "api")), s, s.Consensus)
78 if err != nil {
79 return nil, err
80 }
81
82 s.Api = apiService
83
84 logger.Info("Created SmalltownNode")
85
86 return s, nil
87}
88
89func (s *SmalltownNode) Start() error {
90 s.logger.Info("Starting Smalltown node")
91
92 if s.Consensus.IsProvisioned() {
93 s.logger.Info("Consensus is provisioned")
94 err := s.startFull()
95 if err != nil {
96 return err
97 }
98 } else {
Leopold Schabel68c58752019-11-14 21:00:59 +010099 s.logger.Info("Consensus is not provisioned, starting provisioning...")
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +0200100 err := s.startForSetup()
101 if err != nil {
102 return err
103 }
104 }
105
106 return nil
107}
108
109func (s *SmalltownNode) startForSetup() error {
110 s.logger.Info("Initializing subsystems for setup mode")
111 s.state = common.StateSetupMode
112 s.joinToken = uuid.New().String()
113
114 err := s.Api.Start()
115 if err != nil {
116 s.logger.Error("Failed to start the API service", zap.Error(err))
117 return err
118 }
119
120 return nil
121}
122
123func (s *SmalltownNode) startFull() error {
124 s.logger.Info("Initializing subsystems for production")
125 s.state = common.StateConfigured
126
127 err := s.SetupBackend()
128 if err != nil {
129 return err
130 }
131
132 err = s.Consensus.Start()
133 if err != nil {
134 return err
135 }
136
137 err = s.Api.Start()
138 if err != nil {
139 s.logger.Error("Failed to start the API service", zap.Error(err))
140 return err
141 }
142
143 return nil
144}
145
146func (s *SmalltownNode) Stop() error {
147 s.logger.Info("Stopping Smalltown node")
148 return nil
149}
150
151func (s *SmalltownNode) SetupBackend() error {
152 s.logger.Debug("Creating trust backend")
153
154 return nil
155}