func doDelete(d *lxd.Client, name string) error { resp, err := d.Delete(name) if err != nil { return err } return d.WaitForSuccess(resp.Operation) }
func lxdForceDelete(d *lxd.Client, name string) error { resp, err := d.Action(name, "stop", -1, true, false) if err == nil { d.WaitForSuccess(resp.Operation) } resp, err = d.Delete(name) if err != nil { return err } return d.WaitForSuccess(resp.Operation) }
func (c *deleteCmd) doDelete(d *lxd.Client, name string) error { if c.interactive { reader := bufio.NewReader(os.Stdin) fmt.Printf(i18n.G("Remove %s (yes/no): "), name) input, _ := reader.ReadString('\n') input = strings.TrimSuffix(input, "\n") if !shared.StringInSlice(strings.ToLower(input), []string{i18n.G("yes")}) { return fmt.Errorf(i18n.G("User aborted delete operation.")) } } resp, err := d.Delete(name) if err != nil { return err } return d.WaitForSuccess(resp.Operation) }
func deleteContainers(c *lxd.Client) error { batch := *argParallel if batch < 1 { // Detect the number of parallel actions cpus, err := ioutil.ReadDir("/sys/bus/cpu/devices") if err != nil { return err } batch = len(cpus) } // List all the containers allContainers, err := c.ListContainers() if err != nil { return err } containers := []shared.ContainerInfo{} for _, container := range allContainers { if container.Config["user.lxd-benchmark"] != "true" { continue } containers = append(containers, container) } // Delete them all count := len(containers) logf("%d containers to delete", count) batches := count / batch deletedCount := 0 wgBatch := sync.WaitGroup{} nextStat := batch deleteContainer := func(ct shared.ContainerInfo) { defer wgBatch.Done() // Stop if ct.IsActive() { resp, err := c.Action(ct.Name, "stop", -1, true, false) if err != nil { logf("Failed to delete container: %s", ct.Name) return } err = c.WaitForSuccess(resp.Operation) if err != nil { logf("Failed to delete container: %s", ct.Name) return } } // Delete resp, err := c.Delete(ct.Name) if err != nil { logf("Failed to delete container: %s", ct.Name) return } err = c.WaitForSuccess(resp.Operation) if err != nil { logf("Failed to delete container: %s", ct.Name) return } } logf("Starting the cleanup") timeStart := time.Now() for i := 0; i < batches; i++ { for j := 0; j < batch; j++ { wgBatch.Add(1) go deleteContainer(containers[deletedCount]) deletedCount = deletedCount + 1 } wgBatch.Wait() if deletedCount >= nextStat { interval := time.Since(timeStart).Seconds() logf("Deleted %d containers in %.3fs (%.3f/s)", deletedCount, interval, float64(deletedCount)/interval) nextStat = nextStat * 2 } } for k := deletedCount; k < count; k++ { wgBatch.Add(1) go deleteContainer(containers[deletedCount]) deletedCount = deletedCount + 1 } wgBatch.Wait() logf("Cleanup completed") return nil }
func cmdDestroy(c *lxd.Client, args []string) error { var wgBatch sync.WaitGroup if os.Getuid() != 0 { return fmt.Errorf("Container destruction must be run as root.") } // Load the simulation routersMap, err := importFromLXD(c) if err != nil { return err } routers := []*Router{} for _, v := range routersMap { if v.Tier < 1 || v.Tier > 3 { continue } routers = append(routers, v) } // Load the LXD container list containers, err := c.ListContainers() if err != nil { return err } containersMap := map[string]api.Container{} for _, ctn := range containers { containersMap[ctn.Name] = ctn } // Helper function deleteContainer := func(name string) { defer wgBatch.Done() ct, ok := containersMap[name] if !ok { logf("Failed to delete container: %s: Doesn't exist", ct.Name) return } // Stop if ct.IsActive() { resp, err := c.Action(ct.Name, "stop", -1, true, false) if err != nil { logf("Failed to delete container: %s: %s", ct.Name, err) return } err = c.WaitForSuccess(resp.Operation) if err != nil { logf("Failed to delete container: %s: %s", ct.Name, err) return } } // Delete resp, err := c.Delete(ct.Name) if err != nil { logf("Failed to delete container: %s: %s", ct.Name, err) return } err = c.WaitForSuccess(resp.Operation) if err != nil { logf("Failed to delete container: %s: %s", ct.Name, err) return } } // Delete all the containers batch := 8 batches := len(routers) / batch remainder := len(routers) % batch current := 0 for i := 0; i < batches; i++ { for j := 0; j < batch; j++ { wgBatch.Add(1) go deleteContainer(routers[current].Name) current += 1 } wgBatch.Wait() } for k := 0; k < remainder; k++ { wgBatch.Add(1) go deleteContainer(routers[current].Name) current += 1 } wgBatch.Wait() // Destroy all the interfaces err = networkDestroy(routersMap) if err != nil { return err } return nil }