Skip to content

Commit

Permalink
Merge pull request #14033 from baude/inspectredo
Browse files Browse the repository at this point in the history
Refactor machine inspect
  • Loading branch information
openshift-merge-robot authored Apr 28, 2022
2 parents 2e9f792 + 2902d32 commit 765c881
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 174 deletions.
8 changes: 2 additions & 6 deletions cmd/podman/machine/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,12 @@ func inspect(cmd *cobra.Command, args []string) error {
errs = append(errs, err)
continue
}
state, err := vm.State(false)
ii, err := vm.Inspect()
if err != nil {
errs = append(errs, err)
continue
}
ii := machine.InspectInfo{
State: state,
VM: vm,
}
vms = append(vms, ii)
vms = append(vms, *ii)
}
if len(inspectFlag.format) > 0 {
// need jhonce to work his template magic
Expand Down
134 changes: 131 additions & 3 deletions pkg/machine/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package machine

import (
errors2 "errors"
"io/ioutil"
"net"
"net/url"
"os"
Expand All @@ -12,6 +14,7 @@ import (

"github.com/containers/storage/pkg/homedir"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

type InitOptions struct {
Expand Down Expand Up @@ -68,7 +71,7 @@ type Download struct {
Artifact string
CompressionType string
Format string
ImageName string `json:"image_name"`
ImageName string
LocalPath string
LocalUncompressedFile string
Sha256sum string
Expand Down Expand Up @@ -120,6 +123,7 @@ type InspectOptions struct{}

type VM interface {
Init(opts InitOptions) (bool, error)
Inspect() (*InspectInfo, error)
Remove(name string, opts RemoveOptions) (string, func() error, error)
Set(name string, opts SetOptions) ([]error, error)
SSH(name string, opts SSHOptions) error
Expand All @@ -133,8 +137,14 @@ type DistributionDownload interface {
Get() *Download
}
type InspectInfo struct {
State Status
VM
ConfigPath VMFile
Created time.Time
Image ImageConfig
LastUp time.Time
Name string
Resources ResourceConfig
SSHConfig SSHConfig
State Status
}

func (rc RemoteConnectionType) MakeSSHURL(host, path, port, userName string) url.URL {
Expand Down Expand Up @@ -186,3 +196,121 @@ func GetConfDir(vmType string) (string, error) {
mkdirErr := os.MkdirAll(confDir, 0755)
return confDir, mkdirErr
}

// ResourceConfig describes physical attributes of the machine
type ResourceConfig struct {
// CPUs to be assigned to the VM
CPUs uint64
// Disk size in gigabytes assigned to the vm
DiskSize uint64
// Memory in megabytes assigned to the vm
Memory uint64
}

const maxSocketPathLength int = 103

type VMFile struct {
// Path is the fully qualified path to a file
Path string
// Symlink is a shortened version of Path by using
// a symlink
Symlink *string `json:"symlink,omitempty"`
}

// GetPath returns the working path for a machinefile. it returns
// the symlink unless one does not exist
func (m *VMFile) GetPath() string {
if m.Symlink == nil {
return m.Path
}
return *m.Symlink
}

// Delete removes the machinefile symlink (if it exists) and
// the actual path
func (m *VMFile) Delete() error {
if m.Symlink != nil {
if err := os.Remove(*m.Symlink); err != nil && !errors2.Is(err, os.ErrNotExist) {
logrus.Errorf("unable to remove symlink %q", *m.Symlink)
}
}
if err := os.Remove(m.Path); err != nil && !errors2.Is(err, os.ErrNotExist) {
return err
}
return nil
}

// Read the contents of a given file and return in []bytes
func (m *VMFile) Read() ([]byte, error) {
return ioutil.ReadFile(m.GetPath())
}

// NewMachineFile is a constructor for VMFile
func NewMachineFile(path string, symlink *string) (*VMFile, error) {
if len(path) < 1 {
return nil, errors2.New("invalid machine file path")
}
if symlink != nil && len(*symlink) < 1 {
return nil, errors2.New("invalid symlink path")
}
mf := VMFile{Path: path}
if symlink != nil && len(path) > maxSocketPathLength {
if err := mf.makeSymlink(symlink); err != nil && !errors2.Is(err, os.ErrExist) {
return nil, err
}
}
return &mf, nil
}

// makeSymlink for macOS creates a symlink in $HOME/.podman/
// for a machinefile like a socket
func (m *VMFile) makeSymlink(symlink *string) error {
homedir, err := os.UserHomeDir()
if err != nil {
return err
}
sl := filepath.Join(homedir, ".podman", *symlink)
// make the symlink dir and throw away if it already exists
if err := os.MkdirAll(filepath.Dir(sl), 0700); err != nil && !errors2.Is(err, os.ErrNotExist) {
return err
}
m.Symlink = &sl
return os.Symlink(m.Path, sl)
}

type Mount struct {
ReadOnly bool
Source string
Tag string
Target string
Type string
}

// ImageConfig describes the bootable image for the VM
type ImageConfig struct {
// IgnitionFile is the path to the filesystem where the
// ignition file was written (if needs one)
IgnitionFile VMFile `json:"IgnitionFilePath"`
// ImageStream is the update stream for the image
ImageStream string
// ImageFile is the fq path to
ImagePath VMFile `json:"ImagePath"`
}

// HostUser describes the host user
type HostUser struct {
// Whether this machine should run in a rootful or rootless manner
Rootful bool
// UID is the numerical id of the user that called machine
UID int
}

// SSHConfig contains remote access information for SSH
type SSHConfig struct {
// IdentityPath is the fq path to the ssh priv key
IdentityPath string
// SSH port for user networking
Port int
// RemoteUsername of the vm user
RemoteUsername string
}
142 changes: 12 additions & 130 deletions pkg/machine/qemu/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@
package qemu

import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"time"

"github.com/sirupsen/logrus"
"github.com/containers/podman/v4/pkg/machine"
)

const (
Expand All @@ -23,7 +19,7 @@ const (
Stable string = "stable"

// Max length of fully qualified socket path
maxSocketPathLength int = 103

)

type Provider struct{}
Expand All @@ -36,7 +32,7 @@ type MachineVMV1 struct {
// The command line representation of the qemu command
CmdLine []string
// Mounts is the list of remote filesystems to mount
Mounts []Mount
Mounts []machine.Mount
// IdentityPath is the fq path to the ssh priv key
IdentityPath string
// IgnitionFilePath is the fq path to the .ign file
Expand Down Expand Up @@ -65,27 +61,27 @@ type MachineVMV1 struct {

type MachineVM struct {
// ConfigPath is the path to the configuration file
ConfigPath MachineFile
ConfigPath machine.VMFile
// The command line representation of the qemu command
CmdLine []string
// HostUser contains info about host user
HostUser
machine.HostUser
// ImageConfig describes the bootable image
ImageConfig
machine.ImageConfig
// Mounts is the list of remote filesystems to mount
Mounts []Mount
Mounts []machine.Mount
// Name of VM
Name string
// PidFilePath is the where the PID file lives
PidFilePath MachineFile
PidFilePath machine.VMFile
// QMPMonitor is the qemu monitor object for sending commands
QMPMonitor Monitor
// ReadySocket tells host when vm is booted
ReadySocket MachineFile
ReadySocket machine.VMFile
// ResourceConfig is physical attrs of the VM
ResourceConfig
machine.ResourceConfig
// SSHConfig for accessing the remote vm
SSHConfig
machine.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
Expand All @@ -94,59 +90,6 @@ type MachineVM struct {
LastUp time.Time
}

// ImageConfig describes the bootable image for the VM
type ImageConfig struct {
IgnitionFilePath MachineFile
// ImageStream is the update stream for the image
ImageStream string
// ImagePath is the fq path to
ImagePath MachineFile
}

// HostUser describes the host user
type HostUser struct {
// Whether this machine should run in a rootful or rootless manner
Rootful bool
// UID is the numerical id of the user that called machine
UID int
}

// SSHConfig contains remote access information for SSH
type SSHConfig struct {
// IdentityPath is the fq path to the ssh priv key
IdentityPath string
// SSH port for user networking
Port int
// RemoteUsername of the vm user
RemoteUsername string
}

// ResourceConfig describes physical attributes of the machine
type ResourceConfig struct {
// CPUs to be assigned to the VM
CPUs uint64
// Memory in megabytes assigned to the vm
Memory uint64
// Disk size in gigabytes assigned to the vm
DiskSize uint64
}

type MachineFile struct {
// Path is the fully qualified path to a file
Path string
// Symlink is a shortened version of Path by using
// a symlink
Symlink *string
}

type Mount struct {
Type string
Tag string
Source string
Target string
ReadOnly bool
}

type Monitorv1 struct {
// Address portion of the qmp monitor (/tmp/tmp.sock)
Address string
Expand All @@ -158,7 +101,7 @@ type Monitorv1 struct {

type Monitor struct {
// Address portion of the qmp monitor (/tmp/tmp.sock)
Address MachineFile
Address machine.VMFile
// Network portion of the qmp monitor (unix)
Network string
// Timeout in seconds for qmp monitor transactions
Expand All @@ -170,64 +113,3 @@ var (
// qmp monitor interactions.
defaultQMPTimeout = 2 * time.Second
)

// GetPath returns the working path for a machinefile. it returns
// the symlink unless one does not exist
func (m *MachineFile) GetPath() string {
if m.Symlink == nil {
return m.Path
}
return *m.Symlink
}

// Delete removes the machinefile symlink (if it exists) and
// the actual path
func (m *MachineFile) Delete() error {
if m.Symlink != nil {
if err := os.Remove(*m.Symlink); err != nil && !errors.Is(err, os.ErrNotExist) {
logrus.Errorf("unable to remove symlink %q", *m.Symlink)
}
}
if err := os.Remove(m.Path); err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
return nil
}

// Read the contents of a given file and return in []bytes
func (m *MachineFile) Read() ([]byte, error) {
return ioutil.ReadFile(m.GetPath())
}

// NewMachineFile is a constructor for MachineFile
func NewMachineFile(path string, symlink *string) (*MachineFile, error) {
if len(path) < 1 {
return nil, errors.New("invalid machine file path")
}
if symlink != nil && len(*symlink) < 1 {
return nil, errors.New("invalid symlink path")
}
mf := MachineFile{Path: path}
if symlink != nil && len(path) > maxSocketPathLength {
if err := mf.makeSymlink(symlink); err != nil && !errors.Is(err, os.ErrExist) {
return nil, err
}
}
return &mf, nil
}

// makeSymlink for macOS creates a symlink in $HOME/.podman/
// for a machinefile like a socket
func (m *MachineFile) makeSymlink(symlink *string) error {
homedir, err := os.UserHomeDir()
if err != nil {
return err
}
sl := filepath.Join(homedir, ".podman", *symlink)
// make the symlink dir and throw away if it already exists
if err := os.MkdirAll(filepath.Dir(sl), 0700); err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
m.Symlink = &sl
return os.Symlink(m.Path, sl)
}
Loading

0 comments on commit 765c881

Please sign in to comment.