Skip to content

Commit

Permalink
Podman 5 machine config file - Step 1
Browse files Browse the repository at this point in the history
The following PR is the very first step in what will a series of steps
to apply a "common" machine configuration file to all providers.
Function names, method names, struct names, and field names are all up
for debate.  The purpose of this PR is to offer a glimpse at the
direction we intend to take.

This PR also contains temporary structs (i.e. aThing) that are not
exported.  These are merely placeholders.

The configuration work in this PR is also unused of yet.  But the code
is compiled.  Once merged, we can begin the next step of development.

[NO NEW TESTS NEEDED]

Signed-off-by: Brent Baude <[email protected]>
  • Loading branch information
baude committed Dec 11, 2023
1 parent 9877dc4 commit e5a4f00
Show file tree
Hide file tree
Showing 30 changed files with 721 additions and 528 deletions.
3 changes: 2 additions & 1 deletion cmd/podman/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/provider"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -184,7 +185,7 @@ func composeDockerHost() (string, error) {
if err != nil {
return "", fmt.Errorf("inspecting machine: %w", err)
}
if info.State != machine.Running {
if info.State != define.Running {
return "", fmt.Errorf("machine %s is not running but in state %s", item.Name, info.State)
}
if machineProvider.VMType() == machine.WSLVirt {
Expand Down
11 changes: 6 additions & 5 deletions pkg/machine/applehv/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/compression"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
vfConfig "github.com/crc-org/vfkit/pkg/config"
"github.com/docker/go-units"
"golang.org/x/sys/unix"
Expand Down Expand Up @@ -76,10 +77,10 @@ func (v AppleHVVirtualization) List(opts machine.ListOptions) ([]*machine.ListRe
}

for _, mm := range mms {
vmState, err := mm.Vfkit.state()
vmState, err := mm.Vfkit.State()
if err != nil {
if errors.Is(err, unix.ECONNREFUSED) {
vmState = machine.Stopped
vmState = define.Stopped
} else {
return nil, err
}
Expand All @@ -89,8 +90,8 @@ func (v AppleHVVirtualization) List(opts machine.ListOptions) ([]*machine.ListRe
Name: mm.Name,
CreatedAt: mm.Created,
LastUp: mm.LastUp,
Running: vmState == machine.Running,
Starting: vmState == machine.Starting,
Running: vmState == define.Running,
Starting: vmState == define.Starting,
Stream: mm.ImageStream,
VMType: machine.AppleHvVirt.String(),
CPUs: mm.CPUs,
Expand Down Expand Up @@ -140,7 +141,7 @@ func (v AppleHVVirtualization) NewMachine(opts machine.InitOptions) (machine.VM,
// Set creation time
m.Created = time.Now()

m.ResourceConfig = machine.ResourceConfig{
m.ResourceConfig = vmconfigs.ResourceConfig{
CPUs: opts.CPUS,
DiskSize: opts.DiskSize,
// Diskpath will be needed
Expand Down
55 changes: 25 additions & 30 deletions pkg/machine/applehv/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import (
"github.com/containers/common/pkg/config"
gvproxy "github.com/containers/gvisor-tap-vsock/pkg/types"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/applehv/vfkit"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/sockets"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/containers/podman/v4/pkg/strongunits"
"github.com/containers/podman/v4/pkg/util"
"github.com/containers/podman/v4/utils"
Expand All @@ -43,14 +46,6 @@ const (
apiUpTimeout = 20 * time.Second
)

// VfkitHelper describes the use of vfkit: cmdline and endpoint
type VfkitHelper struct {
LogLevel logrus.Level
Endpoint string
VfkitBinaryPath *define.VMFile
VirtualMachine *vfConfig.VirtualMachine
}

// appleHVReadyUnit is a unit file that sets up the virtual serial device
// where when the VM is done configuring, it will send an ack
// so a listening host knows it can begin interacting with it
Expand All @@ -71,27 +66,27 @@ type MacMachine struct {
// ConfigPath is the fully qualified path to the configuration file
ConfigPath define.VMFile
// HostUser contains info about host user
machine.HostUser
vmconfigs.HostUser
// ImageConfig describes the bootable image
machine.ImageConfig
// Mounts is the list of remote filesystems to mount
Mounts []machine.Mount
Mounts []vmconfigs.Mount
// Name of VM
Name string
// ReadySocket tells host when vm is booted
ReadySocket define.VMFile
// ResourceConfig is physical attrs of the VM
machine.ResourceConfig
vmconfigs.ResourceConfig
// SSHConfig for accessing the remote vm
machine.SSHConfig
vmconfigs.SSHConfig
// Starting tells us whether the machine is running or if we have just dialed it to start it
Starting bool
// Created contains the original created time instead of querying the file mod time
Created time.Time
// LastUp contains the last recorded uptime
LastUp time.Time
// The VFKit endpoint where we can interact with the VM
Vfkit VfkitHelper
Vfkit vfkit.VfkitHelper
LogPath define.VMFile
GvProxyPid define.VMFile
GvProxySock define.VMFile
Expand All @@ -108,7 +103,7 @@ func (m *MacMachine) setGVProxyInfo(runtimeDir string) error {
}
m.GvProxyPid = *gvProxyPid

return machine.SetSocket(&m.GvProxySock, filepath.Join(runtimeDir, "gvproxy.sock"), nil)
return sockets.SetSocket(&m.GvProxySock, filepath.Join(runtimeDir, "gvproxy.sock"), nil)
}

// setVfkitInfo stores the default devices, sets the vfkit endpoint, and
Expand Down Expand Up @@ -138,7 +133,7 @@ func (m *MacMachine) setVfkitInfo(cfg *config.Config, readySocket define.VMFile)
// addMountsToVM converts the volumes passed through the CLI to virtio-fs mounts
// and adds them to the machine
func (m *MacMachine) addMountsToVM(opts machine.InitOptions, virtiofsMnts *[]machine.VirtIoFs) error {
var mounts []machine.Mount
var mounts []vmconfigs.Mount
for _, volume := range opts.Volumes {
source, target, _, readOnly, err := machine.ParseVolumeFromPath(volume)
if err != nil {
Expand Down Expand Up @@ -202,7 +197,7 @@ func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
return false, err
}

if err := machine.SetSocket(&m.ReadySocket, machine.ReadySocketPath(runtimeDir, m.Name), nil); err != nil {
if err := sockets.SetSocket(&m.ReadySocket, sockets.ReadySocketPath(runtimeDir, m.Name), nil); err != nil {
return false, err
}

Expand Down Expand Up @@ -305,7 +300,7 @@ func (m *MacMachine) removeSystemConnections() error {
}

func (m *MacMachine) Inspect() (*machine.InspectInfo, error) {
vmState, err := m.Vfkit.state()
vmState, err := m.Vfkit.State()
if err != nil {
return nil, err
}
Expand All @@ -329,7 +324,7 @@ func (m *MacMachine) Inspect() (*machine.InspectInfo, error) {
},
LastUp: m.LastUp,
Name: m.Name,
Resources: machine.ResourceConfig{
Resources: vmconfigs.ResourceConfig{
CPUs: m.CPUs,
DiskSize: m.DiskSize,
Memory: m.Memory,
Expand Down Expand Up @@ -367,16 +362,16 @@ func (m *MacMachine) Remove(name string, opts machine.RemoveOptions) (string, fu
m.lock.Lock()
defer m.lock.Unlock()

vmState, err := m.Vfkit.state()
vmState, err := m.Vfkit.State()
if err != nil {
return "", nil, err
}

if vmState == machine.Running {
if vmState == define.Running {
if !opts.Force {
return "", nil, &machine.ErrVMRunningCannotDestroyed{Name: m.Name}
}
if err := m.Vfkit.stop(true, true); err != nil {
if err := m.Vfkit.Stop(true, true); err != nil {
return "", nil, err
}
defer func() {
Expand Down Expand Up @@ -430,7 +425,7 @@ func (m *MacMachine) Set(name string, opts machine.SetOptions) ([]error, error)
if err != nil {
return nil, err
}
if vmState != machine.Stopped {
if vmState != define.Stopped {
return nil, machine.ErrWrongState
}
if cpus := opts.CPUs; cpus != nil {
Expand Down Expand Up @@ -473,7 +468,7 @@ func (m *MacMachine) SSH(name string, opts machine.SSHOptions) error {
if err != nil {
return err
}
if st != machine.Running {
if st != define.Running {
return fmt.Errorf("vm %q is not running", m.Name)
}
username := opts.Username
Expand Down Expand Up @@ -561,7 +556,7 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
return err
}

if st == machine.Running {
if st == define.Running {
return machine.ErrVMAlreadyRunning
}

Expand Down Expand Up @@ -664,7 +659,7 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {

logrus.Debug("waiting for ready notification")
readyChan := make(chan error)
go machine.ListenAndWaitOnSocket(readyChan, readyListen)
go sockets.ListenAndWaitOnSocket(readyChan, readyListen)

if err := cmd.Start(); err != nil {
return err
Expand Down Expand Up @@ -715,8 +710,8 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
return nil
}

func (m *MacMachine) State(_ bool) (machine.Status, error) {
vmStatus, err := m.Vfkit.state()
func (m *MacMachine) State(_ bool) (define.Status, error) {
vmStatus, err := m.Vfkit.State()
if err != nil {
return "", err
}
Expand All @@ -732,7 +727,7 @@ func (m *MacMachine) Stop(name string, opts machine.StopOptions) error {
return err
}

if vmState != machine.Running {
if vmState != define.Running {
return nil
}

Expand All @@ -742,7 +737,7 @@ func (m *MacMachine) Stop(name string, opts machine.StopOptions) error {
}
}()

return m.Vfkit.stop(false, true)
return m.Vfkit.Stop(false, true)
}

// getVMConfigPath is a simple wrapper for getting the fully-qualified
Expand Down Expand Up @@ -845,7 +840,7 @@ func getVMInfos() ([]*machine.ListResponse, error) {
if err != nil {
return err
}
listEntry.Running = vmState == machine.Running
listEntry.Running = vmState == define.Running
listEntry.LastUp = vm.LastUp

listed = append(listed, listEntry)
Expand Down
36 changes: 21 additions & 15 deletions pkg/machine/applehv/rest.go → pkg/machine/applehv/vfkit/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//go:build darwin
// +build darwin

package applehv
package vfkit

import (
"bytes"
Expand All @@ -12,14 +12,13 @@ import (
"net/http"
"time"

"github.com/containers/podman/v4/pkg/machine"
"github.com/crc-org/vfkit/pkg/rest/define"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/crc-org/vfkit/pkg/config"
rest "github.com/crc-org/vfkit/pkg/rest/define"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

type Endpoint string

const (
inspect = "/vm/inspect"
state = "/vm/state"
Expand All @@ -45,8 +44,8 @@ func (vf *VfkitHelper) post(endpoint string, payload io.Reader) (*http.Response,
}

// getRawState asks vfkit for virtual machine state unmodified (see state())
func (vf *VfkitHelper) getRawState() (machine.Status, error) {
var response define.VMState
func (vf *VfkitHelper) getRawState() (define.Status, error) {
var response rest.VMState
endPoint := vf.Endpoint + state
serverResponse, err := vf.get(endPoint, nil)
if err != nil {
Expand All @@ -60,25 +59,24 @@ func (vf *VfkitHelper) getRawState() (machine.Status, error) {
return "", err
}
return ToMachineStatus(response.State)

}

// state asks vfkit for the virtual machine state. in case the vfkit
// service is not responding, we assume the service is not running
// and return a stopped status
func (vf *VfkitHelper) state() (machine.Status, error) {
func (vf *VfkitHelper) State() (define.Status, error) {
vmState, err := vf.getRawState()
if err == nil {
return vmState, err
}
if errors.Is(err, unix.ECONNREFUSED) {
return machine.Stopped, nil
return define.Stopped, nil
}
return "", err
}

func (vf *VfkitHelper) stateChange(newState define.StateChange) error {
b, err := json.Marshal(define.VMState{State: string(newState)})
func (vf *VfkitHelper) stateChange(newState rest.StateChange) error {
b, err := json.Marshal(rest.VMState{State: string(newState)})
if err != nil {
return err
}
Expand All @@ -87,15 +85,15 @@ func (vf *VfkitHelper) stateChange(newState define.StateChange) error {
return err
}

func (vf *VfkitHelper) stop(force, wait bool) error {
func (vf *VfkitHelper) Stop(force, wait bool) error {
waitDuration := time.Millisecond * 10
// TODO Add ability to wait until stopped
if force {
if err := vf.stateChange(define.HardStop); err != nil {
if err := vf.stateChange(rest.HardStop); err != nil {
return err
}
} else {
if err := vf.stateChange(define.Stop); err != nil {
if err := vf.stateChange(rest.Stop); err != nil {
return err
}
}
Expand All @@ -116,3 +114,11 @@ func (vf *VfkitHelper) stop(force, wait bool) error {
}
return waitErr
}

// VfkitHelper describes the use of vfkit: cmdline and endpoint
type VfkitHelper struct {
LogLevel logrus.Level
Endpoint string
VfkitBinaryPath *define.VMFile
VirtualMachine *config.VirtualMachine
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
//go:build darwin
// +build darwin

package applehv
package vfkit

import (
"errors"
"fmt"

"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/define"
)

type Endpoint string

// VZMachineState is what the restful service in vfkit will return
type VZMachineState string

Expand All @@ -26,14 +28,14 @@ const (
VZMachineStateStopping VZMachineState = "VirtualMachineStateStopping"
)

func ToMachineStatus(val string) (machine.Status, error) {
func ToMachineStatus(val string) (define.Status, error) {
switch val {
case string(VZMachineStateRunning), string(VZMachineStatePausing), string(VZMachineStateResuming), string(VZMachineStateStopping), string(VZMachineStatePaused):
return machine.Running, nil
return define.Running, nil
case string(VZMachineStateStopped):
return machine.Stopped, nil
return define.Stopped, nil
case string(VZMachineStateStarting):
return machine.Starting, nil
return define.Starting, nil
case string(VZMachineStateError):
return "", errors.New("machine is in error state")
}
Expand Down
Loading

0 comments on commit e5a4f00

Please sign in to comment.