Esempio n. 1
0
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)
}
Esempio n. 2
0
func spawnContainers(c *lxd.Client, count int, image string, privileged bool) 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)
	}

	batches := count / batch
	remainder := count % batch

	// Print the test header
	st, err := c.ServerStatus()
	if err != nil {
		return err
	}

	privilegedStr := "unprivileged"
	if privileged {
		privilegedStr = "privileged"
	}

	mode := "normal startup"
	if *argFreeze {
		mode = "start and freeze"
	}

	fmt.Printf("Test environment:\n")
	fmt.Printf("  Server backend: %s\n", st.Environment.Server)
	fmt.Printf("  Server version: %s\n", st.Environment.ServerVersion)
	fmt.Printf("  Kernel: %s\n", st.Environment.Kernel)
	fmt.Printf("  Kernel architecture: %s\n", st.Environment.KernelArchitecture)
	fmt.Printf("  Kernel version: %s\n", st.Environment.KernelVersion)
	fmt.Printf("  Storage backend: %s\n", st.Environment.Storage)
	fmt.Printf("  Storage version: %s\n", st.Environment.StorageVersion)
	fmt.Printf("  Container backend: %s\n", st.Environment.Driver)
	fmt.Printf("  Container version: %s\n", st.Environment.DriverVersion)
	fmt.Printf("\n")
	fmt.Printf("Test variables:\n")
	fmt.Printf("  Container count: %d\n", count)
	fmt.Printf("  Container mode: %s\n", privilegedStr)
	fmt.Printf("  Startup mode: %s\n", mode)
	fmt.Printf("  Image: %s\n", image)
	fmt.Printf("  Batches: %d\n", batches)
	fmt.Printf("  Batch size: %d\n", batch)
	fmt.Printf("  Remainder: %d\n", remainder)
	fmt.Printf("\n")

	// Pre-load the image
	var fingerprint string
	if strings.Contains(image, ":") {
		var remote string
		remote, fingerprint = lxd.DefaultConfig.ParseRemoteAndContainer(image)

		if fingerprint == "" {
			fingerprint = "default"
		}

		d, err := lxd.NewClient(&lxd.DefaultConfig, remote)
		if err != nil {
			return err
		}

		target := d.GetAlias(fingerprint)
		if target != "" {
			fingerprint = target
		}

		_, err = c.GetImageInfo(fingerprint)
		if err != nil {
			logf("Importing image into local store: %s", fingerprint)
			err := d.CopyImage(fingerprint, c, false, nil, false, false, nil)
			if err != nil {
				return err
			}
		} else {
			logf("Found image in local store: %s", fingerprint)
		}
	} else {
		fingerprint = image
		logf("Found image in local store: %s", fingerprint)
	}

	// Start the containers
	spawnedCount := 0
	nameFormat := "benchmark-%." + fmt.Sprintf("%d", len(fmt.Sprintf("%d", count))) + "d"
	wgBatch := sync.WaitGroup{}
	nextStat := batch

	startContainer := func(name string) {
		defer wgBatch.Done()

		// Configure
		config := map[string]string{}
		if privileged {
			config["security.privileged"] = "true"
		}
		config["user.lxd-benchmark"] = "true"

		// Create
		resp, err := c.Init(name, "local", fingerprint, nil, config, nil, false)
		if err != nil {
			logf(fmt.Sprintf("Failed to spawn container '%s': %s", name, err))
			return
		}

		err = c.WaitForSuccess(resp.Operation)
		if err != nil {
			logf(fmt.Sprintf("Failed to spawn container '%s': %s", name, err))
			return
		}

		// Start
		resp, err = c.Action(name, "start", -1, false, false)
		if err != nil {
			logf(fmt.Sprintf("Failed to spawn container '%s': %s", name, err))
			return
		}

		err = c.WaitForSuccess(resp.Operation)
		if err != nil {
			logf(fmt.Sprintf("Failed to spawn container '%s': %s", name, err))
			return
		}

		// Freeze
		if *argFreeze {
			resp, err = c.Action(name, "freeze", -1, false, false)
			if err != nil {
				logf(fmt.Sprintf("Failed to spawn container '%s': %s", name, err))
				return
			}

			err = c.WaitForSuccess(resp.Operation)
			if err != nil {
				logf(fmt.Sprintf("Failed to spawn container '%s': %s", name, err))
				return
			}
		}
	}

	logf("Starting the test")
	timeStart := time.Now()

	for i := 0; i < batches; i++ {
		for j := 0; j < batch; j++ {
			spawnedCount = spawnedCount + 1
			name := fmt.Sprintf(nameFormat, spawnedCount)

			wgBatch.Add(1)
			go startContainer(name)
		}
		wgBatch.Wait()

		if spawnedCount >= nextStat {
			interval := time.Since(timeStart).Seconds()
			logf("Started %d containers in %.3fs (%.3f/s)", spawnedCount, interval, float64(spawnedCount)/interval)
			nextStat = nextStat * 2
		}
	}

	for k := 0; k < remainder; k++ {
		spawnedCount = spawnedCount + 1
		name := fmt.Sprintf(nameFormat, spawnedCount)

		wgBatch.Add(1)
		go startContainer(name)
	}
	wgBatch.Wait()

	logf("Test completed in %.3fs", time.Since(timeStart).Seconds())

	return nil
}
Esempio n. 3
0
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
}
Esempio n. 4
0
func cmdStop(c *lxd.Client, args []string) error {
	var wgBatch sync.WaitGroup

	if os.Getuid() != 0 {
		return fmt.Errorf("Container stop 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)
	}

	// Helper function
	stopContainer := func(name string) {
		defer wgBatch.Done()

		resp, err := c.Action(name, "stop", -1, true, false)
		if err != nil {
			return
		}

		err = c.WaitForSuccess(resp.Operation)
		if err != nil {
			return
		}
	}

	// Stop 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 stopContainer(routers[current].Name)
			current += 1
		}
		wgBatch.Wait()
	}

	for k := 0; k < remainder; k++ {
		wgBatch.Add(1)
		go stopContainer(routers[current].Name)
		current += 1
	}
	wgBatch.Wait()

	// Destroy all the interfaces
	err = networkDestroy(routersMap)
	if err != nil {
		return err
	}

	return nil
}
Esempio n. 5
0
func cmdStart(c *lxd.Client, args []string) error {
	var wgBatch sync.WaitGroup

	if os.Getuid() != 0 {
		return fmt.Errorf("Container startup 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)
	}

	// Create all the needed interfaces
	logf("Creating the network interfaces")
	err = networkCreate(routersMap)
	if err != nil {
		return err
	}

	// Helper function
	startContainer := func(name string) {
		defer wgBatch.Done()

		resp, err := c.Action(name, "start", -1, false, false)
		if err != nil {
			logf("Failed to start container '%s': %s", name, err)
			return
		}

		err = c.WaitForSuccess(resp.Operation)
		if err != nil {
			logf("Failed to start container '%s': %s", name, err)
			return
		}
	}

	// Start the containers
	batch := 8
	batches := len(routers) / batch
	remainder := len(routers) % batch

	logf("Starting the containers")
	current := 0
	for i := 0; i < batches; i++ {
		for j := 0; j < batch; j++ {
			wgBatch.Add(1)
			go startContainer(routers[current].Name)
			current += 1
		}
		wgBatch.Wait()
	}

	for k := 0; k < remainder; k++ {
		wgBatch.Add(1)
		go startContainer(routers[current].Name)
		current += 1
	}
	wgBatch.Wait()
	logf("%d containers started", len(routers))

	return nil
}
Esempio n. 6
0
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
}