116 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"time"
 | 
						|
 | 
						|
	gocontext "context"
 | 
						|
 | 
						|
	"github.com/docker/containerd/api/execution"
 | 
						|
	"github.com/urfave/cli"
 | 
						|
)
 | 
						|
 | 
						|
type runConfig struct {
 | 
						|
	Image   string `toml:"image"`
 | 
						|
	Process struct {
 | 
						|
		Args []string `toml:"args"`
 | 
						|
		Env  []string `toml:"env"`
 | 
						|
		Cwd  string   `toml:"cwd"`
 | 
						|
		Uid  int      `toml:"uid"`
 | 
						|
		Gid  int      `toml:"gid"`
 | 
						|
		Tty  bool     `toml:"tty"`
 | 
						|
	} `toml:"process"`
 | 
						|
	Network struct {
 | 
						|
		Type    string `toml:"type"`
 | 
						|
		IP      string `toml:"ip"`
 | 
						|
		Gateway string `toml:"gateway"`
 | 
						|
	} `toml:"network"`
 | 
						|
}
 | 
						|
 | 
						|
var runCommand = cli.Command{
 | 
						|
	Name:  "run",
 | 
						|
	Usage: "run a container",
 | 
						|
	Flags: []cli.Flag{
 | 
						|
		cli.StringFlag{
 | 
						|
			Name:  "bundle, b",
 | 
						|
			Usage: "path to the container's bundle",
 | 
						|
		},
 | 
						|
		cli.BoolFlag{
 | 
						|
			Name:  "tty, t",
 | 
						|
			Usage: "allocate a TTY for the container",
 | 
						|
		},
 | 
						|
	},
 | 
						|
	Action: func(context *cli.Context) error {
 | 
						|
		// var config runConfig
 | 
						|
		// if _, err := toml.DecodeFile(context.Args().First(), &config); err != nil {
 | 
						|
		// 	return err
 | 
						|
		// }
 | 
						|
		id := context.Args().First()
 | 
						|
		if id == "" {
 | 
						|
			return fmt.Errorf("container id must be provided")
 | 
						|
		}
 | 
						|
		executionService, err := getExecutionService(context)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		tmpDir, err := getTempDir(id)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		defer os.RemoveAll(tmpDir)
 | 
						|
 | 
						|
		crOpts := &execution.CreateContainerRequest{
 | 
						|
			ID:         id,
 | 
						|
			BundlePath: context.String("bundle"),
 | 
						|
			Console:    context.Bool("tty"),
 | 
						|
			Stdin:      filepath.Join(tmpDir, "stdin"),
 | 
						|
			Stdout:     filepath.Join(tmpDir, "stdout"),
 | 
						|
			Stderr:     filepath.Join(tmpDir, "stderr"),
 | 
						|
		}
 | 
						|
 | 
						|
		fwg, err := prepareStdio(crOpts.Stdin, crOpts.Stdout, crOpts.Stderr)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		cr, err := executionService.Create(gocontext.Background(), crOpts)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		if _, err := executionService.Start(gocontext.Background(), &execution.StartContainerRequest{
 | 
						|
			ID: cr.Container.ID,
 | 
						|
		}); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		// wait for it to die
 | 
						|
		for {
 | 
						|
			gcr, err := executionService.Get(gocontext.Background(), &execution.GetContainerRequest{
 | 
						|
				ID: cr.Container.ID,
 | 
						|
			})
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			if gcr.Container.Status != execution.Status_RUNNING {
 | 
						|
				break
 | 
						|
			}
 | 
						|
			time.Sleep(100 * time.Millisecond)
 | 
						|
		}
 | 
						|
 | 
						|
		if _, err := executionService.Delete(gocontext.Background(), &execution.DeleteContainerRequest{
 | 
						|
			ID: cr.Container.ID,
 | 
						|
		}); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		// Ensure we read all io
 | 
						|
		fwg.Wait()
 | 
						|
 | 
						|
		return nil
 | 
						|
	},
 | 
						|
}
 |