Merge pull request #1047 in YUNIONIO/onecloud from ~WANYAOQI/onecloud:feature/wyq/host-server-v2 to release/2.6.0

* commit '3eb7c2900ec29e5b8fa2d1f1def6d469ce003de0':
  fix code
  fs driver fix
This commit is contained in:
万垚奇
2019-02-14 20:31:00 +08:00
28 changed files with 200 additions and 60 deletions
+2 -1
View File
@@ -332,7 +332,8 @@ func (app *Application) ListenAndServe(addr string) {
app.server = app.initServer(addr)
err := app.server.ListenAndServe()
if err != nil {
log.Infof("ListAndServer: %s", err)
log.Errorf("ListAndServer: %s", err)
panic(err)
}
}
-1
View File
@@ -51,5 +51,4 @@ func ServeForever(app *appsrv.Application, options *CommonOptions) {
} else {
app.ListenAndServe(addr)
}
select {} // for quit handler
}
+1 -1
View File
@@ -220,7 +220,7 @@ func DeployGuestFs(
func IsPartitionReadonly(rootfs fsdriver.IDiskPartition) bool {
log.Infof("Test if read-only fs ...")
var filename = fmt.Sprintf("./%f", rand.Float32())
var filename = fmt.Sprintf("/.%f", rand.Float32())
if err := rootfs.FilePutContents(filename, fmt.Sprintf("%f", rand.Float32()), false, false); err == nil {
rootfs.Remove(filename, false)
return false
@@ -33,6 +33,7 @@ type IDiskPartition interface {
type IRootFsDriver interface {
GetPartition() IDiskPartition
GetName() string
String() string
IsFsCaseInsensitive() bool
RootSignatures() []string
+28
View File
@@ -513,6 +513,10 @@ func NewDebianRootFs(part IDiskPartition) IRootFsDriver {
return driver
}
func (d *SDebianRootFs) String() string {
return "DebianRootFs"
}
func (d *SDebianRootFs) GetName() string {
return "Debian"
}
@@ -556,6 +560,10 @@ func (d *SCirrosRootFs) GetName() string {
return "Cirros"
}
func (d *SCirrosRootFs) String() string {
return "CirrosRootFs"
}
func (d *SCirrosRootFs) DistroName() string {
return d.GetName()
}
@@ -586,6 +594,10 @@ func (d *SCirrosNewRootFs) GetName() string {
return "Cirros"
}
func (d *SCirrosNewRootFs) String() string {
return "CirrosNewRootFs"
}
func (d *SCirrosNewRootFs) DistroName() string {
return d.GetName()
}
@@ -621,6 +633,10 @@ func (d *SUbuntuRootFs) GetName() string {
return "Ubuntu"
}
func (d *SUbuntuRootFs) String() string {
return "UbuntuRootFs"
}
func (d *SUbuntuRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo {
distroKey := "DISTRIB_RELEASE="
rel, err := rootFs.FileGetContents("/etc/lsb-release", false)
@@ -833,6 +849,10 @@ func NewCentosRootFs(part IDiskPartition) IRootFsDriver {
return &SCentosRootFs{sRedhatLikeRootFs: newRedhatLikeRootFs(part)}
}
func (c *SCentosRootFs) String() string {
return "CentosRootFs"
}
func (c *SCentosRootFs) GetName() string {
return "CentOS"
}
@@ -884,6 +904,10 @@ func NewFedoraRootFs(part IDiskPartition) IRootFsDriver {
return &SFedoraRootFs{sRedhatLikeRootFs: newRedhatLikeRootFs(part)}
}
func (c *SFedoraRootFs) String() string {
return "FedoraRootFs"
}
func (c *SFedoraRootFs) GetName() string {
return "Fedora"
}
@@ -921,6 +945,10 @@ func (d *SRhelRootFs) GetName() string {
return "RHEL"
}
func (d *SRhelRootFs) String() string {
return "RhelRootFs"
}
func (d *SRhelRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo {
rel, _ := rootFs.FileGetContents("/etc/redhat-release", false)
var version string
+9 -6
View File
@@ -1,7 +1,6 @@
package fsdriver
import (
"crypto/md5"
"fmt"
"math/rand"
"path"
@@ -17,6 +16,7 @@ import (
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/seclib2"
"yunion.io/x/onecloud/pkg/util/stringutils2"
"yunion.io/x/onecloud/pkg/util/version"
"yunion.io/x/onecloud/pkg/util/winutils"
"yunion.io/x/pkg/utils"
@@ -57,6 +57,10 @@ func (w *SWindowsRootFs) GetName() string {
return "Windows"
}
func (w *SWindowsRootFs) String() string {
return "WindowsRootFs"
}
func (w *SWindowsRootFs) DeployPublicKey(IDiskPartition, string, *sshkeys.SSHKeys) error {
return nil
}
@@ -88,6 +92,7 @@ func (w *SWindowsRootFs) GetReleaseInfo(IDiskPartition) *SReleaseInfo {
func (w *SWindowsRootFs) GetLoginAccount(rootFs IDiskPartition, defaultRootUser bool, windowsDefaultAdminUser bool) string {
confPath := w.rootFs.GetLocalPath("/windows/system32/config", true)
tool := winutils.NewWinRegTool(confPath)
tool.CheckPath()
users := tool.GetUsers()
admin := "Administrator"
selUsr := ""
@@ -120,7 +125,6 @@ func (w *SWindowsRootFs) IsWindows10() bool {
return true
}
return false
}
func (w *SWindowsRootFs) GetOs() string {
@@ -152,7 +156,6 @@ func (w *SWindowsRootFs) putGuestScriptContents(spath, content string) error {
}
content = strings.Join(contentArr, "\r\n")
return w.rootFs.FilePutContents(spath, content, false, true)
}
@@ -366,7 +369,7 @@ func (w *SWindowsRootFs) deployPublicKeyByGuest(uname, passwd string) bool {
}, "\r\n")
w.prependGuestBootScript(bootScript)
logPath := w.guestDebugLogPath
chksum := md5.Sum([]byte(passwd + logPath[(len(logPath)-10):]))
chksum := stringutils2.GetMD5Hash(passwd + logPath[(len(logPath)-10):])
chgpwdScript := strings.Join([]string{
w.MakeGuestDebugCmd("change password step 1"),
@@ -411,8 +414,8 @@ func (w *SWindowsRootFs) deploySetupCompleteScripts(uname, passwd string) bool {
{"IncludeRecommendedUpdates", "REG_DWORD", "0"},
{"EnableFeaturedSoftware", "REG_DWORD", "1"},
} {
cmds = append(cmds, `REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v %s /t %s /d %s /f`,
v[0], v[1], v[2])
cmds = append(cmds, fmt.Sprintf(`REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v %s /t %s /d %s /f`,
v[0], v[1], v[2]))
}
cmds = append(cmds, "Net start wuauserv")
cmds = append(cmds, "wuauclt /detectnow")
+1 -1
View File
@@ -51,8 +51,8 @@ func (p *SKVMGuestDiskPartition) Mount() bool {
err = p.mount(false)
if err != nil {
log.Errorf("SKVMGuestDiskPartition mount error: %s", err)
return false
}
if p.IsReadonly() {
log.Errorf("SKVMGuestDiskPartition %s is readonly, try mount as ro", p.partDev)
p.Umount()
+4 -4
View File
@@ -32,10 +32,10 @@ func (f *SLocalGuestFS) GetLocalPath(sPath string, caseInsensitive bool) string
files, _ := ioutil.ReadDir(fullPath)
for _, file := range files {
var f = file.Name()
if f == seg || (caseInsensitive && (strings.ToLower(f)) == strings.ToLower(seg)) ||
(seg[len(seg)-1] == '*' && strings.HasPrefix(f, seg[:len(seg)-1])) ||
(caseInsensitive && strings.HasPrefix(strings.ToLower(f),
strings.ToLower(seg[:]))) {
if f == seg || (caseInsensitive && strings.ToLower(f) == strings.ToLower(seg)) ||
(seg[len(seg)-1] == '*' && (strings.HasPrefix(f, seg[:len(seg)-1]) ||
(caseInsensitive && strings.HasPrefix(strings.ToLower(f),
strings.ToLower(seg[:len(seg)-1]))))) {
realSeg = f
break
}
+4 -1
View File
@@ -102,7 +102,10 @@ func cpusetBalance(ctx context.Context, w http.ResponseWriter, r *http.Request)
func deleteGuest(ctx context.Context, w http.ResponseWriter, r *http.Request) {
params, _, body := appsrv.FetchEnv(ctx, w, r)
var sid = params["<sid>"]
var migrated = jsonutils.QueryBoolean(body, "migrated", false)
var migrated bool
if body != nil {
migrated = jsonutils.QueryBoolean(body, "migrated", false)
}
guest, err := guestman.GetGuestManager().Delete(sid)
if err != nil {
hostutils.Response(ctx, w, err)
+2 -1
View File
@@ -75,6 +75,7 @@ func (m *SGuestManager) VerifyExistingGuests(pendingDelete bool) {
params.Set("admin", jsonutils.JSONTrue)
params.Set("system", jsonutils.JSONTrue)
params.Set("pending_delete", jsonutils.NewBool(pendingDelete))
params.Set("get_backup_guests_on_host", jsonutils.JSONTrue)
params.Set("filter.0", jsonutils.NewString(
fmt.Sprintf("host_id.equals(%s)", m.host.GetHostId())))
if len(m.CandidateServers) > 0 {
@@ -84,7 +85,7 @@ func (m *SGuestManager) VerifyExistingGuests(pendingDelete bool) {
keys[index] = k
index++
}
params.Set("filter.1", jsonutils.NewString(strings.Join(keys, ",")))
params.Set("filter.1", jsonutils.NewString(fmt.Sprintf("id.in(%s)", strings.Join(keys, ","))))
}
res, err := modules.Servers.List(hostutils.GetComputeSession(context.Background()), params)
if err != nil {
+14 -1
View File
@@ -82,7 +82,20 @@ func (host *SHostService) StartService() {
cronManager.AddJob2(
"CleanRecycleDiskFiles", 1, 3, 0, 0, storageman.CleanRecycleDiskfiles, false)
cloudcommon.ServeForever(app, &options.HostOptions.CommonOptions)
go func() {
defer func() {
if r := recover(); r != nil {
if !host.isExiting {
log.Fatalf("%s", r)
} else {
log.Errorln(r)
}
}
}()
cloudcommon.ServeForever(app, &options.HostOptions.CommonOptions)
}()
select {} // for quit handler
}
func (host *SHostService) initHandlers(app *appsrv.Application) {
@@ -239,6 +239,11 @@ func (o *SOVSBridgeDriver) Setup() error {
}
}
if o.inter != nil && !utils.IsInStringArray(o.inter.String(), o.Interfaces()) {
if err := o.SetupInterface(); err != nil {
return err
}
}
if len(o.bridge.Addr) == 0 {
if len(o.ip) > 0 {
if err := o.SetupAddresses(o.inter.Mask); err != nil {
@@ -264,6 +269,17 @@ func (o *SOVSBridgeDriver) Setup() error {
return o.BringupInterface()
}
func (o *SOVSBridgeDriver) SetupInterface() error {
if o.inter != nil && !utils.IsInStringArray(o.inter.String(), o.Interfaces()) {
output, err := procutils.NewCommand("ovs-vsctl", "--", "--may-exist",
"add-port", o.bridge.String(), o.inter.String()).Run()
if err != nil {
return fmt.Errorf("Failed to add interface %s", output)
}
}
return nil
}
func (o *SOVSBridgeDriver) SetupBridgeDev() error {
if !o.Exists() {
_, err := procutils.NewCommand("ovs-vsctl", "--", "--may-exist", "add-br", o.bridge.String()).Run()
+2
View File
@@ -722,6 +722,7 @@ func (h *SHostInfo) fetchAccessNetworkInfo() {
}
params := jsonutils.NewDict()
params.Set("ip", jsonutils.NewString(masterIp))
params.Set("is_private", jsonutils.JSONTrue)
params.Set("limit", jsonutils.NewInt(0))
wire, err := hostutils.GetWireOfIp(context.Background(), params)
if err != nil {
@@ -958,6 +959,7 @@ func (h *SHostInfo) uploadNetworkInfo() {
if len(nic.Network) == 0 {
kwargs := jsonutils.NewDict()
kwargs.Set("ip", jsonutils.NewString(nic.Ip))
kwargs.Set("is_private", jsonutils.JSONTrue)
kwargs.Set("limit", jsonutils.NewInt(0))
wireInfo, err := hostutils.GetWireOfIp(context.Background(), kwargs)
+1 -1
View File
@@ -298,7 +298,7 @@ func StartDetachStorages(hs []jsonutils.JSONObject) {
storageId, _ := hs[0].GetString("storage_id")
_, err := modules.Hoststorages.Detach(
hostutils.GetComputeSession(context.Background()),
hostId, storageId)
hostId, storageId, nil)
if err != nil {
log.Errorf("Host %s detach storage %s failed: %s",
hostId, storageId, err)
+1 -1
View File
@@ -275,7 +275,7 @@ func (m *HmpMonitor) Migrate(
cmd := "migrate -d"
if copyIncremental {
cmd += " -i"
} else if copyIncremental {
} else if copyFull {
cmd += " -b"
}
cmd += " " + destStr
+6 -3
View File
@@ -91,12 +91,15 @@ func (d *SBaseDisk) DeployGuestFs(diskPath string, guestDesc *jsonutils.JSONDict
defer kvmDisk.Disconnect()
log.Infof("Kvm Disk Connect Success !!")
if root := kvmDisk.Mount(); root != nil {
defer kvmDisk.Umount(root)
if root := kvmDisk.MountKvmRootfs(); root != nil {
defer kvmDisk.UmountKvmRootfs(root)
return guestfs.DeployGuestFs(root, guestDesc, deployInfo)
} else {
return nil, fmt.Errorf("Kvm Disk Mount error")
}
} else {
return nil, fmt.Errorf("Kvm disk connecterror")
}
return nil, fmt.Errorf("Kvm disk connect or mount error")
}
func (d *SBaseDisk) GetDiskSetupScripts(diskIndex int) string {
+16 -1
View File
@@ -174,6 +174,21 @@ func (d *SLocalDisk) CreateFromImageFuse(ctx context.Context, url string) error
}
func (d *SLocalDisk) CreateFromTemplate(ctx context.Context, imageId, format string, size int64) (jsonutils.JSONObject, error) {
ret, err := d.createFromTemplate(ctx, imageId, format)
if err != nil {
return nil, err
}
retSize, _ := ret.Int("disk_size")
log.Infof("REQSIZE: %d, RETSIZE: %d", size, retSize)
if size > retSize {
params := jsonutils.NewDict()
params.Set("size", jsonutils.NewInt(size))
return d.Resize(ctx, params)
}
return ret, nil
}
func (d *SLocalDisk) createFromTemplate(ctx context.Context, imageId, format string) (jsonutils.JSONObject, error) {
var imageCacheManager = storageManager.LocalStorageImagecacheManager
imageCache := imageCacheManager.AcquireImage(ctx, imageId, d.GetZone(), "", "")
if imageCache != nil {
@@ -193,7 +208,7 @@ func (d *SLocalDisk) CreateFromTemplate(ctx context.Context, imageId, format str
log.Errorln(err)
return nil, err
}
if err := newImg.CreateQcow2(int(size), false, cacheImagePath); err != nil {
if err := newImg.CreateQcow2(0, false, cacheImagePath); err != nil {
log.Errorln(err)
return nil, fmt.Errorf("Fail to create disk %s", d.Id)
}
+7 -2
View File
@@ -96,6 +96,11 @@ func (d *SKVMGuestDisk) findPartitions() error {
d.partitions = append(d.partitions, part)
}
}
// XXX: HACK reverse partitions
for i, j := 0, len(d.partitions)-1; i < j; i, j = i+1, j-1 {
d.partitions[i], d.partitions[j] = d.partitions[j], d.partitions[i]
}
return nil
}
@@ -121,7 +126,7 @@ func (d *SKVMGuestDisk) Disconnect() bool {
}
}
func (d *SKVMGuestDisk) Mount() fsdriver.IRootFsDriver {
func (d *SKVMGuestDisk) MountKvmRootfs() fsdriver.IRootFsDriver {
for i := 0; i < len(d.partitions); i++ {
if d.partitions[i].Mount() {
if fs := guestfs.DetectRootFs(d.partitions[i]); fs != nil {
@@ -135,7 +140,7 @@ func (d *SKVMGuestDisk) Mount() fsdriver.IRootFsDriver {
return nil
}
func (d *SKVMGuestDisk) Umount(fd fsdriver.IRootFsDriver) {
func (d *SKVMGuestDisk) UmountKvmRootfs(fd fsdriver.IRootFsDriver) {
if part := fd.GetPartition(); part != nil {
part.Umount()
}
+1 -1
View File
@@ -241,7 +241,7 @@ func (l *SLocalImageCache) Remove(ctx context.Context) error {
go func() {
_, err := modules.Storagecachedimages.Detach(hostutils.GetComputeSession(ctx),
l.Manager.GetId(), l.imageId)
l.Manager.GetId(), l.imageId, nil)
if err != nil {
log.Errorf("Fail to delete host cached image: %s", err)
}
+3
View File
@@ -168,10 +168,13 @@ func (s *SBaseStorage) CreateDiskByDiskinfo(ctx context.Context, params interfac
switch {
case createParams.DiskInfo.Contains("snapshot"):
log.Infof("CreateDiskFromSnpashot %s", createParams)
return s.CreateDiskFromSnpashot(ctx, disk, createParams)
case createParams.DiskInfo.Contains("image_id"):
log.Infof("CreateDiskFromTemplate %s", createParams)
return s.CreateDiskFromTemplate(ctx, disk, createParams)
case createParams.DiskInfo.Contains("size"):
log.Infof("CreateRawDisk %s", createParams)
return s.CreateRawDisk(ctx, disk, createParams)
default:
return nil, fmt.Errorf("Not fount")
+9 -1
View File
@@ -1,6 +1,10 @@
package storageman
import "yunion.io/x/jsonutils"
import (
"fmt"
"yunion.io/x/jsonutils"
)
type SDiskCreateByDiskinfo struct {
DiskId string
@@ -10,6 +14,10 @@ type SDiskCreateByDiskinfo struct {
Storage IStorage
}
func (i *SDiskCreateByDiskinfo) String() string {
return fmt.Sprintf("disk_id: %s, disk_info: %s", i.DiskId, i.DiskInfo)
}
type SDiskReset struct {
SnapshotId string
OutOfChain bool
+2 -2
View File
@@ -212,8 +212,8 @@ func (s *SLocalStorage) saveToGlance(ctx context.Context, imageId, imagePath str
if kvmDisk.Connect() {
defer kvmDisk.Disconnect()
if root := kvmDisk.Mount(); root != nil {
defer kvmDisk.Umount(root)
if root := kvmDisk.MountKvmRootfs(); root != nil {
defer kvmDisk.UmountKvmRootfs(root)
osInfo = root.GetOs()
relInfo = root.GetReleaseInfo(root.GetPartition())
+1 -1
View File
@@ -150,7 +150,7 @@ func (this *JointResourceManager) Update(s *mcclient.ClientSession, mid, sid str
if query != nil {
queryStr := query.QueryString()
if len(queryStr) > 0 {
path = fmt.Sprint("%s?%s", path, queryStr)
path = fmt.Sprintf("%s?%s", path, queryStr)
}
}
result, err := this._put(s, path, this.params2Body(s, params), this.Keyword)
+16 -18
View File
@@ -141,25 +141,23 @@ func (c *Conn) Close() error {
// packet and the interface it was received on.
func (c *Conn) RecvDHCP() (Packet, *net.UDPAddr, *net.Interface, error) {
var buf [1500]byte
for {
b, addr, _, err := c.conn.Recv(buf[:])
if err != nil {
return nil, nil, nil, err
}
/*if c.ifIndex != 0 && ifidx != c.ifIndex {
log.Errorf("======= ifIndex continue, c.ifIndex: %d, ifidx: %d", c.ifIndex, ifidx)
continue
}*/
pkt := Unmarshal(b)
// intf, err := net.InterfaceByIndex(ifidx)
// if err != nil {
// return nil, nil, nil, err
// }
// TODO: possibly more validation that the source lines up
// with what the packet says.
return pkt, addr, nil, nil
b, addr, _, err := c.conn.Recv(buf[:])
if err != nil {
return nil, nil, nil, err
}
/*if c.ifIndex != 0 && ifidx != c.ifIndex {
log.Errorf("======= ifIndex continue, c.ifIndex: %d, ifidx: %d", c.ifIndex, ifidx)
continue
}*/
pkt := Unmarshal(b)
// intf, err := net.InterfaceByIndex(ifidx)
// if err != nil {
// return nil, nil, nil, err
// }
// TODO: possibly more validation that the source lines up
// with what the packet says.
return pkt, addr, nil, nil
}
// SendDHCP sends pkt. The precise transmission mechanism depends
+9 -1
View File
@@ -12,6 +12,7 @@ import (
"regexp"
"strconv"
"strings"
"syscall"
"golang.org/x/sys/unix"
@@ -446,7 +447,14 @@ func ResizeDiskFs(diskPath string, sizeMb int) error {
log.Infof("gdisk: %s %s", stdoutPut, stderrOutPut)
if err = proc.Wait(); err != nil {
log.Errorln(err)
return err
if exiterr, ok := err.(*exec.ExitError); ok {
ws := exiterr.Sys().(syscall.WaitStatus)
if ws.ExitStatus() != 1 {
return err
}
} else {
return err
}
}
}
if len(parts) > 0 && (label == "gpt" ||
+1
View File
@@ -366,6 +366,7 @@ func (img *SQemuImage) create(sizeMB int, format TImageFormat, options []string)
if sizeMB > 0 {
args = append(args, fmt.Sprintf("%dM", sizeMB))
}
log.Debugf("%s %s", qemutils.GetQemuImg(), args)
cmd := exec.Command(qemutils.GetQemuImg(), args...)
err := cmd.Run()
if err != nil {
+8
View File
@@ -1,10 +1,18 @@
package stringutils2
import (
"crypto/md5"
"encoding/hex"
"fmt"
"strings"
)
func GetMD5Hash(text string) string {
hasher := md5.New()
hasher.Write([]byte(text))
return hex.EncodeToString(hasher.Sum(nil))
}
func EscapeString(str string, pairs [][]string) string {
if len(pairs) == 0 {
pairs = [][]string{
+35 -11
View File
@@ -11,6 +11,7 @@ import (
"strconv"
"strings"
"syscall"
"time"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/util/fileutils2"
@@ -147,8 +148,17 @@ func (w *SWinRegTool) samChange(user string, seq ...string) error {
return err
}
log.Debugf("Sam change %s %s", stdoutPut, stderrOutPut)
if proc.ProcessState.Exited() {
if err := proc.Wait(); err != nil {
done := make(chan error, 1)
go func() {
done <- proc.Wait()
}()
select {
case <-time.After(time.Millisecond * 100):
proc.Process.Kill()
return fmt.Errorf("Failed to change SAM password, not exit cleanly")
case err := <-done:
if err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
ws := exiterr.Sys().(syscall.WaitStatus)
if ws.ExitStatus() == 2 {
@@ -160,9 +170,6 @@ func (w *SWinRegTool) samChange(user string, seq ...string) error {
} else {
return nil
}
} else {
proc.Process.Kill()
return fmt.Errorf("Failed to change SAM password, not exit cleanly")
}
}
@@ -179,7 +186,7 @@ func (w *SWinRegTool) UnlockUser(user string) error {
}
func (w *SWinRegTool) GetRegFile(regPath string) (string, []string) {
re := regexp.MustCompile("\\")
re := regexp.MustCompile(`\\`)
vals := re.Split(regPath, -1)
regSeg := []string{}
for _, val := range vals {
@@ -232,8 +239,19 @@ func (w *SWinRegTool) showRegistry(spath string, keySeg []string, verb string) (
if err != nil {
return nil, err
}
if !proc.ProcessState.Exited() {
time.Sleep(time.Millisecond * 100)
done := make(chan error, 1)
go func() {
done <- proc.Wait()
}()
select {
case <-time.After(time.Millisecond * 100):
proc.Process.Kill()
case err := <-done:
if err != nil {
return nil, err
}
}
return strings.Split(string(stdoutPut), "\n"), nil
}
@@ -329,8 +347,16 @@ func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode int) bool
return false
}
log.Debugf("Cmd registry %s %s", stdoutPut, stderrOutPut)
if proc.ProcessState.Exited() {
if err := proc.Wait(); err != nil {
done := make(chan error, 1)
go func() {
done <- proc.Wait()
}()
select {
case <-time.After(time.Millisecond * 100):
proc.Process.Kill()
case err := <-done:
if err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
ws := exiterr.Sys().(syscall.WaitStatus)
if ws.ExitStatus() == retcode {
@@ -340,8 +366,6 @@ func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode int) bool
} else {
return retcode == 0
}
} else {
proc.Process.Kill()
}
return false
}