Example #1
0
func setupBaseImage() {
	eng, err := engine.New(unitTestStoreBase)
	if err != nil {
		log.Fatalf("Can't initialize engine at %s: %s", unitTestStoreBase, err)
	}
	job := eng.Job("initserver")
	job.Setenv("Root", unitTestStoreBase)
	job.SetenvBool("Autorestart", false)
	job.Setenv("BridgeIface", unitTestNetworkBridge)
	if err := job.Run(); err != nil {
		log.Fatalf("Unable to create a runtime for tests: %s", err)
	}

	job = eng.Job("inspect", unitTestImageName, "image")
	img, _ := job.Stdout.AddEnv()
	// If the unit test is not found, try to download it.
	if err := job.Run(); err != nil || img.Get("id") != unitTestImageID {
		// Retrieve the Image
		job = eng.Job("pull", unitTestImageName)
		job.Stdout.Add(utils.NopWriteCloser(os.Stdout))
		if err := job.Run(); err != nil {
			log.Fatalf("Unable to pull the test image: %s", err)
		}
	}
}
Example #2
0
// Job creates a new job which can later be executed.
// This function mimics `Command` from the standard os/exec package.
func (eng *Engine) Job(name string, args ...string) *Job {
	job := &Job{
		Eng:    eng,
		Name:   name,
		Args:   args,
		Stdin:  NewInput(),
		Stdout: NewOutput(),
		Stderr: NewOutput(),
		env:    &Env{},
	}
	job.Stderr.Add(utils.NopWriteCloser(eng.Stderr))
	handler, exists := eng.handlers[name]
	if exists {
		job.handler = handler
	}
	return job
}
Example #3
0
// Register makes a container object usable by the runtime as <container.ID>
func (runtime *Runtime) Register(container *Container) error {
	if container.runtime != nil || runtime.Exists(container.ID) {
		return fmt.Errorf("Container is already loaded")
	}
	if err := validateID(container.ID); err != nil {
		return err
	}
	if err := runtime.ensureName(container); err != nil {
		return err
	}

	// Get the root filesystem from the driver
	basefs, err := runtime.driver.Get(container.ID)
	if err != nil {
		return fmt.Errorf("Error getting container filesystem %s from driver %s: %s", container.ID, runtime.driver, err)
	}
	defer runtime.driver.Put(container.ID)
	container.basefs = basefs

	container.runtime = runtime

	// Attach to stdout and stderr
	container.stderr = utils.NewWriteBroadcaster()
	container.stdout = utils.NewWriteBroadcaster()
	// Attach to stdin
	if container.Config.OpenStdin {
		container.stdin, container.stdinPipe = io.Pipe()
	} else {
		container.stdinPipe = utils.NopWriteCloser(ioutil.Discard) // Silently drop stdin
	}
	// done
	runtime.containers.PushBack(container)
	runtime.idIndex.Add(container.ID)

	// FIXME: if the container is supposed to be running but is not, auto restart it?
	//        if so, then we need to restart monitor and init a new lock
	// If the container is supposed to be running, make sure of it
	if container.State.IsRunning() {
		info := runtime.execDriver.Info(container.ID)

		if !info.IsRunning() {
			utils.Debugf("Container %s was supposed to be running but is not.", container.ID)
			if runtime.config.AutoRestart {
				utils.Debugf("Restarting")
				container.State.SetGhost(false)
				container.State.SetStopped(0)
				if err := container.Start(); err != nil {
					return err
				}
			} else {
				utils.Debugf("Marking as stopped")
				container.State.SetStopped(-127)
				if err := container.ToDisk(); err != nil {
					return err
				}
			}
		} else {
			utils.Debugf("Reconnecting to container %v", container.ID)

			if err := container.allocateNetwork(); err != nil {
				return err
			}

			container.waitLock = make(chan struct{})
			go container.monitor(nil)
		}
	} else {
		// When the container is not running, we still initialize the waitLock
		// chan and close it. Receiving on nil chan blocks whereas receiving on a
		// closed chan does not. In this case we do not want to block.
		container.waitLock = make(chan struct{})
		close(container.waitLock)
	}
	return nil
}