mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Feature: host support centos 6 (#406)
This commit is contained in:
committed by
yunion-ci-robot
parent
dfa0285dec
commit
3d4766611c
@@ -1245,9 +1245,9 @@ func fillDiskConfigByImage(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
}
|
||||
diskConfig.ImageId = image.Id
|
||||
diskConfig.ImageProperties = image.Properties
|
||||
if len(diskConfig.Format) == 0 {
|
||||
diskConfig.Format = image.DiskFormat
|
||||
}
|
||||
// if len(diskConfig.Format) == 0 {
|
||||
// diskConfig.Format = image.DiskFormat
|
||||
// }
|
||||
// diskConfig.ImageDiskFormat = image.DiskFormat
|
||||
CachedimageManager.ImageAddRefCount(image.Id)
|
||||
if diskConfig.SizeMb < image.MinDiskMB {
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/ethernet/arp"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/qemutils"
|
||||
"yunion.io/x/onecloud/pkg/util/sysutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -383,8 +384,18 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
|
||||
cpuType = ""
|
||||
if osname == OS_NAME_MACOS {
|
||||
cpuType = "Penryn,vendor=GenuineIntel"
|
||||
} else {
|
||||
} else if options.HostOptions.HostCpuPassthrough {
|
||||
cpuType = "host"
|
||||
} else {
|
||||
cpuType = "qemu64"
|
||||
if sysutils.IsProcessorIntel() {
|
||||
cpuType += ",+vmx"
|
||||
cpuType += ",+ssse3,+sse4.1,+sse4.2,-x2apic,+aes,+avx"
|
||||
cpuType += ",+vme,+pat,+ss,+pclmulqdq,+xsave"
|
||||
cpuType += ",level=13"
|
||||
} else if sysutils.IsProcessorAmd() {
|
||||
cpuType += ",+svm"
|
||||
}
|
||||
}
|
||||
|
||||
if !guestManger.GetHost().IsNestedVirtualization() {
|
||||
|
||||
@@ -51,16 +51,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/winutils"
|
||||
)
|
||||
|
||||
var (
|
||||
KVM_MODULE_INTEL = "kvm-intel"
|
||||
KVM_MODULE_AMD = "kvm-amd"
|
||||
KVM_MODULE_UNSUPPORT = "unsupport"
|
||||
|
||||
HOST_NEST_UNSUPPORT = "0"
|
||||
HOST_NEST_SUPPORT = "1"
|
||||
HOST_NEST_ENABLE = "3"
|
||||
)
|
||||
|
||||
type SHostInfo struct {
|
||||
isRegistered bool
|
||||
IsRegistered chan struct{}
|
||||
@@ -70,9 +60,6 @@ type SHostInfo struct {
|
||||
saved bool
|
||||
pinger *SHostPingTask
|
||||
|
||||
kvmModuleSupport string
|
||||
nestStatus string
|
||||
|
||||
Cpu *SCPUInfo
|
||||
Mem *SMemory
|
||||
sysinfo *SSysInfo
|
||||
@@ -121,10 +108,7 @@ func (h *SHostInfo) GetMediumType() string {
|
||||
}
|
||||
|
||||
func (h *SHostInfo) IsKvmSupport() bool {
|
||||
if h.kvmModuleSupport == KVM_MODULE_UNSUPPORT {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return sysutils.IsKvmSupport()
|
||||
}
|
||||
|
||||
func (h *SHostInfo) IsNestedVirtualization() bool {
|
||||
@@ -290,9 +274,8 @@ func (h *SHostInfo) detectHostInfo() error {
|
||||
}
|
||||
h.sysinfo.SDMISystemInfo = sysinfo
|
||||
|
||||
h.detectiveKVMModuleSupport()
|
||||
h.detectiveNestSupport()
|
||||
h.tryEnableNest()
|
||||
h.detectKvmModuleSupport()
|
||||
h.detectNestSupport()
|
||||
|
||||
if err := h.detectiveSyssoftwareInfo(); err != nil {
|
||||
return err
|
||||
@@ -458,149 +441,18 @@ func (h *SHostInfo) resetIptables() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *SHostInfo) detectiveKVMModuleSupport() {
|
||||
if len(h.kvmModuleSupport) == 0 {
|
||||
h.kvmModuleSupport = h._detectiveKVMModuleSupport()
|
||||
}
|
||||
func (h *SHostInfo) detectKvmModuleSupport() string {
|
||||
return sysutils.GetKVMModuleSupport()
|
||||
}
|
||||
|
||||
func (h *SHostInfo) _detectiveKVMModuleSupport() string {
|
||||
var km = KVM_MODULE_UNSUPPORT
|
||||
if h.modprobeKvmModule(KVM_MODULE_INTEL, false, false) {
|
||||
km = KVM_MODULE_INTEL
|
||||
} else if h.modprobeKvmModule(KVM_MODULE_AMD, false, false) {
|
||||
km = KVM_MODULE_AMD
|
||||
}
|
||||
return km
|
||||
}
|
||||
|
||||
func (h *SHostInfo) modprobeKvmModule(name string, remove, nest bool) bool {
|
||||
var params = []string{"modprobe"}
|
||||
if remove {
|
||||
params = append(params, "-r")
|
||||
}
|
||||
params = append(params, name)
|
||||
if nest {
|
||||
params = append(params, "nested=1")
|
||||
}
|
||||
if _, err := procutils.NewCommand(params[0], params[1:]...).Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *SHostInfo) getKvmModuleSupport() string {
|
||||
if len(h.kvmModuleSupport) == 0 {
|
||||
h.detectiveKVMModuleSupport()
|
||||
}
|
||||
return h.kvmModuleSupport
|
||||
}
|
||||
|
||||
func (h *SHostInfo) detectiveNestSupport() {
|
||||
if len(h.nestStatus) == 0 {
|
||||
h.nestStatus = h._detectiveNestSupport()
|
||||
}
|
||||
h.sysinfo.Nest = h.nestStatus2Str(h.nestStatus)
|
||||
}
|
||||
|
||||
func (h *SHostInfo) _detectiveNestSupport() string {
|
||||
var (
|
||||
moduleName = h.getKvmModuleSupport()
|
||||
nestStatus = HOST_NEST_UNSUPPORT
|
||||
)
|
||||
|
||||
if moduleName != KVM_MODULE_UNSUPPORT && h._isNestSupport(moduleName) {
|
||||
nestStatus = HOST_NEST_SUPPORT
|
||||
}
|
||||
return nestStatus
|
||||
}
|
||||
|
||||
func (h *SHostInfo) _isNestSupport(name string) bool {
|
||||
output, err := procutils.NewCommand("modinfo", name).Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO Test
|
||||
var re = regexp.MustCompile(`parm:\s*nested:`)
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if re.MatchString(line) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *SHostInfo) nestStatus2Str(status string) string {
|
||||
if status == HOST_NEST_ENABLE {
|
||||
return "enabled"
|
||||
func (h *SHostInfo) detectNestSupport() {
|
||||
if sysutils.IsNestEnabled() {
|
||||
h.sysinfo.Nest = "enabled"
|
||||
} else {
|
||||
return "disbaled"
|
||||
h.sysinfo.Nest = "disabled"
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostInfo) tryEnableNest() {
|
||||
if h.nestStatus == HOST_NEST_SUPPORT {
|
||||
if h.loadKvmModuleWithNest(h.kvmModuleSupport) {
|
||||
h.nestStatus = HOST_NEST_ENABLE
|
||||
}
|
||||
}
|
||||
h.sysinfo.Nest = h.nestStatus2Str(h.nestStatus)
|
||||
}
|
||||
|
||||
func (h *SHostInfo) loadKvmModuleWithNest(name string) bool {
|
||||
var notload = true
|
||||
if h.checkKvmModuleInstall(name) {
|
||||
nest := h.getModuleParameter(name, "nested")
|
||||
if nest == "Y" {
|
||||
return true
|
||||
}
|
||||
notload = h.unloadKvmModule(name)
|
||||
}
|
||||
if notload {
|
||||
if h.modprobeKvmModule(name, false, true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *SHostInfo) unloadKvmModule(name string) bool {
|
||||
return h.modprobeKvmModule(name, true, false)
|
||||
}
|
||||
|
||||
func (h *SHostInfo) getModuleParameter(name, moduel string) string {
|
||||
pa := path.Join("/sys/module/", strings.Replace(name, "-", "_", -1), "/parameters/", moduel)
|
||||
if f, err := os.Stat(pa); err == nil {
|
||||
if f.IsDir() {
|
||||
return ""
|
||||
}
|
||||
cont, err := fileutils2.FileGetContents(pa)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(cont)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (h *SHostInfo) checkKvmModuleInstall(name string) bool {
|
||||
output, err := procutils.NewCommand("lsmod").Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return false
|
||||
}
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
lm := strings.Split(line, " ")
|
||||
if len(lm) > 0 && utils.IsInStringArray(strings.Replace(name, "-", "_", -1), lm) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *SHostInfo) detectiveOsDist() {
|
||||
files, err := procutils.NewCommand("sh", "-c", "ls /etc/*elease").Run()
|
||||
if err != nil {
|
||||
@@ -819,7 +671,7 @@ func (h *SHostInfo) getHostInfo(zoneId string) {
|
||||
|
||||
func (h *SHostInfo) setHostname(name string) {
|
||||
h.FullName = name
|
||||
_, err := procutils.NewCommand("hostnamectl", "set-hostname", name).Run()
|
||||
err := sysutils.SetHostname(name)
|
||||
if err != nil {
|
||||
log.Errorln("Fail to set system hostname: %s", err)
|
||||
}
|
||||
@@ -829,8 +681,21 @@ func (h *SHostInfo) fetchHostname() string {
|
||||
if len(options.HostOptions.Hostname) > 0 {
|
||||
return options.HostOptions.Hostname
|
||||
} else {
|
||||
hn, err := os.Hostname()
|
||||
if err != nil {
|
||||
log.Fatalf("fail to get hostname %s", err)
|
||||
return ""
|
||||
}
|
||||
dotIdx := strings.IndexByte(hn, '.')
|
||||
if dotIdx >= 0 {
|
||||
hn = hn[:dotIdx]
|
||||
}
|
||||
hn = strings.ToLower(hn)
|
||||
if len(hn) == 0 {
|
||||
hn = "host"
|
||||
}
|
||||
masterIp := h.GetMasterIp()
|
||||
return "host-" + masterIp
|
||||
return hn + "-" + strings.Replace(masterIp, ".", "-", -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ type SHostOptions struct {
|
||||
|
||||
EnableTelegraf bool `default:"true" help:"enable send monitoring data to telegraf"`
|
||||
WindowsDefaultAdminUser bool `default:"true" help:"Default account for Windows system is Administrator"`
|
||||
|
||||
HostCpuPassthrough bool `default:"true" help:"if it is true, set qemu cpu type as -cpu host, otherwise, qemu64. default is true"`
|
||||
}
|
||||
|
||||
var HostOptions SHostOptions
|
||||
|
||||
@@ -127,7 +127,9 @@ func (c *SLocalImageCacheManager) PrefetchImageCache(ctx context.Context, data i
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
format, _ := body.GetString("format")
|
||||
// format, _ := body.GetString("format")
|
||||
// force qcow2 for KVM
|
||||
format := "qcow2"
|
||||
srcUrl, _ := body.GetString("src_url")
|
||||
|
||||
if imgCache := c.AcquireImage(ctx, imageId, storageManager.GetZone(),
|
||||
|
||||
@@ -25,7 +25,7 @@ type SDocker struct {
|
||||
}
|
||||
|
||||
func NewDockerService() *SDocker {
|
||||
return &SDocker{&SBaseSystemService{"docker", nil}}
|
||||
return &SDocker{NewBaseSystemService("docker", nil)}
|
||||
}
|
||||
|
||||
func (s *SDocker) GetConfig(kwargs map[string]interface{}) string {
|
||||
|
||||
@@ -29,7 +29,7 @@ type SFluentbit struct {
|
||||
}
|
||||
|
||||
func NewFluentbitService() *SFluentbit {
|
||||
return &SFluentbit{&SBaseSystemService{"fluentbit", nil}}
|
||||
return &SFluentbit{NewBaseSystemService("fluentbit", nil)}
|
||||
}
|
||||
|
||||
func (s *SFluentbit) GetConfig(kwargs map[string]interface{}) string {
|
||||
|
||||
@@ -21,7 +21,7 @@ type SKubeAgent struct {
|
||||
}
|
||||
|
||||
func NewKubeAgentService() *SKubeAgent {
|
||||
return &SKubeAgent{&SBaseSystemService{"yunion-kube-agent", nil}}
|
||||
return &SKubeAgent{NewBaseSystemService("yunion-kube-agent", nil)}
|
||||
}
|
||||
|
||||
func (s *SKubeAgent) GetConfig(kwargs map[string]interface{}) string {
|
||||
|
||||
@@ -19,7 +19,7 @@ type SLxcfs struct {
|
||||
}
|
||||
|
||||
func NewLxcfsService() *SLxcfs {
|
||||
return &SLxcfs{&SBaseSystemService{"lxcfs", nil}}
|
||||
return &SLxcfs{NewBaseSystemService("lxcfs", nil)}
|
||||
}
|
||||
|
||||
func (s *SLxcfs) Reload(kwargs map[string]interface{}) error {
|
||||
|
||||
@@ -21,7 +21,7 @@ type SNtpd struct {
|
||||
}
|
||||
|
||||
func NewNtpdService() *SNtpd {
|
||||
return &SNtpd{&SBaseSystemService{"ntpd", nil}}
|
||||
return &SNtpd{NewBaseSystemService("ntpd", nil)}
|
||||
}
|
||||
|
||||
func (s *SNtpd) GetConfig(kwargs map[string]interface{}) string {
|
||||
|
||||
@@ -19,7 +19,7 @@ type SOpenvswitch struct {
|
||||
}
|
||||
|
||||
func NewOpenvswitchService() *SOpenvswitch {
|
||||
return &SOpenvswitch{&SBaseSystemService{"openvswitch", nil}}
|
||||
return &SOpenvswitch{NewBaseSystemService("openvswitch", nil)}
|
||||
}
|
||||
|
||||
func (s *SOpenvswitch) Reload(kwargs map[string]interface{}) error {
|
||||
|
||||
@@ -19,7 +19,7 @@ type SHostSdnagent struct {
|
||||
}
|
||||
|
||||
func NewHostSdnagentService() *SHostSdnagent {
|
||||
return &SHostSdnagent{&SBaseSystemService{"yunion-host-sdnagent", nil}}
|
||||
return &SHostSdnagent{NewBaseSystemService("yunion-host-sdnagent", nil)}
|
||||
}
|
||||
|
||||
func (s *SHostSdnagent) Reload(kwargs map[string]interface{}) error {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package system_service
|
||||
|
||||
type SServiceStatus struct {
|
||||
Loaded bool
|
||||
Active bool
|
||||
}
|
||||
|
||||
type IServiceManager interface {
|
||||
Detect() bool
|
||||
Start(srvname string) error
|
||||
Enable(srvname string) error
|
||||
Stop(srvname string) error
|
||||
Disable(srvname string) error
|
||||
GetStatus(srvname string) SServiceStatus
|
||||
}
|
||||
@@ -15,12 +15,9 @@
|
||||
package system_service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
type ISystemService interface {
|
||||
@@ -34,7 +31,6 @@ type ISystemService interface {
|
||||
BgReload(kwargs map[string]interface{})
|
||||
Enable() error
|
||||
Disable() error
|
||||
GetStatus() map[string]string
|
||||
Reload(kwargs map[string]interface{}) error
|
||||
}
|
||||
|
||||
@@ -60,8 +56,21 @@ func GetService(name string) ISystemService {
|
||||
}
|
||||
|
||||
type SBaseSystemService struct {
|
||||
name string
|
||||
urls interface{}
|
||||
manager IServiceManager
|
||||
name string
|
||||
urls interface{}
|
||||
}
|
||||
|
||||
func NewBaseSystemService(name string, urls interface{}) *SBaseSystemService {
|
||||
ss := SBaseSystemService{}
|
||||
if SysVServiceManager.Detect() {
|
||||
ss.manager = SysVServiceManager
|
||||
} else {
|
||||
ss.manager = SystemdServiceManager
|
||||
}
|
||||
ss.name = name
|
||||
ss.urls = urls
|
||||
return &ss
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) reload(conf, conFile string) error {
|
||||
@@ -81,28 +90,8 @@ func (s *SBaseSystemService) reload(conf, conFile string) error {
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) IsInstalled() bool {
|
||||
status := s.GetStatus()
|
||||
if loaded, ok := status["loaded"]; ok && loaded == "loaded" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) GetStatus() map[string]string {
|
||||
res, _ := procutils.NewCommand("systemctl", "status", s.name).Run()
|
||||
var ret = make(map[string]string, 0)
|
||||
lines := strings.Split(string(res), "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if len(line) > 0 {
|
||||
if strings.HasPrefix(line, "Loaded:") {
|
||||
ret["loaded"] = strings.Split(line, " ")[1]
|
||||
} else if strings.HasPrefix(line, "Active:") {
|
||||
ret["active"] = strings.Split(line, " ")[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
status := s.manager.GetStatus(s.name)
|
||||
return status.Loaded
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) Start(enable bool) error {
|
||||
@@ -111,8 +100,7 @@ func (s *SBaseSystemService) Start(enable bool) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err := procutils.NewCommand("systemctl", "restart", s.name).Run()
|
||||
return err
|
||||
return s.manager.Start(s.name)
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) Stop(disable bool) error {
|
||||
@@ -121,16 +109,12 @@ func (s *SBaseSystemService) Stop(disable bool) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err := procutils.NewCommand("systemctl", "stop", s.name).Run()
|
||||
return err
|
||||
return s.manager.Stop(s.name)
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) IsActive() bool {
|
||||
status := s.GetStatus()
|
||||
if active, ok := status["active"]; ok && active == "active" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
status := s.manager.GetStatus(s.name)
|
||||
return status.Active
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) GetConfig(map[string]interface{}) string {
|
||||
@@ -150,11 +134,9 @@ func (s *SBaseSystemService) GetConf() interface{} {
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) Enable() error {
|
||||
_, err := procutils.NewCommand("systemctl", "enable", s.name).Run()
|
||||
return err
|
||||
return s.manager.Enable(s.name)
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) Disable() error {
|
||||
_, err := procutils.NewCommand("systemctl", "disable", s.name).Run()
|
||||
return err
|
||||
return s.manager.Disable(s.name)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package system_service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
var (
|
||||
SystemdServiceManager IServiceManager = &SSystemdServiceManager{}
|
||||
)
|
||||
|
||||
type SSystemdServiceManager struct {
|
||||
}
|
||||
|
||||
func (manager *SSystemdServiceManager) Detect() bool {
|
||||
_, err := procutils.NewCommand("systemctl", "--version").Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (manager *SSystemdServiceManager) Start(srvname string) error {
|
||||
_, err := procutils.NewCommand("systemctl", "restart", srvname).Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSystemdServiceManager) Enable(srvname string) error {
|
||||
_, err := procutils.NewCommand("systemctl", "enable", srvname).Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSystemdServiceManager) Stop(srvname string) error {
|
||||
_, err := procutils.NewCommand("systemctl", "stop", srvname).Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSystemdServiceManager) Disable(srvname string) error {
|
||||
_, err := procutils.NewCommand("systemctl", "disable", srvname).Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSystemdServiceManager) GetStatus(srvname string) SServiceStatus {
|
||||
res, _ := procutils.NewCommand("systemctl", "status", srvname).Run()
|
||||
return parseSystemdStatus(string(res), srvname)
|
||||
}
|
||||
|
||||
func parseSystemdStatus(res string, srvname string) SServiceStatus {
|
||||
var ret SServiceStatus
|
||||
lines := strings.Split(string(res), "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if len(line) > 0 {
|
||||
if strings.HasPrefix(line, "Loaded:") {
|
||||
parts := strings.Split(line, " ")
|
||||
if len(parts) > 1 && parts[1] == "loaded" {
|
||||
ret.Loaded = true
|
||||
}
|
||||
} else if strings.HasPrefix(line, "Active:") {
|
||||
parts := strings.Split(line, " ")
|
||||
if len(parts) > 1 && parts[1] == "active" {
|
||||
ret.Active = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package system_service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseSystemd(t *testing.T) {
|
||||
cases := []struct {
|
||||
in string
|
||||
name string
|
||||
wantLoaded bool
|
||||
wantActive bool
|
||||
}{
|
||||
{`openvswitch.service - LSB: Open vSwitch switch
|
||||
Loaded: loaded (/etc/rc.d/init.d/openvswitch; bad; vendor preset: disabled)
|
||||
Active: active (running) since Wed 2019-04-10 15:11:23 CST; 4 days ago
|
||||
Docs: man:systemd-sysv-generator(8)
|
||||
Process: 3686 ExecStart=/etc/rc.d/init.d/openvswitch start (code=exited, status=0/SUCCESS)
|
||||
CGroup: /system.slice/openvswitch.service
|
||||
├─3722 ovsdb-server: monitoring pid 3723 (healthy)
|
||||
├─3723 ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsysl...
|
||||
├─3774 ovs-vswitchd: monitoring pid 3775 (healthy)
|
||||
└─3775 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:em...`, "openvswitch", true, true},
|
||||
{"Unit yunion-host.service could not be found.", "yunion-host", false, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
status := parseSystemdStatus(c.in, c.name)
|
||||
if status.Loaded != c.wantLoaded || status.Active != c.wantActive {
|
||||
t.Errorf("parseSystemdStatus %s Loaded: want %v got %v Active: want %v got %v", c.name, c.wantLoaded, status.Loaded, c.wantActive, status.Active)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package system_service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
var (
|
||||
SysVServiceManager IServiceManager = &SSysVServiceManager{}
|
||||
)
|
||||
|
||||
type SSysVServiceManager struct {
|
||||
}
|
||||
|
||||
func (manager *SSysVServiceManager) Detect() bool {
|
||||
_, err := procutils.NewCommand("chkconfig", "--version").Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (manager *SSysVServiceManager) Start(srvname string) error {
|
||||
_, err := procutils.NewCommand("service", srvname, "restart").Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSysVServiceManager) Enable(srvname string) error {
|
||||
_, err := procutils.NewCommand("chkconfig", srvname, "on").Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSysVServiceManager) Stop(srvname string) error {
|
||||
_, err := procutils.NewCommand("service", srvname, "stop").Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSysVServiceManager) Disable(srvname string) error {
|
||||
_, err := procutils.NewCommand("chkconfig", srvname, "off").Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSysVServiceManager) GetStatus(srvname string) SServiceStatus {
|
||||
res, _ := procutils.NewCommand("chkconfig", "--list", srvname).Run()
|
||||
res2, _ := procutils.NewCommand("service", srvname, "status").Run()
|
||||
return parseSysvStatus(string(res), string(res2), srvname)
|
||||
}
|
||||
|
||||
func parseSysvStatus(res string, res2 string, srvname string) SServiceStatus {
|
||||
var ret SServiceStatus
|
||||
lines := strings.Split(res, "\n")
|
||||
for _, line := range lines {
|
||||
parts := strings.Split(strings.TrimSpace(line), "\t")
|
||||
if len(parts) > 1 && strings.TrimSpace(parts[0]) == srvname {
|
||||
ret.Loaded = true
|
||||
if strings.Index(res2, "running") > 0 {
|
||||
ret.Active = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package system_service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseSysv(t *testing.T) {
|
||||
cases := []struct {
|
||||
in1 string
|
||||
in2 string
|
||||
name string
|
||||
wantLoaded bool
|
||||
wantActive bool
|
||||
}{
|
||||
{`openvswitch 0:off 1:off 2:off 3:off 4:off 5:off 6:off`, `ovsdb-server is running with pid 114553
|
||||
ovs-vswitchd is running with pid 114563`, "openvswitch", true, true},
|
||||
{`yunion-host 0:off 1:off 2:on 3:on 4:on 5:on 6:off`, "", "yunion-host", true, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
status := parseSysvStatus(c.in1, c.in2, c.name)
|
||||
if status.Loaded != c.wantLoaded || status.Active != c.wantActive {
|
||||
t.Errorf("parseSysVStatus %s Loaded want %v got %v Active want %v got %v", c.name, c.wantLoaded, status.Loaded, c.wantActive, status.Active)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ type STelegraf struct {
|
||||
}
|
||||
|
||||
func NewTelegrafService() *STelegraf {
|
||||
return &STelegraf{&SBaseSystemService{"telegraf", nil}}
|
||||
return &STelegraf{NewBaseSystemService("telegraf", nil)}
|
||||
}
|
||||
|
||||
func (s *STelegraf) GetConfig(kwargs map[string]interface{}) string {
|
||||
|
||||
@@ -97,6 +97,14 @@ func Zerofiles(sPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func FileSetContents(filename string, content string) error {
|
||||
return FilePutContents(filename, content, false)
|
||||
}
|
||||
|
||||
func FileAppendContents(filename string, content string) error {
|
||||
return FilePutContents(filename, content, true)
|
||||
}
|
||||
|
||||
func FilePutContents(filename string, content string, modAppend bool) error {
|
||||
var mode = os.O_WRONLY | os.O_CREATE
|
||||
if modAppend {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package sysutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
func setHostname7(name string) error {
|
||||
_, err := procutils.NewCommand("hostnamectl", "set-hostname", name).Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func setHostname6(name string) error {
|
||||
_, err := procutils.NewCommand("hostname", name).Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cont := fmt.Sprintf("NETWORKING=yes\nHOSTNAME=%s\n", name)
|
||||
return fileutils2.FileSetContents("/etc/sysconfig/network", cont)
|
||||
}
|
||||
|
||||
func SetHostname(name string) error {
|
||||
err := setHostname7(name)
|
||||
if err != nil {
|
||||
err = setHostname6(name)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package sysutils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
const (
|
||||
KVM_MODULE_INTEL = "kvm-intel"
|
||||
KVM_MODULE_AMD = "kvm-amd"
|
||||
KVM_MODULE_UNSUPPORT = "unsupport"
|
||||
|
||||
HOST_NEST_UNSUPPORT = "0"
|
||||
HOST_NEST_SUPPORT = "1"
|
||||
HOST_NEST_ENABLE = "3"
|
||||
)
|
||||
|
||||
var (
|
||||
kvmModuleSupport string
|
||||
nestStatus string
|
||||
)
|
||||
|
||||
func GetKVMModuleSupport() string {
|
||||
if len(kvmModuleSupport) == 0 {
|
||||
kvmModuleSupport = detectiveKVMModuleSupport()
|
||||
}
|
||||
return kvmModuleSupport
|
||||
}
|
||||
|
||||
func IsKvmSupport() bool {
|
||||
GetKVMModuleSupport()
|
||||
if kvmModuleSupport == KVM_MODULE_UNSUPPORT {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsProcessorIntel() bool {
|
||||
GetKVMModuleSupport()
|
||||
if kvmModuleSupport == KVM_MODULE_INTEL {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsProcessorAmd() bool {
|
||||
GetKVMModuleSupport()
|
||||
if kvmModuleSupport == KVM_MODULE_AMD {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func detectiveKVMModuleSupport() string {
|
||||
var km = KVM_MODULE_UNSUPPORT
|
||||
if ModprobeKvmModule(KVM_MODULE_INTEL, false, false) {
|
||||
km = KVM_MODULE_INTEL
|
||||
} else if ModprobeKvmModule(KVM_MODULE_AMD, false, false) {
|
||||
km = KVM_MODULE_AMD
|
||||
}
|
||||
return km
|
||||
}
|
||||
|
||||
func ModprobeKvmModule(name string, remove, nest bool) bool {
|
||||
var params = []string{"modprobe"}
|
||||
if remove {
|
||||
params = append(params, "-r")
|
||||
}
|
||||
params = append(params, name)
|
||||
if nest {
|
||||
params = append(params, "nested=1")
|
||||
}
|
||||
if _, err := procutils.NewCommand(params[0], params[1:]...).Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsNestEnabled() bool {
|
||||
return GetNestSupport() == HOST_NEST_ENABLE
|
||||
}
|
||||
|
||||
func GetNestSupport() string {
|
||||
if len(nestStatus) == 0 {
|
||||
nestStatus = detectNestSupport()
|
||||
}
|
||||
return nestStatus
|
||||
}
|
||||
|
||||
func detectNestSupport() string {
|
||||
moduleName := GetKVMModuleSupport()
|
||||
nestStatus := HOST_NEST_UNSUPPORT
|
||||
|
||||
if moduleName != KVM_MODULE_UNSUPPORT && isNestSupport(moduleName) {
|
||||
nestStatus = HOST_NEST_SUPPORT
|
||||
}
|
||||
|
||||
if nestStatus == HOST_NEST_SUPPORT && loadKvmModuleWithNest(moduleName) {
|
||||
nestStatus = HOST_NEST_ENABLE
|
||||
}
|
||||
return nestStatus
|
||||
}
|
||||
|
||||
func isNestSupport(name string) bool {
|
||||
output, err := procutils.NewCommand("modinfo", name).Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO Test
|
||||
var re = regexp.MustCompile(`parm:\s*nested:`)
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if re.MatchString(line) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func loadKvmModuleWithNest(name string) bool {
|
||||
var notload = true
|
||||
if IsKernelModuleLoaded(name) {
|
||||
nest := GetKernelModuleParameter(name, "nested")
|
||||
if nest == "Y" {
|
||||
return true
|
||||
}
|
||||
notload = unloadKvmModule(name)
|
||||
}
|
||||
if notload {
|
||||
if ModprobeKvmModule(name, false, true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func unloadKvmModule(name string) bool {
|
||||
return ModprobeKvmModule(name, true, false)
|
||||
}
|
||||
|
||||
func GetKernelModuleParameter(name, moduel string) string {
|
||||
pa := path.Join("/sys/module/", strings.Replace(name, "-", "_", -1), "/parameters/", moduel)
|
||||
if f, err := os.Stat(pa); err == nil {
|
||||
if f.IsDir() {
|
||||
return ""
|
||||
}
|
||||
cont, err := fileutils2.FileGetContents(pa)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(cont)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func IsKernelModuleLoaded(name string) bool {
|
||||
output, err := procutils.NewCommand("lsmod").Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return false
|
||||
}
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
lm := strings.Split(line, " ")
|
||||
if len(lm) > 0 && utils.IsInStringArray(strings.Replace(name, "-", "_", -1), lm) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user