Run creates and starts a containerd container using the ctr CLI. It uses the configured namespace (default "moby" for Docker-in-Docker environments).
(args ContainerdRunArgs, cmd ...string)
| 620 | // Run creates and starts a containerd container using the ctr CLI. |
| 621 | // It uses the configured namespace (default "moby" for Docker-in-Docker environments). |
| 622 | func (a *containerdActions) Run(args ContainerdRunArgs, cmd ...string) string { |
| 623 | a.seqNum++ |
| 624 | containerName := args.Name |
| 625 | if containerName == "" { |
| 626 | // Generate a unique 64-char hex container ID |
| 627 | // cAdvisor's containerd handler expects container IDs to match this format |
| 628 | // Use timestamp in nanoseconds to ensure uniqueness across test runs |
| 629 | containerName = fmt.Sprintf("%016x%016x%016x%016x", os.Getpid(), a.seqNum, time.Now().UnixNano(), time.Now().UnixNano()%1000000) |
| 630 | } |
| 631 | |
| 632 | // Build the ctr command |
| 633 | // ctr -a <socket> -n <namespace> run -d <image> <container-id> [cmd...] |
| 634 | ctrArgs := []string{ |
| 635 | "ctr", |
| 636 | "--address", a.socket, |
| 637 | "--namespace", a.namespace, |
| 638 | } |
| 639 | |
| 640 | // Pull the image first |
| 641 | klog.Infof("Pulling containerd image %s", args.Image) |
| 642 | pullArgs := append(ctrArgs, "image", "pull", args.Image) |
| 643 | a.fm.Shell().Run("sudo", pullArgs...) |
| 644 | |
| 645 | // Build the run command |
| 646 | // Use the configured snapshotter (from CONTAINERD_SNAPSHOTTER env var, default overlayfs) |
| 647 | runArgs := append(ctrArgs, "run", "-d", "--snapshotter", a.snapshotter) |
| 648 | |
| 649 | // Add labels if specified |
| 650 | for key, value := range args.Labels { |
| 651 | runArgs = append(runArgs, "--label", fmt.Sprintf("%s=%s", key, value)) |
| 652 | } |
| 653 | |
| 654 | // Add the image and container name |
| 655 | runArgs = append(runArgs, args.Image, containerName) |
| 656 | |
| 657 | // Add the command if specified |
| 658 | if len(cmd) > 0 { |
| 659 | runArgs = append(runArgs, cmd...) |
| 660 | } |
| 661 | |
| 662 | klog.Infof("Creating containerd container %s", containerName) |
| 663 | a.fm.Shell().Run("sudo", runArgs...) |
| 664 | |
| 665 | // ctr run returns the container ID (which is the same as the name we provided) |
| 666 | containerID := containerName |
| 667 | |
| 668 | klog.Infof("Created containerd container with ID: %s", containerID) |
| 669 | |
| 670 | // Register cleanup function |
| 671 | // Use RunStress for cleanup commands to avoid test failures when containers have already exited |
| 672 | a.fm.cleanups = append(a.fm.cleanups, func() { |
| 673 | klog.Infof("Cleaning up containerd container %s", containerID) |
| 674 | // Kill the task with SIGKILL to ensure it stops immediately |
| 675 | // Use RunStress so we don't fail if the task has already exited |
| 676 | killArgs := append([]string{"ctr", "--address", a.socket, "--namespace", a.namespace}, |
| 677 | "task", "kill", "--signal", "SIGKILL", containerID) |
| 678 | a.fm.Shell().RunStress("sudo", killArgs...) |
| 679 | // Wait a moment for the task to stop |