71 lines
2.4 KiB
Go
71 lines
2.4 KiB
Go
// Package inspect reports local prerequisite observations without executing
|
|
// commands, connecting to Docker or altering configuration.
|
|
package inspect
|
|
|
|
import (
|
|
"errors"
|
|
"io/fs"
|
|
"os"
|
|
"runtime"
|
|
)
|
|
|
|
type Report struct {
|
|
ProtocolVersion int `json:"protocolVersion"`
|
|
OS string `json:"os"`
|
|
Architecture string `json:"architecture"`
|
|
SupportedPlatform bool `json:"supportedPlatform"`
|
|
SystemdRuntime string `json:"systemdRuntime"`
|
|
DockerClient string `json:"dockerClient"`
|
|
DockerDaemon string `json:"dockerDaemon"`
|
|
Compose string `json:"compose"`
|
|
Unchecked []string `json:"unchecked"`
|
|
DeploymentReady bool `json:"deploymentReady"`
|
|
}
|
|
|
|
func Collect() Report { return Probe(runtime.GOOS, runtime.GOARCH, os.DirFS("/")) }
|
|
|
|
// Probe observes filesystem metadata only. "present" is not an assertion that
|
|
// systemd is responsive or the Docker executable is authentic or operational.
|
|
func Probe(goos, arch string, files fs.FS) Report {
|
|
r := Report{ProtocolVersion: 1, OS: goos, Architecture: arch, SupportedPlatform: goos == "linux" && (arch == "amd64" || arch == "arm64"), SystemdRuntime: "not_checked", DockerClient: "not_checked", DockerDaemon: "not_checked", Compose: "not_checked", Unchecked: []string{"docker_daemon", "compose_version", "host_identity", "distribution_support", "permissions", "disk_space", "ports", "dns", "firewall", "gateway"}}
|
|
if goos != "linux" {
|
|
return r
|
|
}
|
|
r.SystemdRuntime = observe(files, "run/systemd/system", true)
|
|
r.DockerClient = observe(files, "usr/bin/docker", false)
|
|
if r.DockerClient != "present" {
|
|
alternate := observe(files, "usr/local/bin/docker", false)
|
|
// Either known executable establishes presence. Otherwise retain any
|
|
// uncertainty instead of reporting absence from an incomplete check.
|
|
switch {
|
|
case alternate == "present":
|
|
r.DockerClient = "present"
|
|
case r.DockerClient == "unknown" || alternate == "unknown":
|
|
r.DockerClient = "unknown"
|
|
case r.DockerClient == "invalid" || alternate == "invalid":
|
|
r.DockerClient = "invalid"
|
|
}
|
|
}
|
|
return r
|
|
}
|
|
|
|
func observe(files fs.FS, path string, directory bool) string {
|
|
info, err := fs.Stat(files, path)
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
return "missing"
|
|
}
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
if directory {
|
|
if info.IsDir() {
|
|
return "present"
|
|
}
|
|
return "invalid"
|
|
}
|
|
if !info.Mode().IsRegular() || info.Mode().Perm()&0111 == 0 {
|
|
return "invalid"
|
|
}
|
|
return "present"
|
|
}
|