Example #1
0
func (b *Builder) run() error {
	// create and run the container
	conf := docker.Config{
		Image:        b.image.ID,
		AttachStdin:  false,
		AttachStdout: true,
		AttachStderr: true,
	}

	// configure if Docker should run in privileged mode
	host := docker.HostConfig{
		Privileged: (b.Privileged && len(b.Repo.PR) == 0),
	}

	// debugging
	log.Noticef("starting build %s", b.Build.Name)

	// link service containers
	for i, service := range b.services {
		// convert name of the image to a slug
		_, name, _ := parseImageName(b.Build.Services[i])

		// link the service container to our
		// build container.
		host.Links = append(host.Links, service.Name[1:]+":"+name)
	}

	// where are temp files going to go?
	tmpPath := "/tmp/drone"
	if len(os.Getenv("DRONE_TMP")) > 0 {
		tmpPath = os.Getenv("DRONE_TMP")
	}

	log.Infof("temp directory is %s", tmpPath)

	if err := os.MkdirAll(tmpPath, 0777); err != nil {
		return fmt.Errorf("Failed to create temp directory at %s: %s", tmpPath, err)
	}

	// link cached volumes
	conf.Volumes = make(map[string]struct{})
	for _, volume := range b.Build.Cache {
		name := filepath.Clean(b.Repo.Name)
		branch := filepath.Clean(b.Repo.Branch)
		volume := filepath.Clean(volume)

		// with Docker, volumes must be an absolute path. If an absolute
		// path is not provided, then assume it is for the repository
		// working directory.
		if strings.HasPrefix(volume, "/") == false {
			volume = filepath.Join(b.Repo.Dir, volume)
		}

		// local cache path on the host machine
		// this path is going to be really long
		hostpath := filepath.Join(tmpPath, name, branch, volume)

		// check if the volume is created
		if _, err := os.Stat(hostpath); err != nil {
			// if does not exist then create
			os.MkdirAll(hostpath, 0777)
		}

		host.Binds = append(host.Binds, hostpath+":"+volume)
		conf.Volumes[volume] = struct{}{}

		// debugging
		log.Infof("mounting volume %s:%s", hostpath, volume)
	}

	// create the container from the image
	run, err := b.dockerClient.Containers.Create(&conf)
	if err != nil {
		return err
	}

	// cache instance of docker.Run
	b.container = run

	// attach to the container
	go func() {
		b.dockerClient.Containers.Attach(run.ID, &writer{b.Stdout})
	}()

	// start the container
	if err := b.dockerClient.Containers.Start(run.ID, &host); err != nil {
		b.BuildState.ExitCode = 1
		b.BuildState.Finished = time.Now().UTC().Unix()
		return err
	}

	// wait for the container to stop
	wait, err := b.dockerClient.Containers.Wait(run.ID)
	if err != nil {
		b.BuildState.ExitCode = 1
		b.BuildState.Finished = time.Now().UTC().Unix()
		return err
	}

	// set completion time
	b.BuildState.Finished = time.Now().UTC().Unix()

	// get the exit code if possible
	b.BuildState.ExitCode = wait.StatusCode

	return nil
}
Example #2
0
func (b *Builder) run() error {
	// create and run the container
	conf := docker.Config{
		Image:        b.image.ID,
		AttachStdin:  false,
		AttachStdout: true,
		AttachStderr: true,
	}
	host := docker.HostConfig{
		Privileged: false,
	}

	// debugging
	log.Noticef("starting build %s", b.Build.Name)

	// link service containers
	for i, service := range b.services {
		image, ok := services[b.Build.Services[i]]
		if !ok {
			continue // THIS SHOULD NEVER HAPPEN
		}
		// link the service container to our
		// build container.
		host.Links = append(host.Links, service.Name[1:]+":"+image.Name)
	}

	// link cached volumes
	conf.Volumes = make(map[string]struct{})
	for _, volume := range b.Build.Cache {
		name := filepath.Clean(b.Repo.Name)
		branch := filepath.Clean(b.Repo.Branch)
		volume := filepath.Clean(volume)

		// with Docker, volumes must be an absolute path. If an absolute
		// path is not provided, then assume it is for the repository
		// working directory.
		if strings.HasPrefix(volume, "/") == false {
			volume = filepath.Join(b.Repo.Dir, volume)
		}

		// local cache path on the host machine
		// this path is going to be really long
		hostpath := filepath.Join("/tmp/drone", name, branch, volume)

		// check if the volume is created
		if _, err := os.Stat(hostpath); err != nil {
			// if does not exist then create
			os.MkdirAll(hostpath, 0777)
		}

		host.Binds = append(host.Binds, hostpath+":"+volume)
		conf.Volumes[volume] = struct{}{}

		// debugging
		log.Infof("mounting volume %s:%s", hostpath, volume)
	}

	// create the container from the image
	run, err := b.dockerClient.Containers.Create(&conf)
	if err != nil {
		return err
	}

	// cache instance of docker.Run
	b.container = run

	// attach to the container
	go func() {
		b.dockerClient.Containers.Attach(run.ID, &writer{b.Stdout})
	}()

	// start the container
	if err := b.dockerClient.Containers.Start(run.ID, &host); err != nil {
		b.BuildState.ExitCode = 1
		b.BuildState.Finished = time.Now().UTC().Unix()
		return err
	}

	// wait for the container to stop
	wait, err := b.dockerClient.Containers.Wait(run.ID)
	if err != nil {
		b.BuildState.ExitCode = 1
		b.BuildState.Finished = time.Now().UTC().Unix()
		return err
	}

	// set completion time
	b.BuildState.Finished = time.Now().UTC().Unix()

	// get the exit code if possible
	b.BuildState.ExitCode = wait.StatusCode

	return nil
}