// Sync syncs all ipvs rules present in state to kernel func (ipvs *Ipvs) Sync(state state.State) error { ipvs.Lock() defer ipvs.Unlock() log.Debug("[ipvs] Syncing") stateSet := ipvs.getStateServicesSet(state) currentSet, err := ipvs.getCurrentServicesSet() if err != nil { return err } rulesToAdd := stateSet.Difference(currentSet) rulesToRemove := currentSet.Difference(stateSet) // Adding services and destinations missing for r := range rulesToAdd.Iter() { service := r.(types.Service) dsts := state.GetDestinations(&service) if err := ipvs.addServiceAndDestinations(service, dsts); err != nil { return err } log.Debugf("[ipvs] Added service: %#v with destinations: %#v", service, dsts) } // Cleaning rules for r := range rulesToRemove.Iter() { service := r.(types.Service) err := gipvs.DeleteService(*ToIpvsService(&service)) if err != nil { return err } log.Debugf("[ipvs] Removed service: %#v", service) } // Syncing destination rules for _, s := range state.GetServices() { if err := ipvs.syncDestinations(state, s); err != nil { return err } } return nil }
// IPVSDeleteService deletes the specified service from the IPVS table. func (ncc *SeesawNCC) IPVSDeleteService(svc *ipvs.Service, out *int) error { ipvsMutex.Lock() defer ipvsMutex.Unlock() return ipvs.DeleteService(*svc) }
// testIPVSModification adds, updates and deletes services and destinations // from the test configurations. At each step the service or destination is // retrieved from IPVS and compared against what should be configured. func testIPVSModification() { log.Println("Testing IPVS modifications...") // Make sure we have a clean slate. if err := ipvs.Flush(); err != nil { log.Fatalf("Failed to flush IPVS table: %v\n", err) } for _, test := range ipvsTests { var svc *ipvs.Service var err error testSvc := test.service testDst := test.destinations[0] // Add service. log.Printf("=> Adding service %s\n", testSvc) if err = ipvs.AddService(testSvc); err != nil { log.Fatalf("ipvs.AddService() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) // Add destination. log.Printf("--> Adding destination %s\n", testDst) if err = ipvs.AddDestination(testSvc, testDst); err != nil { log.Fatalf("ipvs.AddDestination() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) compareDst(&testDst, svc.Destinations) // Update service. testSvc.Scheduler = "lc" if err = ipvs.UpdateService(testSvc); err != nil { log.Fatalf("ipvs.UpdateService() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) compareDst(&testDst, svc.Destinations) // Update destination. testDst.Weight = 1000 if err = ipvs.UpdateDestination(testSvc, testDst); err != nil { log.Fatalf("ipvs.UpdateDestination() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) compareDst(&testDst, svc.Destinations) // Delete destination. if err = ipvs.DeleteDestination(testSvc, testDst); err != nil { log.Fatalf("ipvs.DeleteDestination() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } if len(svc.Destinations) != 0 { log.Printf("ERROR: Service still has destinations\n") } // Delete service. if err = ipvs.DeleteService(testSvc); err != nil { log.Fatalf("ipvs.DeleteService() failed: %v\n", err) } // Make sure there is nothing left behind. svcs, err := ipvs.GetServices() if err != nil { log.Fatalf("ipvs.GetServices() failed: %v\n", err) } if len(svcs) != 0 { log.Printf("ERROR: IPVS services still exist!\n") for _, svc = range svcs { log.Printf("=> Got service %s\n", svc) } } } }