talos
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
5package qemu6
7import (8"sync"9
10"github.com/siderolabs/talos/pkg/provision/providers/vm"11)
12
13// PowerState is current VM power state.
14type PowerState string15
16// Virtual machine power state.
17const (18PoweredOn PowerState = "on"19PoweredOff PowerState = "off"20)
21
22// VMCommand is a translated VM command.
23type VMCommand string24
25// Virtual machine commands.
26const (27VMCommandStart VMCommand = "start"28VMCommandStop VMCommand = "stop"29)
30
31// Controller supports IPMI-like machine control.
32type Controller struct {33mu sync.Mutex34state PowerState
35
36forcePXEBoot bool37
38commandsCh chan VMCommand39}
40
41// NewController initializes controller in "powered on" state.
42func NewController() *Controller {43return &Controller{44state: PoweredOn,45commandsCh: make(chan VMCommand),46}47}
48
49// PowerOn implements vm.Controller interface.
50func (c *Controller) PowerOn() error {51c.mu.Lock()52
53if c.state == PoweredOn {54c.mu.Unlock()55
56return nil57}58
59c.state = PoweredOn60c.mu.Unlock()61
62c.commandsCh <- VMCommandStart63
64return nil65}
66
67// PowerOff implements vm.Controller interface.
68func (c *Controller) PowerOff() error {69c.mu.Lock()70
71if c.state == PoweredOff {72c.mu.Unlock()73
74return nil75}76
77c.state = PoweredOff78c.mu.Unlock()79
80c.commandsCh <- VMCommandStop81
82return nil83}
84
85// Reboot implements vm.Controller interface.
86func (c *Controller) Reboot() error {87c.mu.Lock()88
89if c.state == PoweredOff {90c.mu.Unlock()91
92return nil93}94
95c.mu.Unlock()96
97c.commandsCh <- VMCommandStop98
99return nil100}
101
102// PXEBootOnce implements vm.Controller interface.
103func (c *Controller) PXEBootOnce() error {104c.mu.Lock()105defer c.mu.Unlock()106
107c.forcePXEBoot = true108
109return nil110}
111
112// Status implements vm.Controller interface.
113func (c *Controller) Status() vm.Status {114return vm.Status{115PoweredOn: c.PowerState() == PoweredOn,116}117}
118
119// PowerState returns current power state.
120func (c *Controller) PowerState() PowerState {121c.mu.Lock()122defer c.mu.Unlock()123
124return c.state125}
126
127// ForcePXEBoot returns whether next boot should be PXE boot.
128func (c *Controller) ForcePXEBoot() bool {129c.mu.Lock()130defer c.mu.Unlock()131
132if c.forcePXEBoot {133c.forcePXEBoot = false134
135return true136}137
138return false139}
140
141// CommandsCh returns channel with commands.
142func (c *Controller) CommandsCh() <-chan VMCommand {143return c.commandsCh144}
145