20
"github.com/hashicorp/go-cleanhttp"
21
"github.com/siderolabs/go-cmd/pkg/cmd/proc"
22
"github.com/siderolabs/go-cmd/pkg/cmd/proc/reaper"
23
debug "github.com/siderolabs/go-debug"
24
"github.com/siderolabs/go-procfs/procfs"
25
"golang.org/x/sys/unix"
27
"github.com/aenix-io/talm/internal/app/apid"
28
"github.com/aenix-io/talm/internal/app/dashboard"
29
"github.com/aenix-io/talm/internal/app/machined/pkg/runtime"
30
"github.com/aenix-io/talm/internal/app/machined/pkg/runtime/emergency"
31
v1alpha1runtime "github.com/aenix-io/talm/internal/app/machined/pkg/runtime/v1alpha1"
32
"github.com/aenix-io/talm/internal/app/machined/pkg/system"
33
"github.com/aenix-io/talm/internal/app/machined/pkg/system/services"
34
"github.com/aenix-io/talm/internal/app/maintenance"
35
"github.com/aenix-io/talm/internal/app/poweroff"
36
"github.com/aenix-io/talm/internal/app/trustd"
37
"github.com/aenix-io/talm/internal/app/wrapperd"
38
"github.com/aenix-io/talm/internal/pkg/mount"
39
"github.com/siderolabs/talos/pkg/httpdefaults"
40
"github.com/siderolabs/talos/pkg/machinery/api/common"
41
"github.com/siderolabs/talos/pkg/machinery/api/machine"
42
"github.com/siderolabs/talos/pkg/machinery/constants"
43
"github.com/siderolabs/talos/pkg/startup"
48
http.DefaultClient.Transport = httpdefaults.PatchTransport(cleanhttp.DefaultPooledTransport())
51
func recovery(ctx context.Context) {
52
if r := recover(); r != nil {
69
func syncNonVolatileStorageBuffers() {
70
syncdone := make(chan struct{})
78
log.Printf("waiting for sync...")
80
for i := 29; i >= 0; i-- {
83
log.Printf("sync done")
86
case <-time.After(time.Second):
90
log.Printf("waiting %d more seconds for sync to finish", i)
94
log.Printf("sync hasn't completed in time, aborting...")
98
func handle(ctx context.Context, err error) {
99
rebootCmd := int(emergency.RebootCmd.Load())
101
var rebootErr runtime.RebootError
103
if errors.As(err, &rebootErr) {
105
rebootCmd = rebootErr.Cmd
112
revertBootloader(ctx)
114
if p := procfs.ProcCmdline().Get(constants.KernelParamPanic).First(); p != nil {
116
log.Printf("panic=0 kernel flag found, sleeping forever")
123
if rebootCmd == unix.LINUX_REBOOT_CMD_RESTART {
124
for i := 10; i >= 0; i-- {
125
log.Printf("rebooting in %d seconds\n", i)
126
time.Sleep(1 * time.Second)
130
if err = proc.KillAll(); err != nil {
131
log.Printf("error killing all procs: %s", err)
134
if err = mount.UnmountAll(); err != nil {
135
log.Printf("error unmounting: %s", err)
138
syncNonVolatileStorageBuffers()
141
exitSignal := make(chan os.Signal, 1)
143
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
146
} else if unix.Reboot(rebootCmd) == nil {
152
func runDebugServer(ctx context.Context) {
153
const debugAddr = ":9982"
155
debugLogFunc := func(msg string) {
159
if err := debug.ListenAndServe(ctx, debugAddr, debugLogFunc); err != nil {
160
log.Fatalf("failed to start debug server: %s", err)
166
errCh := make(chan error)
169
startup.LimitMaxProcs(constants.MachinedMaxProcs)
172
if err := os.Setenv("PATH", constants.PATH); err != nil {
173
return errors.New("error setting PATH")
177
c, err := v1alpha1runtime.NewController()
182
ctx, cancel := context.WithCancel(context.Background())
185
drainer := runtime.NewDrainer()
187
drainCtx, drainCtxCancel := context.WithTimeout(context.Background(), time.Second*10)
188
defer drainCtxCancel()
190
if e := drainer.Drain(drainCtx); e != nil {
191
log.Printf("WARNING: failed to drain controllers: %s", e)
195
go runDebugServer(ctx)
198
defer system.Services(c.Runtime()).Shutdown(ctx)
202
if e := c.ListenForEvents(ctx); e != nil {
203
log.Printf("WARNING: signals and ACPI events will be ignored: %s", e)
209
if e := c.V1Alpha2().Run(ctx, drainer); e != nil {
210
ctrlErr := fmt.Errorf("fatal controller runtime error: %s", e)
212
log.Printf("controller runtime goroutine error: %s", ctrlErr)
217
log.Printf("controller runtime finished")
221
maintenance.InjectController(c)
224
system.Services(c.Runtime()).Load(
225
&services.Machined{Controller: c},
228
initializeCanceled := false
231
if err = c.Run(ctx, runtime.SequenceInitialize, nil); err != nil {
232
if errors.Is(err, context.Canceled) {
233
initializeCanceled = true
240
if !initializeCanceled {
242
if err = c.Run(ctx, runtime.SequenceInstall, nil); err != nil {
247
system.Services(c.Runtime()).LoadAndStart(
252
if err = c.Run(ctx, runtime.SequenceBoot, nil); err != nil && !errors.Is(err, context.Canceled) {
259
_ = c.Runtime().Events().Watch(
260
func(events <-chan runtime.EventInfo) {
262
for event := range events {
263
switch msg := event.Payload.(type) {
264
case *machine.SequenceEvent:
265
if msg.Error != nil {
266
if msg.Error.GetCode() == common.Code_LOCKED ||
267
msg.Error.GetCode() == common.Code_CANCELED {
273
"fatal sequencer error in %q sequence: %v",
275
msg.GetError().String(),
278
case *machine.RestartEvent:
279
errCh <- runtime.RebootError{Cmd: int(msg.Cmd)}
290
ctx, cancel := context.WithCancel(context.Background())
293
switch filepath.Base(os.Args[0]) {
303
case "poweroff", "shutdown":
304
poweroff.Main(os.Args)
323
defer reaper.Shutdown()