diff --git a/pkg/appsrv/appsrv.go b/pkg/appsrv/appsrv.go index 11dc85a35d..bf314abc25 100644 --- a/pkg/appsrv/appsrv.go +++ b/pkg/appsrv/appsrv.go @@ -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) } } diff --git a/pkg/cloudcommon/app.go b/pkg/cloudcommon/app.go index c21dfbdf49..5ed94b973a 100644 --- a/pkg/cloudcommon/app.go +++ b/pkg/cloudcommon/app.go @@ -51,5 +51,4 @@ func ServeForever(app *appsrv.Application, options *CommonOptions) { } else { app.ListenAndServe(addr) } - select {} // for quit handler } diff --git a/pkg/hostman/guestfs/core.go b/pkg/hostman/guestfs/core.go index b576dfbce6..982b50471a 100644 --- a/pkg/hostman/guestfs/core.go +++ b/pkg/hostman/guestfs/core.go @@ -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 diff --git a/pkg/hostman/guestfs/fsdriver/interface.go b/pkg/hostman/guestfs/fsdriver/interface.go index a7006db48a..1224dc1048 100644 --- a/pkg/hostman/guestfs/fsdriver/interface.go +++ b/pkg/hostman/guestfs/fsdriver/interface.go @@ -33,6 +33,7 @@ type IDiskPartition interface { type IRootFsDriver interface { GetPartition() IDiskPartition GetName() string + String() string IsFsCaseInsensitive() bool RootSignatures() []string diff --git a/pkg/hostman/guestfs/fsdriver/linux.go b/pkg/hostman/guestfs/fsdriver/linux.go index 4f11ee9b85..d890477afe 100644 --- a/pkg/hostman/guestfs/fsdriver/linux.go +++ b/pkg/hostman/guestfs/fsdriver/linux.go @@ -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 diff --git a/pkg/hostman/guestfs/fsdriver/windows.go b/pkg/hostman/guestfs/fsdriver/windows.go index fd8347ffb6..55e3275f18 100644 --- a/pkg/hostman/guestfs/fsdriver/windows.go +++ b/pkg/hostman/guestfs/fsdriver/windows.go @@ -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") diff --git a/pkg/hostman/guestfs/kvmpart.go b/pkg/hostman/guestfs/kvmpart.go index afa27ca992..6f990897dd 100644 --- a/pkg/hostman/guestfs/kvmpart.go +++ b/pkg/hostman/guestfs/kvmpart.go @@ -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() diff --git a/pkg/hostman/guestfs/localfs.go b/pkg/hostman/guestfs/localfs.go index 94afa5e31c..6be45b04b4 100644 --- a/pkg/hostman/guestfs/localfs.go +++ b/pkg/hostman/guestfs/localfs.go @@ -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 } diff --git a/pkg/hostman/guesthandlers/guesthandler.go b/pkg/hostman/guesthandlers/guesthandler.go index 54e1c2e582..ffddfc4b33 100644 --- a/pkg/hostman/guesthandlers/guesthandler.go +++ b/pkg/hostman/guesthandlers/guesthandler.go @@ -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[""] - 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) diff --git a/pkg/hostman/guestman/guestman.go b/pkg/hostman/guestman/guestman.go index 2d242621ed..e0eaa1eff0 100644 --- a/pkg/hostman/guestman/guestman.go +++ b/pkg/hostman/guestman/guestman.go @@ -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 { diff --git a/pkg/hostman/host_services.go b/pkg/hostman/host_services.go index 237734a4c2..a14fd1b72a 100644 --- a/pkg/hostman/host_services.go +++ b/pkg/hostman/host_services.go @@ -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) { diff --git a/pkg/hostman/hostinfo/hostbridge/hostbridge.go b/pkg/hostman/hostinfo/hostbridge/hostbridge.go index 91bedb0e0f..a2aded7584 100644 --- a/pkg/hostman/hostinfo/hostbridge/hostbridge.go +++ b/pkg/hostman/hostinfo/hostbridge/hostbridge.go @@ -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() diff --git a/pkg/hostman/hostinfo/hostinfo.go b/pkg/hostman/hostinfo/hostinfo.go index 6fe1e38f37..fdc3b864dc 100644 --- a/pkg/hostman/hostinfo/hostinfo.go +++ b/pkg/hostman/hostinfo/hostinfo.go @@ -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) diff --git a/pkg/hostman/hostinfo/hostinfohelper.go b/pkg/hostman/hostinfo/hostinfohelper.go index 3761b36cf5..04b2686518 100644 --- a/pkg/hostman/hostinfo/hostinfohelper.go +++ b/pkg/hostman/hostinfo/hostinfohelper.go @@ -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) diff --git a/pkg/hostman/monitor/hmp.go b/pkg/hostman/monitor/hmp.go index ea317f36a5..af21ce9d21 100644 --- a/pkg/hostman/monitor/hmp.go +++ b/pkg/hostman/monitor/hmp.go @@ -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 diff --git a/pkg/hostman/storageman/diskbase.go b/pkg/hostman/storageman/diskbase.go index 3885549e8d..bc902741c0 100644 --- a/pkg/hostman/storageman/diskbase.go +++ b/pkg/hostman/storageman/diskbase.go @@ -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 { diff --git a/pkg/hostman/storageman/disklocal.go b/pkg/hostman/storageman/disklocal.go index b0665e3ce9..4fab39f418 100644 --- a/pkg/hostman/storageman/disklocal.go +++ b/pkg/hostman/storageman/disklocal.go @@ -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) } diff --git a/pkg/hostman/storageman/diskutils.go b/pkg/hostman/storageman/diskutils.go index 0117d99c8b..49f4bedc14 100644 --- a/pkg/hostman/storageman/diskutils.go +++ b/pkg/hostman/storageman/diskutils.go @@ -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() } diff --git a/pkg/hostman/storageman/imagecachebase.go b/pkg/hostman/storageman/imagecachebase.go index 6e495f6705..a1800981cd 100644 --- a/pkg/hostman/storageman/imagecachebase.go +++ b/pkg/hostman/storageman/imagecachebase.go @@ -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) } diff --git a/pkg/hostman/storageman/storagebase.go b/pkg/hostman/storageman/storagebase.go index 6bd4522592..d96f601ac2 100644 --- a/pkg/hostman/storageman/storagebase.go +++ b/pkg/hostman/storageman/storagebase.go @@ -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") diff --git a/pkg/hostman/storageman/storagehelper.go b/pkg/hostman/storageman/storagehelper.go index 1bef35d379..7ebc464c01 100644 --- a/pkg/hostman/storageman/storagehelper.go +++ b/pkg/hostman/storageman/storagehelper.go @@ -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 diff --git a/pkg/hostman/storageman/storagelocal.go b/pkg/hostman/storageman/storagelocal.go index ad7f8bec78..90832d7f7d 100644 --- a/pkg/hostman/storageman/storagelocal.go +++ b/pkg/hostman/storageman/storagelocal.go @@ -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()) diff --git a/pkg/mcclient/modules/joint.go b/pkg/mcclient/modules/joint.go index b6438a61c9..4e69e7d10b 100644 --- a/pkg/mcclient/modules/joint.go +++ b/pkg/mcclient/modules/joint.go @@ -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) diff --git a/pkg/util/dhcp/conn.go b/pkg/util/dhcp/conn.go index a9ffa73b9d..44a3930eb2 100644 --- a/pkg/util/dhcp/conn.go +++ b/pkg/util/dhcp/conn.go @@ -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 diff --git a/pkg/util/fileutils2/fileutils.go b/pkg/util/fileutils2/fileutils.go index 841e6d86eb..04bdd938af 100644 --- a/pkg/util/fileutils2/fileutils.go +++ b/pkg/util/fileutils2/fileutils.go @@ -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" || diff --git a/pkg/util/qemuimg/qemuimg.go b/pkg/util/qemuimg/qemuimg.go index ccfdb30c0a..3623c1e066 100644 --- a/pkg/util/qemuimg/qemuimg.go +++ b/pkg/util/qemuimg/qemuimg.go @@ -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 { diff --git a/pkg/util/stringutils2/stringutils.go b/pkg/util/stringutils2/stringutils.go index db4a3f3384..6d75e2b8b3 100644 --- a/pkg/util/stringutils2/stringutils.go +++ b/pkg/util/stringutils2/stringutils.go @@ -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{ diff --git a/pkg/util/winutils/winutils.go b/pkg/util/winutils/winutils.go index dd8b8b74fe..b6da6b74e2 100644 --- a/pkg/util/winutils/winutils.go +++ b/pkg/util/winutils/winutils.go @@ -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 }