-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14762 from ashley-cui/machinfo
Podman machine info
- Loading branch information
Showing
9 changed files
with
320 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
//go:build amd64 || arm64 | ||
// +build amd64 arm64 | ||
|
||
package machine | ||
|
||
import ( | ||
"fmt" | ||
"html/template" | ||
"os" | ||
"runtime" | ||
|
||
"github.com/containers/common/pkg/completion" | ||
"github.com/containers/common/pkg/config" | ||
"github.com/containers/common/pkg/report" | ||
"github.com/containers/podman/v4/cmd/podman/common" | ||
"github.com/containers/podman/v4/cmd/podman/registry" | ||
"github.com/containers/podman/v4/cmd/podman/validate" | ||
"github.com/containers/podman/v4/libpod/define" | ||
"github.com/containers/podman/v4/pkg/machine" | ||
"github.com/ghodss/yaml" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var infoDescription = `Display information pertaining to the machine host.` | ||
|
||
var ( | ||
infoCmd = &cobra.Command{ | ||
Use: "info [options]", | ||
Short: "Display machine host info", | ||
Long: infoDescription, | ||
PersistentPreRunE: rootlessOnly, | ||
RunE: info, | ||
Args: validate.NoArgs, | ||
ValidArgsFunction: completion.AutocompleteNone, | ||
Example: `podman machine info`, | ||
} | ||
) | ||
|
||
var ( | ||
inFormat string | ||
) | ||
|
||
// Info contains info on the machine host and version info | ||
type Info struct { | ||
Host *HostInfo `json:"Host"` | ||
Version define.Version `json:"Version"` | ||
} | ||
|
||
// HostInfo contains info on the machine host | ||
type HostInfo struct { | ||
Arch string `json:"Arch"` | ||
CurrentMachine string `json:"CurrentMachine"` | ||
DefaultMachine string `json:"DefaultMachine"` | ||
EventsDir string `json:"EventsDir"` | ||
MachineConfigDir string `json:"MachineConfigDir"` | ||
MachineImageDir string `json:"MachineImageDir"` | ||
MachineState string `json:"MachineState"` | ||
NumberOfMachines int `json:"NumberOfMachines"` | ||
OS string `json:"OS"` | ||
VMType string `json:"VMType"` | ||
} | ||
|
||
func init() { | ||
registry.Commands = append(registry.Commands, registry.CliCommand{ | ||
Command: infoCmd, | ||
Parent: machineCmd, | ||
}) | ||
|
||
flags := infoCmd.Flags() | ||
formatFlagName := "format" | ||
flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") | ||
_ = infoCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&define.Info{})) | ||
} | ||
|
||
func info(cmd *cobra.Command, args []string) error { | ||
info := Info{} | ||
version, err := define.GetVersion() | ||
if err != nil { | ||
return fmt.Errorf("error getting version info %w", err) | ||
} | ||
info.Version = version | ||
|
||
host, err := hostInfo() | ||
if err != nil { | ||
return err | ||
} | ||
info.Host = host | ||
|
||
switch { | ||
case report.IsJSON(inFormat): | ||
b, err := json.MarshalIndent(info, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(string(b)) | ||
case cmd.Flags().Changed("format"): | ||
tmpl := template.New(cmd.Name()).Funcs(template.FuncMap(report.DefaultFuncs)) | ||
inFormat = report.NormalizeFormat(inFormat) | ||
tmpl, err := tmpl.Parse(inFormat) | ||
if err != nil { | ||
return err | ||
} | ||
return tmpl.Execute(os.Stdout, info) | ||
default: | ||
b, err := yaml.Marshal(info) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(string(b)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func hostInfo() (*HostInfo, error) { | ||
host := HostInfo{} | ||
|
||
host.Arch = runtime.GOARCH | ||
host.OS = runtime.GOOS | ||
|
||
provider := GetSystemDefaultProvider() | ||
var listOpts machine.ListOptions | ||
listResponse, err := provider.List(listOpts) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get machines %w", err) | ||
} | ||
|
||
host.NumberOfMachines = len(listResponse) | ||
|
||
cfg, err := config.ReadCustomConfig() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Default state of machine is stopped | ||
host.MachineState = "Stopped" | ||
for _, vm := range listResponse { | ||
// Set default machine if found | ||
if vm.Name == cfg.Engine.ActiveService { | ||
host.DefaultMachine = vm.Name | ||
} | ||
// If machine is running or starting, it is automatically the current machine | ||
if vm.Running { | ||
host.CurrentMachine = vm.Name | ||
host.MachineState = "Running" | ||
} else if vm.Starting { | ||
host.CurrentMachine = vm.Name | ||
host.MachineState = "Starting" | ||
} | ||
} | ||
// If no machines are starting or running, set current machine to default machine | ||
// If no default machines are found, do not report a default machine or a state | ||
if host.CurrentMachine == "" { | ||
if host.DefaultMachine == "" { | ||
host.MachineState = "" | ||
} else { | ||
host.CurrentMachine = host.DefaultMachine | ||
} | ||
} | ||
|
||
host.VMType = provider.VMType() | ||
|
||
dataDir, err := machine.GetDataDir(host.VMType) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get machine image dir") | ||
} | ||
host.MachineImageDir = dataDir | ||
|
||
confDir, err := machine.GetConfDir(host.VMType) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get machine config dir %w", err) | ||
} | ||
host.MachineConfigDir = confDir | ||
|
||
eventsDir, err := eventSockDir() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get events dir: %w", err) | ||
} | ||
host.EventsDir = eventsDir | ||
|
||
return &host, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
% podman-machine-info(1) | ||
|
||
## NAME | ||
podman\-machine\-info - Display machine host info | ||
|
||
## SYNOPSIS | ||
**podman machine info** | ||
|
||
## DESCRIPTION | ||
|
||
Display information pertaining to the machine host. | ||
Rootless only, as all `podman machine` commands can be only be used with rootless Podman. | ||
|
||
## OPTIONS | ||
|
||
#### **--format**=*format*, **-f** | ||
|
||
Change output format to "json" or a Go template. | ||
|
||
#### **--help** | ||
|
||
Print usage statement. | ||
|
||
## EXAMPLES | ||
|
||
``` | ||
$ podman machine info | ||
$ podman machine info --format json | ||
$ podman machine info --format {{.Host.Arch}} | ||
``` | ||
|
||
## SEE ALSO | ||
**[podman(1)](podman.1.md)**, **[podman-machine(1)](podman-machine.1.md)** | ||
|
||
## HISTORY | ||
June 2022, Originally compiled by Ashley Cui <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ All `podman machine` commands are rootless only. | |
|
||
| Command | Man Page | Description | | ||
|---------|------------------------------------------------------|-----------------------------------| | ||
| info | [podman-machine-info(1)](podman-machine-info.1.md) | Display machine host info | | ||
| init | [podman-machine-init(1)](podman-machine-init.1.md) | Initialize a new virtual machine | | ||
| inspect | [podman-machine-inspect(1)](podman-machine-inspect.1.md) | Inspect one or more virtual machines | | ||
| list | [podman-machine-list(1)](podman-machine-list.1.md) | List virtual machines | | ||
|
@@ -30,7 +31,7 @@ All `podman machine` commands are rootless only. | |
| stop | [podman-machine-stop(1)](podman-machine-stop.1.md) | Stop a virtual machine | | ||
|
||
## SEE ALSO | ||
**[podman(1)](podman.1.md)**, **[podman-machine-init(1)](podman-machine-init.1.md)**, **[podman-machine-list(1)](podman-machine-list.1.md)**, **[podman-machine-rm(1)](podman-machine-rm.1.md)**, **[podman-machine-ssh(1)](podman-machine-ssh.1.md)**, **[podman-machine-start(1)](podman-machine-start.1.md)**, **[podman-machine-stop(1)](podman-machine-stop.1.md)**, **[podman-machine-inspect(1)](podman-machine-inspect.1.md)** | ||
**[podman(1)](podman.1.md)**, **[podman-machine-info(1)](podman-machine-info.1.md)**, **[podman-machine-init(1)](podman-machine-init.1.md)**, **[podman-machine-list(1)](podman-machine-list.1.md)**, **[podman-machine-rm(1)](podman-machine-rm.1.md)**, **[podman-machine-ssh(1)](podman-machine-ssh.1.md)**, **[podman-machine-start(1)](podman-machine-start.1.md)**, **[podman-machine-stop(1)](podman-machine-stop.1.md)**, **[podman-machine-inspect(1)](podman-machine-inspect.1.md)** | ||
|
||
## HISTORY | ||
March 2021, Originally compiled by Ashley Cui <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package e2e | ||
|
||
type infoMachine struct { | ||
format string | ||
cmd []string | ||
} | ||
|
||
func (i *infoMachine) buildCmd(m *machineTestBuilder) []string { | ||
cmd := []string{"machine", "info"} | ||
if len(i.format) > 0 { | ||
cmd = append(cmd, "--format", i.format) | ||
} | ||
i.cmd = cmd | ||
return cmd | ||
} | ||
|
||
func (i *infoMachine) withFormat(format string) *infoMachine { | ||
i.format = format | ||
return i | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package e2e | ||
|
||
import ( | ||
"github.com/containers/podman/v4/cmd/podman/machine" | ||
jsoniter "github.com/json-iterator/go" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
. "github.com/onsi/gomega/gexec" | ||
) | ||
|
||
var _ = Describe("podman machine info", func() { | ||
var ( | ||
mb *machineTestBuilder | ||
testDir string | ||
) | ||
|
||
BeforeEach(func() { | ||
testDir, mb = setup() | ||
}) | ||
AfterEach(func() { | ||
teardown(originalHomeDir, testDir, mb) | ||
}) | ||
|
||
It("machine info", func() { | ||
info := new(infoMachine) | ||
infoSession, err := mb.setCmd(info).run() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(infoSession).Should(Exit(0)) | ||
|
||
// Verify go template works and check for no running machines | ||
info = new(infoMachine) | ||
infoSession, err = mb.setCmd(info.withFormat("{{.Host.NumberOfMachines}}")).run() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(infoSession).Should(Exit(0)) | ||
Expect(infoSession.outputToString()).To(Equal("0")) | ||
|
||
// Create a machine and check if info has been updated | ||
i := new(initMachine) | ||
initSession, err := mb.setCmd(i.withImagePath(mb.imagePath)).run() | ||
Expect(err).To(BeNil()) | ||
Expect(initSession).To(Exit(0)) | ||
|
||
info = new(infoMachine) | ||
infoSession, err = mb.setCmd(info.withFormat("{{.Host.NumberOfMachines}}")).run() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(infoSession).Should(Exit(0)) | ||
Expect(infoSession.outputToString()).To(Equal("1")) | ||
|
||
// Check if json is in correct format | ||
infoSession, err = mb.setCmd(info.withFormat("json")).run() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(infoSession).Should(Exit(0)) | ||
|
||
infoReport := &machine.Info{} | ||
err = jsoniter.Unmarshal(infoSession.Bytes(), infoReport) | ||
Expect(err).To(BeNil()) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters