diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index e76aeaf3ed..f8c522e571 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -4071,19 +4071,22 @@ func (self *SGuest) Delete(ctx context.Context, userCred mcclient.TokenCredentia return nil } -func (self *SGuest) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error { +func (self *SGuest) CleanTapRecords(ctx context.Context, userCred mcclient.TokenCredential) error { // delete tap devices - if srvs, err := NetTapServiceManager.getTapServicesByGuestId(self.Id, false); err != nil { + if err := NetTapServiceManager.removeTapServicesByGuestId(ctx, userCred, self.Id); err != nil { return errors.Wrap(err, "NetTapServiceManager.getTapServicesByGuestId") - } else { - for _, srv := range srvs { - err := srv.cleanup(ctx, userCred) - if err != nil { - return errors.Wrap(err, "srv.Delete") - } - } } + if err := NetTapFlowManager.removeTapFlowsByGuestId(ctx, userCred, self.Id); err != nil { + return errors.Wrap(err, "NetTapFlowManager.getTapServicesByGuestId") + } + return nil +} +func (self *SGuest) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error { + err := self.CleanTapRecords(ctx, userCred) + if err != nil { + return errors.Wrap(err, "CleanTapRecords") + } return self.SVirtualResourceBase.Delete(ctx, userCred) } diff --git a/pkg/compute/models/host_taps.go b/pkg/compute/models/host_taps.go index 4123a722cf..50d07bdaca 100644 --- a/pkg/compute/models/host_taps.go +++ b/pkg/compute/models/host_taps.go @@ -34,7 +34,11 @@ func (h *SHost) GetDetailsTapConfig(ctx context.Context, userCred mcclient.Token for _, flow := range flows { mirror, err := flow.getMirrorConfig(true) if err != nil { - return conf, errors.Wrap(err, "flow.getMirrorConfig") + if errors.Cause(err) == errors.ErrNotFound { + continue + } else { + return conf, errors.Wrap(err, "flow.getMirrorConfig") + } } mirrors = append(mirrors, mirror) } diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 8726aa1252..530b5e6bcb 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -782,15 +782,11 @@ func (self *SHost) RealDelete(ctx context.Context, userCred mcclient.TokenCreden DeleteResourceJointSchedtags(self, ctx, userCred) // delete tap devices - if srvs, err := NetTapServiceManager.getTapServicesByHostId(self.Id, false); err != nil { + if err := NetTapServiceManager.removeTapServicesByHostId(ctx, userCred, self.Id); err != nil { return errors.Wrap(err, "NetTapServiceManager.getTapServicesByHostId") - } else { - for _, srv := range srvs { - err := srv.cleanup(ctx, userCred) - if err != nil { - return errors.Wrap(err, "srv.Delete") - } - } + } + if err := NetTapFlowManager.removeTapFlowsByHostId(ctx, userCred, self.Id); err != nil { + return errors.Wrap(err, "NetTapFlowManager.getTapFlowsByHostId") } IsolatedDeviceManager.DeleteDevicesByHost(ctx, userCred, self) diff --git a/pkg/compute/models/net_tap_flows.go b/pkg/compute/models/net_tap_flows.go index 5c961c247e..2f1ec77f49 100644 --- a/pkg/compute/models/net_tap_flows.go +++ b/pkg/compute/models/net_tap_flows.go @@ -210,17 +210,25 @@ func (flow *SNetTapFlow) getMoreDetails(ctx context.Context, details api.NetTapF switch flow.Type { case api.TapFlowVSwitch: host := HostManager.FetchHostById(flow.SourceId) - details.Source = host.Name - details.SourceIps = host.AccessIp + if host != nil { + details.Source = host.Name + details.SourceIps = host.AccessIp + } wire := WireManager.FetchWireById(flow.NetId) - details.Net = wire.Name + if wire != nil { + details.Net = wire.Name + } case api.TapFlowGuestNic: guest := GuestManager.FetchGuestById(flow.SourceId) - details.Source = guest.Name - ret := fetchGuestIPs([]string{flow.SourceId}, tristate.False) - details.SourceIps = strings.Join(ret[flow.SourceId], ",") + if guest != nil { + details.Source = guest.Name + ret := fetchGuestIPs([]string{flow.SourceId}, tristate.False) + details.SourceIps = strings.Join(ret[flow.SourceId], ",") + } netObj, _ := NetworkManager.FetchById(flow.NetId) - details.Net = netObj.GetName() + if netObj != nil { + details.Net = netObj.GetName() + } } return details } @@ -432,6 +440,10 @@ func (flow *SNetTapFlow) getMirrorConfig(needTapHostIp bool) (api.SMirrorConfig, wireId = flow.NetId case api.TapFlowGuestNic: guest := GuestManager.FetchGuestById(flow.SourceId) + if guest == nil { + // guest has been deleted? + return ret, errors.Wrap(errors.ErrNotFound, "source not found") + } gn, err := guest.GetGuestnetworkByMac(flow.MacAddr) if err != nil { return ret, errors.Wrap(err, "GetGuestnetworkByMac") @@ -463,3 +475,37 @@ func (flow *SNetTapFlow) getMirrorConfig(needTapHostIp bool) (api.SMirrorConfig, ret.Direction = flow.Direction return ret, nil } + +func (manager *SNetTapFlowManager) removeTapFlowsByGuestId(ctx context.Context, userCred mcclient.TokenCredential, sourceId string) error { + return manager.removeTapFlows(ctx, userCred, api.TapFlowGuestNic, sourceId) +} + +func (manager *SNetTapFlowManager) removeTapFlowsByHostId(ctx context.Context, userCred mcclient.TokenCredential, sourceId string) error { + return manager.removeTapFlows(ctx, userCred, api.TapFlowVSwitch, sourceId) +} + +func (manager *SNetTapFlowManager) removeTapFlows(ctx context.Context, userCred mcclient.TokenCredential, srvType string, targetId string) error { + srvs, err := manager.getTapFlows(srvType, targetId) + if err != nil { + return errors.Wrap(err, "getTapServicesByHostId") + } + for i := range srvs { + err := srvs[i].Delete(ctx, userCred) + if err != nil { + return errors.Wrap(err, "Delete") + } + } + return nil +} + +func (manager *SNetTapFlowManager) getTapFlows(srvType string, sourceId string) ([]SNetTapFlow, error) { + q := manager.Query() + q = q.Equals("type", srvType) + q = q.Equals("source_id", sourceId) + ret := make([]SNetTapFlow, 0) + err := db.FetchModelObjects(manager, q, &ret) + if err != nil { + return nil, errors.Wrap(err, "FetchModelObjects") + } + return ret, nil +} diff --git a/pkg/compute/models/net_tap_services.go b/pkg/compute/models/net_tap_services.go index dfa8170735..466b044a80 100644 --- a/pkg/compute/models/net_tap_services.go +++ b/pkg/compute/models/net_tap_services.go @@ -548,3 +548,25 @@ func (srv *SNetTapService) cleanup(ctx context.Context, userCred mcclient.TokenC } return nil } + +func (manager *SNetTapServiceManager) removeTapServicesByGuestId(ctx context.Context, userCred mcclient.TokenCredential, targetId string) error { + return manager.removeTapServices(ctx, userCred, api.TapServiceGuest, targetId) +} + +func (manager *SNetTapServiceManager) removeTapServicesByHostId(ctx context.Context, userCred mcclient.TokenCredential, targetId string) error { + return manager.removeTapServices(ctx, userCred, api.TapServiceHost, targetId) +} + +func (manager *SNetTapServiceManager) removeTapServices(ctx context.Context, userCred mcclient.TokenCredential, srvType string, targetId string) error { + srvs, err := manager.getTapServices(srvType, targetId, false) + if err != nil { + return errors.Wrap(err, "getTapServicesByHostId") + } + for i := range srvs { + err := srvs[i].cleanup(ctx, userCred) + if err != nil { + return errors.Wrap(err, "cleanup") + } + } + return nil +} diff --git a/pkg/compute/tasks/guest_delete_task.go b/pkg/compute/tasks/guest_delete_task.go index ffa5638cc0..4f6ffd1d8f 100644 --- a/pkg/compute/tasks/guest_delete_task.go +++ b/pkg/compute/tasks/guest_delete_task.go @@ -203,6 +203,9 @@ func (self *GuestDeleteTask) OnSyncConfigComplete(ctx context.Context, obj db.IS // try to leave all groups guest.LeaveAllGroups(ctx, self.UserCred) + // cleanup tap services and flows + guest.CleanTapRecords(ctx, self.UserCred) + isPurge := jsonutils.QueryBoolean(self.Params, "purge", false) overridePendingDelete := jsonutils.QueryBoolean(self.Params, "override_pending_delete", false)