package domain import ( "context" "encoding/json" "encoding/xml" "fmt" "log" "strings" "deevirt.fr/compute/pkg/amqp" "deevirt.fr/compute/pkg/api/proto" "deevirt.fr/compute/pkg/schema" deevirt_schema "deevirt.fr/compute/pkg/schema/deevirt" "libvirt.org/go/libvirt" ) type EventsDetail map[string]string func (d *Domain) domainEventLifecycle(nodeId string, domainId string, state int64, event *libvirt.DomainEventLifecycle) { d.Logger.Sugar().Infof("%s => %s: Evènement %v", nodeId, domainId, event) domStore := deevirt_schema.DomainStore{} domData, err := d.Store.Get(fmt.Sprintf("/etc/libvirt/domain/%s", domainId)) if err != nil || len(domData) == 0 { d.Logger.Sugar().Errorf("Critique !!, la VM %s n'existe pas ou comporte une erreur importante !", domainId) } json.Unmarshal(domData, &domStore) switch event.Event { case libvirt.DOMAIN_EVENT_DEFINED: // Changement de noeud ! oldNodeId := strings.Clone(domStore.NodeId) dom2node, _ := json.Marshal(deevirt_schema.DomainToNodeStore{ State: int(state), }) d.Store.Set(fmt.Sprintf("/etc/libvirt/domain/qemu/%s/%s", nodeId, domainId), dom2node) domStore.NodeId = nodeId dom2store, _ := json.Marshal(domStore) d.Store.Set(fmt.Sprintf("/etc/libvirt/domain/%s", domainId), dom2store) println(oldNodeId) d.Store.Delete(fmt.Sprintf("/etc/libvirt/domain/qemu/%s/%s", oldNodeId, domainId)) case libvirt.DOMAIN_EVENT_STARTED: switch event.Detail { case int(libvirt.DOMAIN_EVENT_STARTED_MIGRATED): // On ne fait rien, migration en cours return } case libvirt.DOMAIN_EVENT_SUSPENDED: switch event.Detail { case int(libvirt.DOMAIN_EVENT_SUSPENDED_MIGRATED): // On ne fait rien, migration en cours return } case libvirt.DOMAIN_EVENT_RESUMED: switch event.Detail { case int(libvirt.DOMAIN_EVENT_RESUMED_MIGRATED): // On ne fait rien, migration en cours return } } // MAJ de l'état nodeData, _ := d.Store.Get(fmt.Sprintf("/etc/libvirt/qemu/%s/%s", nodeId, domainId)) domNodeData := deevirt_schema.DomainToNodeStore{} json.Unmarshal(nodeData, &domNodeData) domNodeData.State = int(state) dom2node, _ := json.Marshal(domNodeData) d.Store.Set(fmt.Sprintf("/etc/libvirt/domain/qemu/%s/%s", nodeId, domainId), dom2node) // AMQP - On envoi l'évènement brut e, _ := json.Marshal(struct { Type string State int }{ Type: "DomainState", State: int(state), }) desc := schema.Domain{} err = xml.Unmarshal([]byte(domStore.Config), &desc) if err != nil { log.Fatalln(err) } a, _ := amqp.NewAMQP() a.Publisher("vmcenter", "events."+desc.Metadata.DeevirtInstance.DeevirtCompanyID+ "."+desc.Metadata.DeevirtInstance.DeevirtDatacenterID+ "."+domainId, e) defer a.Close() } func (d *Domain) Event(ctx context.Context, req *proto.DomainEventRequest) (*proto.DomainEventResponse, error) { switch req.Type { case "DomainEventLifecycle": event := libvirt.DomainEventLifecycle{} if json.Unmarshal(req.Event, &event) == nil { d.domainEventLifecycle(req.NodeId, req.DomainId, req.State, &event) } } /*events := Events{ NodeID: req.DomainId, DomainID: req.DomainId, Event: e, }*/ /*var events Events err := json.Unmarshal(req.Event, &events) if err != nil { fmt.Println("Erreur lors du décodage JSON:", err) } var edetail EventsDetail if events.Event.Event == "MIGRATION" { err = json.Unmarshal([]byte(events.Event.Details), &edetail) if err != nil { fmt.Println("Erreur lors du décodage JSON:", err) } if edetail["status"] == "setup" { r, _ := d.Store.Get(fmt.Sprintf("/etc/libvirt/qemu/%s/%s", events.NodeID, events.DomainID)) if r != nil { var j raft.DomainStore json.Unmarshal(r, &j) j.Migrate = true new, _ := json.Marshal(j) d.Store.Set(fmt.Sprintf("/etc/libvirt/qemu/%s/%s", events.NodeID, events.DomainID), new) } else { new, _ := json.Marshal(raft.DomainStore{ Config: string(events.Config), State: events.State, Migrate: false, }) d.Store.Set(fmt.Sprintf("/etc/libvirt/qemu/%s/%s", events.NodeID, events.DomainID), new) } fmt.Printf("%s => %v\n", events.NodeID, edetail) } else if edetail["status"] == "completed" { r, _ := d.Store.Get(fmt.Sprintf("/etc/libvirt/qemu/%s/%s", events.NodeID, events.DomainID)) if r != nil { var j raft.DomainStore json.Unmarshal(r, &j) if j.Migrate { d.Store.Delete(fmt.Sprintf("/etc/libvirt/qemu/%s/%s", events.NodeID, events.DomainID)) } } fmt.Printf("%s => %v\n", events.NodeID, edetail) } } // AMQP - On envoi l'évènement brut /*e, _ := json.Marshal(events.Event) a, _ := amqp.NewAMQP() a.Publisher("vmcenter", "events."+events.CompanyID+ "."+events.DatacenterID+ "."+events.DomainID, e) defer a.Close()*/ return &proto.DomainEventResponse{}, nil }