talos

Форк
0
144 строки · 3.2 Кб
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
package vm
6

7
import (
8
	"encoding/json"
9
	"errors"
10
	"fmt"
11
	"io"
12
	"net/http"
13
	"net/netip"
14
	"os"
15
	"os/signal"
16
	"syscall"
17

18
	"github.com/siderolabs/talos/pkg/machinery/nethelpers"
19
	"github.com/siderolabs/talos/pkg/provision/internal/inmemhttp"
20
)
21

22
// ReadConfig loads configuration from stdin.
23
func ReadConfig(config interface{}) error {
24
	d := json.NewDecoder(os.Stdin)
25
	if err := d.Decode(config); err != nil {
26
		return fmt.Errorf("error decoding config from stdin: %w", err)
27
	}
28

29
	if d.More() {
30
		return errors.New("extra unexpected input on stdin")
31
	}
32

33
	return os.Stdin.Close()
34
}
35

36
// ConfigureSignals configures signal handling for the process.
37
func ConfigureSignals() chan os.Signal {
38
	signal.Ignore(syscall.SIGHUP)
39

40
	c := make(chan os.Signal, 1)
41
	signal.Notify(c, syscall.SIGTERM, syscall.SIGINT)
42

43
	return c
44
}
45

46
func httpPostWrapper(f func() error) http.Handler {
47
	return http.HandlerFunc(
48
		func(w http.ResponseWriter, req *http.Request) {
49
			if req.Body != nil {
50
				_, _ = io.Copy(io.Discard, req.Body) //nolint:errcheck
51
				req.Body.Close()                     //nolint:errcheck
52
			}
53

54
			if req.Method != http.MethodPost {
55
				w.WriteHeader(http.StatusNotImplemented)
56

57
				return
58
			}
59

60
			err := f()
61
			if err != nil {
62
				w.WriteHeader(http.StatusInternalServerError)
63

64
				fmt.Fprint(w, err.Error())
65

66
				return
67
			}
68

69
			w.WriteHeader(http.StatusOK)
70
		},
71
	)
72
}
73

74
func httpGetWrapper(f func(w io.Writer)) http.Handler {
75
	return http.HandlerFunc(
76
		func(w http.ResponseWriter, req *http.Request) {
77
			if req.Body != nil {
78
				_, _ = io.Copy(io.Discard, req.Body) //nolint:errcheck
79
				req.Body.Close()                     //nolint:errcheck
80
			}
81

82
			switch req.Method {
83
			case http.MethodHead:
84
				w.Header().Add("Content-Type", "application/json")
85
				w.WriteHeader(http.StatusOK)
86
			case http.MethodGet:
87
				w.Header().Add("Content-Type", "application/json")
88
				w.WriteHeader(http.StatusOK)
89

90
				f(w)
91
			default:
92
				w.WriteHeader(http.StatusNotImplemented)
93
			}
94
		},
95
	)
96
}
97

98
// NewHTTPServer creates new inmemhttp.Server and mounts config file into it.
99
func NewHTTPServer(gatewayAddr netip.Addr, port int, config []byte, controller Controller) (inmemhttp.Server, error) {
100
	httpServer, err := inmemhttp.NewServer(nethelpers.JoinHostPort(gatewayAddr.String(), port))
101
	if err != nil {
102
		return nil, fmt.Errorf("error launching in-memory HTTP server: %w", err)
103
	}
104

105
	if err = httpServer.AddFile("config.yaml", config); err != nil {
106
		return nil, err
107
	}
108

109
	if controller != nil {
110
		for _, method := range []struct {
111
			pattern string
112
			f       func() error
113
		}{
114
			{
115
				pattern: "/poweron",
116
				f:       controller.PowerOn,
117
			},
118
			{
119
				pattern: "/poweroff",
120
				f:       controller.PowerOff,
121
			},
122
			{
123
				pattern: "/reboot",
124
				f:       controller.Reboot,
125
			},
126
			{
127
				pattern: "/pxeboot",
128
				f:       controller.PXEBootOnce,
129
			},
130
		} {
131
			httpServer.AddHandler(method.pattern, httpPostWrapper(method.f))
132
		}
133

134
		httpServer.AddHandler(
135
			"/status", httpGetWrapper(
136
				func(w io.Writer) {
137
					json.NewEncoder(w).Encode(controller.Status()) //nolint:errcheck
138
				},
139
			),
140
		)
141
	}
142

143
	return httpServer, nil
144
}
145

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.