func (c *Cluster) CreateContainerPullOptsSchedulerOpts(opts docker.CreateContainerOptions, pullOpts docker.PullImageOptions, pullAuth docker.AuthConfiguration, schedulerOpts SchedulerOptions, nodes ...string) (string, *docker.Container, error) {
	var (
		addr      string
		container *docker.Container
		err       error
	)
	useScheduler := len(nodes) == 0
	maxTries := 5
	for ; maxTries > 0; maxTries-- {
		if opts.Context != nil {
			select {
			case <-opts.Context.Done():
				return "", nil, opts.Context.Err()
			default:
			}
		}
		if useScheduler {
			node, scheduleErr := c.scheduler.Schedule(c, &opts, schedulerOpts)
			if scheduleErr != nil {
				if err != nil {
					scheduleErr = fmt.Errorf("Error in scheduler after previous errors (%s) trying to create container: %s", err.Error(), scheduleErr.Error())
				}
				return addr, nil, scheduleErr
			}
			addr = node.Address
		} else {
			addr = nodes[rand.Intn(len(nodes))]
		}
		if addr == "" {
			return addr, nil, errors.New("CreateContainer needs a non empty node addr")
		}
		err = c.runHookForAddr(HookEventBeforeContainerCreate, addr)
		if err != nil {
			log.Errorf("Error in before create container hook in node %q: %s. Trying again in another node...", addr, err)
		}
		if err == nil {
			container, err = c.createContainerInNode(opts, pullOpts, pullAuth, addr)
			if err == nil {
				c.handleNodeSuccess(addr)
				break
			}
			log.Errorf("Error trying to create container in node %q: %s. Trying again in another node...", addr, err.Error())
		}
		shouldIncrementFailures := false
		isCreateContainerErr := false
		baseErr := err
		if nodeErr, ok := baseErr.(DockerNodeError); ok {
			isCreateContainerErr = nodeErr.cmd == "createContainer"
			baseErr = nodeErr.BaseError()
		}
		if urlErr, ok := baseErr.(*url.Error); ok {
			baseErr = urlErr.Err
		}
		_, isNetErr := baseErr.(net.Error)
		if isNetErr || isCreateContainerErr || baseErr == docker.ErrConnectionRefused {
			shouldIncrementFailures = true
		}
		c.handleNodeError(addr, err, shouldIncrementFailures)
		if !useScheduler {
			return addr, nil, err
		}
	}
	if err != nil {
		return addr, nil, fmt.Errorf("CreateContainer: maximum number of tries exceeded, last error: %s", err.Error())
	}
	err = c.storage().StoreContainer(container.ID, addr)
	return addr, container, err
}
Similar to CreateContainer but allows arbritary options to be passed to
the scheduler and to the pull image call.
package cluster
import (
	"errors"
	"fmt"
	"math/rand"
	"net"
	"net/url"
	"sync"
	"time"
	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/docker-cluster/log"
)
type Container struct {
	Id   string `bson:"_id"`
	Host string
}
func (c *Cluster) CreateContainer(opts docker.CreateContainerOptions, inactivityTimeout time.Duration, nodes ...string) (string, *docker.Container, error) {
	return c.CreateContainerSchedulerOpts(opts, nil, inactivityTimeout, nodes...)
}
func (c *Cluster) CreateContainerSchedulerOpts(opts docker.CreateContainerOptions, schedulerOpts SchedulerOptions, inactivityTimeout time.Duration, nodes ...string) (string, *docker.Container, error) {
	return c.CreateContainerPullOptsSchedulerOpts(opts, docker.PullImageOptions{
		Repository:        opts.Config.Image,
		InactivityTimeout: inactivityTimeout,
		Context:           opts.Context,
	}, docker.AuthConfiguration{}, schedulerOpts, nodes...)
}