Exemple #1
0
func main() {
	fname := flag.String("from", "", "name of container to clone from or create before cloning")
	bname := flag.String("to", "", "name to use for clone")

	if *fname == "" || *bname == "" {
		log.Println("Unacceptable for names to be empty!")
		return
	}

	var err error

	cl := &lxc.CloneOptions{
		Backend:  lxc.Aufs,
		KeepName: true,
		Snapshot: true,
	}

	tl := &lxc.TemplateOptions{
		Template: "download",
		Distro:   "ubuntu",
		Release:  "trusty",
		Arch:     "amd64",
		Backend:  lxc.Directory,
	}

	c, err := lxc.NewContainer(*fname, lxc.DefaultConfigPath())

	if err != nil {
		log.Printf("Allocating Container %s error %s", *fname, err)
		panic("Unable to get container")
	}

	lxc.Release(c)

	if !c.Defined() {

		err := c.Create(*tl)

		if err != nil {
			log.Printf("Allocating Container %s error %s", *fname, err)
			panic("Unable to create container")
		}
	}

	err = c.Clone(*bname, *cl)

	if err != nil {
		log.Println("Unable to clone", *bname)
		return
	}

	cloned, err := lxc.NewContainer(*bname, lxc.DefaultConfigPath())

	if err != nil {
		log.Println("Unable to locate clone", *bname)
		return
	}

	switch cloned.State() {
	case lxc.FROZEN:
		err = cloned.Unfreeze()
		log.Printf("Container in current State: %+s", cloned.State())
	case lxc.STOPPED:
		err = cloned.Start()
		log.Printf("Container in current State: %+s", cloned.State())
	case lxc.RUNNING:
		log.Printf("Container in current State: %+s", cloned.State())
		return
	default:
		log.Printf("Container in current State: %+s", cloned.State())
		err = fmt.Errorf("Bad controller")
	}

	if err != nil {
		return
	}

	if !cloned.Wait(lxc.RUNNING, 60) {
		log.Printf("Unable to get it running (%+v)", cloned.State())
		return
	}

	// var dest string
	//
	// log.Printf("Begin IP Acquisition process for container")
	//
	// for {
	// 	ip, err := con.IPAddress("eth0")
	//
	// 	if err != nil {
	// 		log.Printf("Waiting for Container (%s) IP to settle", err.Error())
	// 		time.Sleep(time.Millisecond * time.Duration(1000))
	// 		continue
	// 	}
	//
	// 	break
	// }
	//
	cloned.Freeze()

	if !cloned.Wait(lxc.FROZEN, 60) {
		log.Printf("Unable to freeze it (%+s)", *bname)
		return
	}

	var durs int

	fmt.Scan(&durs)

	time.Sleep(time.Duration(durs) * time.Second)

	lxc.Release(cloned)

	time.Sleep(time.Duration(durs) * time.Second)

}
Exemple #2
0
// Start starts the LXC Driver
func (d *LxcDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) {
	var driverConfig LxcDriverConfig
	if err := mapstructure.WeakDecode(task.Config, &driverConfig); err != nil {
		return nil, err
	}
	lxcPath := lxc.DefaultConfigPath()
	if path := d.config.Read("driver.lxc.path"); path != "" {
		lxcPath = path
	}

	containerName := fmt.Sprintf("%s-%s", task.Name, ctx.AllocID)
	c, err := lxc.NewContainer(containerName, lxcPath)
	if err != nil {
		return nil, fmt.Errorf("unable to initialize container: %v", err)
	}

	var verbosity lxc.Verbosity
	switch driverConfig.Verbosity {
	case "verbose":
		verbosity = lxc.Verbose
	case "", "quiet":
		verbosity = lxc.Quiet
	default:
		return nil, fmt.Errorf("lxc driver config 'verbosity' can only be either quiet or verbose")
	}
	c.SetVerbosity(verbosity)

	var logLevel lxc.LogLevel
	switch driverConfig.LogLevel {
	case "trace":
		logLevel = lxc.TRACE
	case "debug":
		logLevel = lxc.DEBUG
	case "info":
		logLevel = lxc.INFO
	case "warn":
		logLevel = lxc.WARN
	case "", "error":
		logLevel = lxc.ERROR
	default:
		return nil, fmt.Errorf("lxc driver config 'log_level' can only be trace, debug, info, warn or error")
	}
	c.SetLogLevel(logLevel)

	logFile := filepath.Join(ctx.AllocDir.LogDir(), fmt.Sprintf("%v-lxc.log", task.Name))
	c.SetLogFile(logFile)

	options := lxc.TemplateOptions{
		Template:             driverConfig.Template,
		Distro:               driverConfig.Distro,
		Release:              driverConfig.Release,
		Arch:                 driverConfig.Arch,
		FlushCache:           driverConfig.FlushCache,
		DisableGPGValidation: driverConfig.DisableGPGValidation,
		ExtraArgs:            driverConfig.TemplateArgs,
	}

	if err := c.Create(options); err != nil {
		return nil, fmt.Errorf("unable to create container: %v", err)
	}

	// Set the network type to none
	if err := c.SetConfigItem("lxc.network.type", "none"); err != nil {
		return nil, fmt.Errorf("error setting network type configuration: %v", err)
	}

	// Bind mount the shared alloc dir and task local dir in the container
	taskDir, ok := ctx.AllocDir.TaskDirs[task.Name]
	if !ok {
		return nil, fmt.Errorf("failed to find task local directory: %v", task.Name)
	}
	secretdir, err := ctx.AllocDir.GetSecretDir(task.Name)
	if err != nil {
		return nil, fmt.Errorf("faild getting secret path for task: %v", err)
	}
	taskLocalDir := filepath.Join(taskDir, allocdir.TaskLocal)
	mounts := []string{
		fmt.Sprintf("%s local none rw,bind,create=dir", taskLocalDir),
		fmt.Sprintf("%s alloc none rw,bind,create=dir", ctx.AllocDir.SharedDir),
		fmt.Sprintf("%s secret none rw,bind,create=dir", secretdir),
	}
	for _, mnt := range mounts {
		if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil {
			return nil, fmt.Errorf("error setting bind mount %q error: %v", mnt, err)
		}
	}

	// Start the container
	if err := c.Start(); err != nil {
		return nil, fmt.Errorf("unable to start container: %v", err)
	}

	// Set the resource limits
	if err := c.SetMemoryLimit(lxc.ByteSize(task.Resources.MemoryMB) * lxc.MB); err != nil {
		return nil, fmt.Errorf("unable to set memory limits: %v", err)
	}
	if err := c.SetCgroupItem("cpu.shares", strconv.Itoa(task.Resources.CPU)); err != nil {
		return nil, fmt.Errorf("unable to set cpu shares: %v", err)
	}

	handle := lxcDriverHandle{
		container:      c,
		initPid:        c.InitPid(),
		lxcPath:        lxcPath,
		logger:         d.logger,
		killTimeout:    GetKillTimeout(task.KillTimeout, d.DriverContext.config.MaxKillTimeout),
		maxKillTimeout: d.DriverContext.config.MaxKillTimeout,
		totalCpuStats:  stats.NewCpuStats(),
		userCpuStats:   stats.NewCpuStats(),
		systemCpuStats: stats.NewCpuStats(),
		waitCh:         make(chan *dstructs.WaitResult, 1),
		doneCh:         make(chan bool, 1),
	}

	go handle.run()

	return &handle, nil
}