Initial commit
This commit is contained in:
100
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/kernel.go
generated
vendored
Normal file
100
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/kernel.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// +build !windows
|
||||
|
||||
// Package kernel provides helper function to get, parse and compare kernel
|
||||
// versions for different platforms.
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// VersionInfo holds information about the kernel.
|
||||
type VersionInfo struct {
|
||||
Kernel int // Version of the kernel (e.g. 4.1.2-generic -> 4)
|
||||
Major int // Major part of the kernel version (e.g. 4.1.2-generic -> 1)
|
||||
Minor int // Minor part of the kernel version (e.g. 4.1.2-generic -> 2)
|
||||
Flavor string // Flavor of the kernel version (e.g. 4.1.2-generic -> generic)
|
||||
}
|
||||
|
||||
func (k *VersionInfo) String() string {
|
||||
return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
|
||||
}
|
||||
|
||||
// CompareKernelVersion compares two kernel.VersionInfo structs.
|
||||
// Returns -1 if a < b, 0 if a == b, 1 it a > b
|
||||
func CompareKernelVersion(a, b VersionInfo) int {
|
||||
if a.Kernel < b.Kernel {
|
||||
return -1
|
||||
} else if a.Kernel > b.Kernel {
|
||||
return 1
|
||||
}
|
||||
|
||||
if a.Major < b.Major {
|
||||
return -1
|
||||
} else if a.Major > b.Major {
|
||||
return 1
|
||||
}
|
||||
|
||||
if a.Minor < b.Minor {
|
||||
return -1
|
||||
} else if a.Minor > b.Minor {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetKernelVersion gets the current kernel version.
|
||||
func GetKernelVersion() (*VersionInfo, error) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
uts, err := uname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
release := make([]byte, len(uts.Release))
|
||||
|
||||
i := 0
|
||||
for _, c := range uts.Release {
|
||||
release[i] = byte(c)
|
||||
i++
|
||||
}
|
||||
|
||||
// Remove the \x00 from the release for Atoi to parse correctly
|
||||
release = release[:bytes.IndexByte(release, 0)]
|
||||
|
||||
return ParseRelease(string(release))
|
||||
}
|
||||
|
||||
// ParseRelease parses a string and creates a VersionInfo based on it.
|
||||
func ParseRelease(release string) (*VersionInfo, error) {
|
||||
var (
|
||||
kernel, major, minor, parsed int
|
||||
flavor, partial string
|
||||
)
|
||||
|
||||
// Ignore error from Sscanf to allow an empty flavor. Instead, just
|
||||
// make sure we got all the version numbers.
|
||||
parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
|
||||
if parsed < 2 {
|
||||
return nil, errors.New("Can't parse kernel version " + release)
|
||||
}
|
||||
|
||||
// sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
|
||||
parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
|
||||
if parsed < 1 {
|
||||
flavor = partial
|
||||
}
|
||||
|
||||
return &VersionInfo{
|
||||
Kernel: kernel,
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Flavor: flavor,
|
||||
}, nil
|
||||
}
|
||||
96
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/kernel_unix_test.go
generated
vendored
Normal file
96
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/kernel_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// +build !windows
|
||||
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func assertParseRelease(t *testing.T, release string, b *VersionInfo, result int) {
|
||||
var (
|
||||
a *VersionInfo
|
||||
)
|
||||
a, _ = ParseRelease(release)
|
||||
|
||||
if r := CompareKernelVersion(*a, *b); r != result {
|
||||
t.Fatalf("Unexpected kernel version comparison result for (%v,%v). Found %d, expected %d", release, b, r, result)
|
||||
}
|
||||
if a.Flavor != b.Flavor {
|
||||
t.Fatalf("Unexpected parsed kernel flavor. Found %s, expected %s", a.Flavor, b.Flavor)
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseRelease tests the ParseRelease() function
|
||||
func TestParseRelease(t *testing.T) {
|
||||
assertParseRelease(t, "3.8.0", &VersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
|
||||
assertParseRelease(t, "3.4.54.longterm-1", &VersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
|
||||
assertParseRelease(t, "3.4.54.longterm-1", &VersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
|
||||
assertParseRelease(t, "3.8.0-19-generic", &VersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
|
||||
assertParseRelease(t, "3.12.8tag", &VersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
|
||||
assertParseRelease(t, "3.12-1-amd64", &VersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
|
||||
assertParseRelease(t, "3.8.0", &VersionInfo{Kernel: 4, Major: 8, Minor: 0}, -1)
|
||||
// Errors
|
||||
invalids := []string{
|
||||
"3",
|
||||
"a",
|
||||
"a.a",
|
||||
"a.a.a-a",
|
||||
}
|
||||
for _, invalid := range invalids {
|
||||
expectedMessage := fmt.Sprintf("Can't parse kernel version %v", invalid)
|
||||
if _, err := ParseRelease(invalid); err == nil || err.Error() != expectedMessage {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func assertKernelVersion(t *testing.T, a, b VersionInfo, result int) {
|
||||
if r := CompareKernelVersion(a, b); r != result {
|
||||
t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
|
||||
}
|
||||
}
|
||||
|
||||
// TestCompareKernelVersion tests the CompareKernelVersion() function
|
||||
func TestCompareKernelVersion(t *testing.T) {
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
0)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 2, Major: 6, Minor: 0},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
-1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
VersionInfo{Kernel: 2, Major: 6, Minor: 0},
|
||||
1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
0)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 5},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 0, Minor: 20},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
-1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 7, Minor: 20},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
-1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 20},
|
||||
VersionInfo{Kernel: 3, Major: 7, Minor: 0},
|
||||
1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 20},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
1)
|
||||
assertKernelVersion(t,
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
|
||||
VersionInfo{Kernel: 3, Major: 8, Minor: 20},
|
||||
-1)
|
||||
}
|
||||
67
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/kernel_windows.go
generated
vendored
Normal file
67
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/kernel_windows.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// VersionInfo holds information about the kernel.
|
||||
type VersionInfo struct {
|
||||
kvi string // Version of the kernel (e.g. 6.1.7601.17592 -> 6)
|
||||
major int // Major part of the kernel version (e.g. 6.1.7601.17592 -> 1)
|
||||
minor int // Minor part of the kernel version (e.g. 6.1.7601.17592 -> 7601)
|
||||
build int // Build number of the kernel version (e.g. 6.1.7601.17592 -> 17592)
|
||||
}
|
||||
|
||||
func (k *VersionInfo) String() string {
|
||||
return fmt.Sprintf("%d.%d %d (%s)", k.major, k.minor, k.build, k.kvi)
|
||||
}
|
||||
|
||||
// GetKernelVersion gets the current kernel version.
|
||||
func GetKernelVersion() (*VersionInfo, error) {
|
||||
|
||||
var (
|
||||
h syscall.Handle
|
||||
dwVersion uint32
|
||||
err error
|
||||
)
|
||||
|
||||
KVI := &VersionInfo{"Unknown", 0, 0, 0}
|
||||
|
||||
if err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
|
||||
syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
|
||||
0,
|
||||
syscall.KEY_READ,
|
||||
&h); err != nil {
|
||||
return KVI, err
|
||||
}
|
||||
defer syscall.RegCloseKey(h)
|
||||
|
||||
var buf [1 << 10]uint16
|
||||
var typ uint32
|
||||
n := uint32(len(buf) * 2) // api expects array of bytes, not uint16
|
||||
|
||||
if err = syscall.RegQueryValueEx(h,
|
||||
syscall.StringToUTF16Ptr("BuildLabEx"),
|
||||
nil,
|
||||
&typ,
|
||||
(*byte)(unsafe.Pointer(&buf[0])),
|
||||
&n); err != nil {
|
||||
return KVI, err
|
||||
}
|
||||
|
||||
KVI.kvi = syscall.UTF16ToString(buf[:])
|
||||
|
||||
// Important - docker.exe MUST be manifested for this API to return
|
||||
// the correct information.
|
||||
if dwVersion, err = syscall.GetVersion(); err != nil {
|
||||
return KVI, err
|
||||
}
|
||||
|
||||
KVI.major = int(dwVersion & 0xFF)
|
||||
KVI.minor = int((dwVersion & 0XFF00) >> 8)
|
||||
KVI.build = int((dwVersion & 0xFFFF0000) >> 16)
|
||||
|
||||
return KVI, nil
|
||||
}
|
||||
19
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/uname_linux.go
generated
vendored
Normal file
19
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/uname_linux.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Utsname represents the system name structure.
|
||||
// It is passthgrouh for syscall.Utsname in order to make it portable with
|
||||
// other platforms where it is not available.
|
||||
type Utsname syscall.Utsname
|
||||
|
||||
func uname() (*syscall.Utsname, error) {
|
||||
uts := &syscall.Utsname{}
|
||||
|
||||
if err := syscall.Uname(uts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uts, nil
|
||||
}
|
||||
18
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/uname_unsupported.go
generated
vendored
Normal file
18
vendor/github.com/hyperhq/hypercli/pkg/parsers/kernel/uname_unsupported.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// +build !linux
|
||||
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Utsname represents the system name structure.
|
||||
// It is defined here to make it portable as it is available on linux but not
|
||||
// on windows.
|
||||
type Utsname struct {
|
||||
Release [65]byte
|
||||
}
|
||||
|
||||
func uname() (*Utsname, error) {
|
||||
return nil, errors.New("Kernel version detection is available only on linux")
|
||||
}
|
||||
18
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_freebsd.go
generated
vendored
Normal file
18
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package operatingsystem
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// GetOperatingSystem gets the name of the current operating system.
|
||||
func GetOperatingSystem() (string, error) {
|
||||
// TODO: Implement OS detection
|
||||
return "", errors.New("Cannot detect OS version")
|
||||
}
|
||||
|
||||
// IsContainerized returns true if we are running inside a container.
|
||||
// No-op on FreeBSD, always returns false.
|
||||
func IsContainerized() (bool, error) {
|
||||
// TODO: Implement jail detection
|
||||
return false, errors.New("Cannot detect if we are in container")
|
||||
}
|
||||
77
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_linux.go
generated
vendored
Normal file
77
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_linux.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Package operatingsystem provides helper function to get the operating system
|
||||
// name for different platforms.
|
||||
package operatingsystem
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-shellwords"
|
||||
)
|
||||
|
||||
var (
|
||||
// file to use to detect if the daemon is running in a container
|
||||
proc1Cgroup = "/proc/1/cgroup"
|
||||
|
||||
// file to check to determine Operating System
|
||||
etcOsRelease = "/etc/os-release"
|
||||
|
||||
// used by stateless systems like Clear Linux
|
||||
altOsRelease = "/usr/lib/os-release"
|
||||
)
|
||||
|
||||
// GetOperatingSystem gets the name of the current operating system.
|
||||
func GetOperatingSystem() (string, error) {
|
||||
osReleaseFile, err := os.Open(etcOsRelease)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("Error opening %s: %v", etcOsRelease, err)
|
||||
}
|
||||
osReleaseFile, err = os.Open(altOsRelease)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error opening %s: %v", altOsRelease, err)
|
||||
}
|
||||
}
|
||||
defer osReleaseFile.Close()
|
||||
|
||||
var prettyName string
|
||||
scanner := bufio.NewScanner(osReleaseFile)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "PRETTY_NAME=") {
|
||||
data := strings.SplitN(line, "=", 2)
|
||||
prettyNames, err := shellwords.Parse(data[1])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("PRETTY_NAME is invalid: %s", err.Error())
|
||||
}
|
||||
if len(prettyNames) != 1 {
|
||||
return "", fmt.Errorf("PRETTY_NAME needs to be enclosed by quotes if they have spaces: %s", data[1])
|
||||
}
|
||||
prettyName = prettyNames[0]
|
||||
}
|
||||
}
|
||||
if prettyName != "" {
|
||||
return prettyName, nil
|
||||
}
|
||||
// If not set, defaults to PRETTY_NAME="Linux"
|
||||
// c.f. http://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
return "Linux", nil
|
||||
}
|
||||
|
||||
// IsContainerized returns true if we are running inside a container.
|
||||
func IsContainerized() (bool, error) {
|
||||
b, err := ioutil.ReadFile(proc1Cgroup)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, line := range bytes.Split(b, []byte{'\n'}) {
|
||||
if len(line) > 0 && !bytes.HasSuffix(line, []byte{'/'}) && !bytes.HasSuffix(line, []byte("init.scope")) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
247
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_unix_test.go
generated
vendored
Normal file
247
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
// +build linux freebsd
|
||||
|
||||
package operatingsystem
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetOperatingSystem(t *testing.T) {
|
||||
var backup = etcOsRelease
|
||||
|
||||
invalids := []struct {
|
||||
content string
|
||||
errorExpected string
|
||||
}{
|
||||
{
|
||||
`PRETTY_NAME=Source Mage GNU/Linux
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
"PRETTY_NAME needs to be enclosed by quotes if they have spaces: Source Mage GNU/Linux",
|
||||
},
|
||||
{
|
||||
`PRETTY_NAME="Ubuntu Linux
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
"PRETTY_NAME is invalid: invalid command line string",
|
||||
},
|
||||
{
|
||||
`PRETTY_NAME=Ubuntu'
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
"PRETTY_NAME is invalid: invalid command line string",
|
||||
},
|
||||
{
|
||||
`PRETTY_NAME'
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
"PRETTY_NAME needs to be enclosed by quotes if they have spaces: Ubuntu 14.04.LTS",
|
||||
},
|
||||
}
|
||||
|
||||
valids := []struct {
|
||||
content string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
`NAME="Ubuntu"
|
||||
PRETTY_NAME_AGAIN="Ubuntu 14.04.LTS"
|
||||
VERSION="14.04, Trusty Tahr"
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
VERSION_ID="14.04"
|
||||
HOME_URL="http://www.ubuntu.com/"
|
||||
SUPPORT_URL="http://help.ubuntu.com/"
|
||||
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
|
||||
"Linux",
|
||||
},
|
||||
{
|
||||
`NAME="Ubuntu"
|
||||
VERSION="14.04, Trusty Tahr"
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
VERSION_ID="14.04"
|
||||
HOME_URL="http://www.ubuntu.com/"
|
||||
SUPPORT_URL="http://help.ubuntu.com/"
|
||||
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
|
||||
"Linux",
|
||||
},
|
||||
{
|
||||
`NAME=Gentoo
|
||||
ID=gentoo
|
||||
PRETTY_NAME="Gentoo/Linux"
|
||||
ANSI_COLOR="1;32"
|
||||
HOME_URL="http://www.gentoo.org/"
|
||||
SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
|
||||
BUG_REPORT_URL="https://bugs.gentoo.org/"
|
||||
`,
|
||||
"Gentoo/Linux",
|
||||
},
|
||||
{
|
||||
`NAME="Ubuntu"
|
||||
VERSION="14.04, Trusty Tahr"
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
PRETTY_NAME="Ubuntu 14.04 LTS"
|
||||
VERSION_ID="14.04"
|
||||
HOME_URL="http://www.ubuntu.com/"
|
||||
SUPPORT_URL="http://help.ubuntu.com/"
|
||||
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
|
||||
"Ubuntu 14.04 LTS",
|
||||
},
|
||||
{
|
||||
`NAME="Ubuntu"
|
||||
VERSION="14.04, Trusty Tahr"
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
PRETTY_NAME='Ubuntu 14.04 LTS'`,
|
||||
"Ubuntu 14.04 LTS",
|
||||
},
|
||||
{
|
||||
`PRETTY_NAME=Source
|
||||
NAME="Source Mage"`,
|
||||
"Source",
|
||||
},
|
||||
{
|
||||
`PRETTY_NAME=Source
|
||||
PRETTY_NAME="Source Mage"`,
|
||||
"Source Mage",
|
||||
},
|
||||
}
|
||||
|
||||
dir := os.TempDir()
|
||||
etcOsRelease = filepath.Join(dir, "etcOsRelease")
|
||||
|
||||
defer func() {
|
||||
os.Remove(etcOsRelease)
|
||||
etcOsRelease = backup
|
||||
}()
|
||||
|
||||
for _, elt := range invalids {
|
||||
if err := ioutil.WriteFile(etcOsRelease, []byte(elt.content), 0600); err != nil {
|
||||
t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
|
||||
}
|
||||
s, err := GetOperatingSystem()
|
||||
if err == nil || err.Error() != elt.errorExpected {
|
||||
t.Fatalf("Expected an error %q, got %q (err: %v)", elt.errorExpected, s, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, elt := range valids {
|
||||
if err := ioutil.WriteFile(etcOsRelease, []byte(elt.content), 0600); err != nil {
|
||||
t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
|
||||
}
|
||||
s, err := GetOperatingSystem()
|
||||
if err != nil || s != elt.expected {
|
||||
t.Fatalf("Expected %q, got %q (err: %v)", elt.expected, s, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsContainerized(t *testing.T) {
|
||||
var (
|
||||
backup = proc1Cgroup
|
||||
nonContainerizedProc1Cgroupsystemd226 = []byte(`9:memory:/init.scope
|
||||
8:net_cls,net_prio:/
|
||||
7:cpuset:/
|
||||
6:freezer:/
|
||||
5:devices:/init.scope
|
||||
4:blkio:/init.scope
|
||||
3:cpu,cpuacct:/init.scope
|
||||
2:perf_event:/
|
||||
1:name=systemd:/init.scope
|
||||
`)
|
||||
nonContainerizedProc1Cgroup = []byte(`14:name=systemd:/
|
||||
13:hugetlb:/
|
||||
12:net_prio:/
|
||||
11:perf_event:/
|
||||
10:bfqio:/
|
||||
9:blkio:/
|
||||
8:net_cls:/
|
||||
7:freezer:/
|
||||
6:devices:/
|
||||
5:memory:/
|
||||
4:cpuacct:/
|
||||
3:cpu:/
|
||||
2:cpuset:/
|
||||
`)
|
||||
containerizedProc1Cgroup = []byte(`9:perf_event:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
8:blkio:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
7:net_cls:/
|
||||
6:freezer:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
5:devices:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
4:memory:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
3:cpuacct:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
2:cpu:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
|
||||
1:cpuset:/`)
|
||||
)
|
||||
|
||||
dir := os.TempDir()
|
||||
proc1Cgroup = filepath.Join(dir, "proc1Cgroup")
|
||||
|
||||
defer func() {
|
||||
os.Remove(proc1Cgroup)
|
||||
proc1Cgroup = backup
|
||||
}()
|
||||
|
||||
if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil {
|
||||
t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
|
||||
}
|
||||
inContainer, err := IsContainerized()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if inContainer {
|
||||
t.Fatal("Wrongly assuming containerized")
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroupsystemd226, 0600); err != nil {
|
||||
t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
|
||||
}
|
||||
inContainer, err = IsContainerized()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if inContainer {
|
||||
t.Fatal("Wrongly assuming containerized for systemd /init.scope cgroup layout")
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil {
|
||||
t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
|
||||
}
|
||||
inContainer, err = IsContainerized()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !inContainer {
|
||||
t.Fatal("Wrongly assuming non-containerized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOsReleaseFallback(t *testing.T) {
|
||||
var backup = etcOsRelease
|
||||
var altBackup = altOsRelease
|
||||
dir := os.TempDir()
|
||||
etcOsRelease = filepath.Join(dir, "etcOsRelease")
|
||||
altOsRelease = filepath.Join(dir, "altOsRelease")
|
||||
|
||||
defer func() {
|
||||
os.Remove(dir)
|
||||
etcOsRelease = backup
|
||||
altOsRelease = altBackup
|
||||
}()
|
||||
content := `NAME=Gentoo
|
||||
ID=gentoo
|
||||
PRETTY_NAME="Gentoo/Linux"
|
||||
ANSI_COLOR="1;32"
|
||||
HOME_URL="http://www.gentoo.org/"
|
||||
SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
|
||||
BUG_REPORT_URL="https://bugs.gentoo.org/"
|
||||
`
|
||||
if err := ioutil.WriteFile(altOsRelease, []byte(content), 0600); err != nil {
|
||||
t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
|
||||
}
|
||||
s, err := GetOperatingSystem()
|
||||
if err != nil || s != "Gentoo/Linux" {
|
||||
t.Fatalf("Expected %q, got %q (err: %v)", "Gentoo/Linux", s, err)
|
||||
}
|
||||
}
|
||||
49
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_windows.go
generated
vendored
Normal file
49
vendor/github.com/hyperhq/hypercli/pkg/parsers/operatingsystem/operatingsystem_windows.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package operatingsystem
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// See https://code.google.com/p/go/source/browse/src/pkg/mime/type_windows.go?r=d14520ac25bf6940785aabb71f5be453a286f58c
|
||||
// for a similar sample
|
||||
|
||||
// GetOperatingSystem gets the name of the current operating system.
|
||||
func GetOperatingSystem() (string, error) {
|
||||
|
||||
var h syscall.Handle
|
||||
|
||||
// Default return value
|
||||
ret := "Unknown Operating System"
|
||||
|
||||
if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
|
||||
syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
|
||||
0,
|
||||
syscall.KEY_READ,
|
||||
&h); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
defer syscall.RegCloseKey(h)
|
||||
|
||||
var buf [1 << 10]uint16
|
||||
var typ uint32
|
||||
n := uint32(len(buf) * 2) // api expects array of bytes, not uint16
|
||||
|
||||
if err := syscall.RegQueryValueEx(h,
|
||||
syscall.StringToUTF16Ptr("ProductName"),
|
||||
nil,
|
||||
&typ,
|
||||
(*byte)(unsafe.Pointer(&buf[0])),
|
||||
&n); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
ret = syscall.UTF16ToString(buf[:])
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// IsContainerized returns true if we are running inside a container.
|
||||
// No-op on Windows, always returns false.
|
||||
func IsContainerized() (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
69
vendor/github.com/hyperhq/hypercli/pkg/parsers/parsers.go
generated
vendored
Normal file
69
vendor/github.com/hyperhq/hypercli/pkg/parsers/parsers.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Package parsers provides helper functions to parse and validate different type
|
||||
// of string. It can be hosts, unix addresses, tcp addresses, filters, kernel
|
||||
// operating system versions.
|
||||
package parsers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseKeyValueOpt parses and validates the specified string as a key/value pair (key=value)
|
||||
func ParseKeyValueOpt(opt string) (string, string, error) {
|
||||
parts := strings.SplitN(opt, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt)
|
||||
}
|
||||
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
|
||||
}
|
||||
|
||||
// ParseUintList parses and validates the specified string as the value
|
||||
// found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be
|
||||
// one of the formats below. Note that duplicates are actually allowed in the
|
||||
// input string. It returns a `map[int]bool` with available elements from `val`
|
||||
// set to `true`.
|
||||
// Supported formats:
|
||||
// 7
|
||||
// 1-6
|
||||
// 0,3-4,7,8-10
|
||||
// 0-0,0,1-7
|
||||
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
||||
// 3,2,1
|
||||
// 0-2,3,1
|
||||
func ParseUintList(val string) (map[int]bool, error) {
|
||||
if val == "" {
|
||||
return map[int]bool{}, nil
|
||||
}
|
||||
|
||||
availableInts := make(map[int]bool)
|
||||
split := strings.Split(val, ",")
|
||||
errInvalidFormat := fmt.Errorf("invalid format: %s", val)
|
||||
|
||||
for _, r := range split {
|
||||
if !strings.Contains(r, "-") {
|
||||
v, err := strconv.Atoi(r)
|
||||
if err != nil {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
availableInts[v] = true
|
||||
} else {
|
||||
split := strings.SplitN(r, "-", 2)
|
||||
min, err := strconv.Atoi(split[0])
|
||||
if err != nil {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
max, err := strconv.Atoi(split[1])
|
||||
if err != nil {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
if max < min {
|
||||
return nil, errInvalidFormat
|
||||
}
|
||||
for i := min; i <= max; i++ {
|
||||
availableInts[i] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return availableInts, nil
|
||||
}
|
||||
70
vendor/github.com/hyperhq/hypercli/pkg/parsers/parsers_test.go
generated
vendored
Normal file
70
vendor/github.com/hyperhq/hypercli/pkg/parsers/parsers_test.go
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
package parsers
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseKeyValueOpt(t *testing.T) {
|
||||
invalids := map[string]string{
|
||||
"": "Unable to parse key/value option: ",
|
||||
"key": "Unable to parse key/value option: key",
|
||||
}
|
||||
for invalid, expectedError := range invalids {
|
||||
if _, _, err := ParseKeyValueOpt(invalid); err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected error %v for %v, got %v", expectedError, invalid, err)
|
||||
}
|
||||
}
|
||||
valids := map[string][]string{
|
||||
"key=value": {"key", "value"},
|
||||
" key = value ": {"key", "value"},
|
||||
"key=value1=value2": {"key", "value1=value2"},
|
||||
" key = value1 = value2 ": {"key", "value1 = value2"},
|
||||
}
|
||||
for valid, expectedKeyValue := range valids {
|
||||
key, value, err := ParseKeyValueOpt(valid)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if key != expectedKeyValue[0] || value != expectedKeyValue[1] {
|
||||
t.Fatalf("Expected {%v: %v} got {%v: %v}", expectedKeyValue[0], expectedKeyValue[1], key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseUintList(t *testing.T) {
|
||||
valids := map[string]map[int]bool{
|
||||
"": {},
|
||||
"7": {7: true},
|
||||
"1-6": {1: true, 2: true, 3: true, 4: true, 5: true, 6: true},
|
||||
"0-7": {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true},
|
||||
"0,3-4,7,8-10": {0: true, 3: true, 4: true, 7: true, 8: true, 9: true, 10: true},
|
||||
"0-0,0,1-4": {0: true, 1: true, 2: true, 3: true, 4: true},
|
||||
"03,1-3": {1: true, 2: true, 3: true},
|
||||
"3,2,1": {1: true, 2: true, 3: true},
|
||||
"0-2,3,1": {0: true, 1: true, 2: true, 3: true},
|
||||
}
|
||||
for k, v := range valids {
|
||||
out, err := ParseUintList(k)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected not to fail, got %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(out, v) {
|
||||
t.Fatalf("Expected %v, got %v", v, out)
|
||||
}
|
||||
}
|
||||
|
||||
invalids := []string{
|
||||
"this",
|
||||
"1--",
|
||||
"1-10,,10",
|
||||
"10-1",
|
||||
"-1",
|
||||
"-1,0",
|
||||
}
|
||||
for _, v := range invalids {
|
||||
if out, err := ParseUintList(v); err == nil {
|
||||
t.Fatalf("Expected failure with %s but got %v", v, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user