예제 #1
0
func (p *dockerProvisioner) UploadDeploy(app provision.App, archiveFile io.ReadCloser, w io.Writer) (string, error) {
	defer archiveFile.Close()
	filePath := "/home/application/archive.tar.gz"
	user, err := config.GetString("docker:user")
	if err != nil {
		user, _ = config.GetString("docker:ssh:user")
	}
	options := docker.CreateContainerOptions{
		Config: &docker.Config{
			AttachStdout: true,
			AttachStderr: true,
			AttachStdin:  true,
			OpenStdin:    true,
			StdinOnce:    true,
			User:         user,
			Image:        p.getBuildImage(app),
			Cmd:          []string{"/bin/bash", "-c", "cat > " + filePath},
		},
	}
	cluster := p.Cluster()
	_, cont, err := cluster.CreateContainerSchedulerOpts(options, []string{app.GetName(), ""})
	if err != nil {
		return "", err
	}
	defer cluster.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})
	err = cluster.StartContainer(cont.ID, nil)
	if err != nil {
		return "", err
	}
	var output bytes.Buffer
	opts := docker.AttachToContainerOptions{
		Container:    cont.ID,
		OutputStream: &output,
		ErrorStream:  &output,
		InputStream:  archiveFile,
		Stream:       true,
		Stdin:        true,
		Stdout:       true,
		Stderr:       true,
	}
	status, err := container.SafeAttachWaitContainer(p, opts)
	if err != nil {
		return "", err
	}
	if status != 0 {
		log.Errorf("Failed to deploy container from upload: %s", &output)
		return "", fmt.Errorf("container exited with status %d", status)
	}
	image, err := cluster.CommitContainer(docker.CommitContainerOptions{Container: cont.ID})
	if err != nil {
		return "", err
	}
	imageId, err := p.archiveDeploy(app, image.ID, "file://"+filePath, w)
	if err != nil {
		return "", err
	}
	return imageId, p.deployAndClean(app, imageId, w)
}
예제 #2
0
func (p *dockerProvisioner) UploadDeploy(app provision.App, archiveFile io.ReadCloser, w io.Writer) (string, error) {
	defer archiveFile.Close()
	dirPath := "/home/application/"
	filePath := fmt.Sprintf("%sarchive.tar.gz", dirPath)
	user, err := config.GetString("docker:user")
	if err != nil {
		user, _ = config.GetString("docker:ssh:user")
	}
	options := docker.CreateContainerOptions{
		Config: &docker.Config{
			AttachStdout: true,
			AttachStderr: true,
			AttachStdin:  true,
			OpenStdin:    true,
			StdinOnce:    true,
			User:         user,
			Image:        p.getBuildImage(app),
			Cmd:          []string{"/bin/bash", "-c", "tail -f /dev/null"},
		},
	}
	cluster := p.Cluster()
	_, cont, err := cluster.CreateContainerSchedulerOpts(options, []string{app.GetName(), ""})
	if err != nil {
		return "", err
	}
	defer cluster.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})
	err = cluster.StartContainer(cont.ID, nil)
	if err != nil {
		return "", err
	}
	var buf bytes.Buffer
	var archiveFileBuf bytes.Buffer
	tarball := tar.NewWriter(&buf)
	if err != nil {
		return "", err
	}
	n, err := archiveFileBuf.ReadFrom(archiveFile)
	if err != nil {
		return "", err
	}
	header := tar.Header{
		Name: "archive.tar.gz",
		Mode: 0666,
		Size: n,
	}
	tarball.WriteHeader(&header)
	archiveReader := bytes.NewReader(archiveFileBuf.Bytes())
	_, err = io.Copy(&buf, archiveReader)
	if err != nil {
		return "", err
	}
	defer tarball.Close()
	uploadOpts := docker.UploadToContainerOptions{
		InputStream: &buf,
		Path:        dirPath,
	}
	err = cluster.UploadToContainer(cont.ID, uploadOpts)
	if err != nil {
		return "", err
	}
	err = cluster.StopContainer(cont.ID, 10)
	if err != nil {
		return "", err
	}
	image, err := cluster.CommitContainer(docker.CommitContainerOptions{Container: cont.ID})
	if err != nil {
		return "", err
	}
	imageId, err := p.archiveDeploy(app, image.ID, "file://"+filePath, w)
	if err != nil {
		return "", err
	}
	return imageId, p.deployAndClean(app, imageId, w)
}
예제 #3
0
func (p *dockerProvisioner) BuildImageWithoutDockerfile(user string, app provision.App, archiveFile io.ReadCloser, dirPath string) (string, error) {
	defer archiveFile.Close()
	options := docker.CreateContainerOptions{
		Config: &docker.Config{
			AttachStdout: true,
			AttachStderr: true,
			AttachStdin:  true,
			OpenStdin:    true,
			StdinOnce:    true,
			User:         user,
			Image:        p.getBuildImage(app),
			Cmd:          []string{"/bin/bash", "-c", "tail -f /dev/null"},
		},
	}
	cluster := p.Cluster()
	_, cont, err := cluster.CreateContainerSchedulerOpts(options, []string{app.GetName(), ""})
	if err != nil {
		return "", err
	}
	defer cluster.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})
	err = cluster.StartContainer(cont.ID, nil)
	if err != nil {
		return "", err
	}
	var buf bytes.Buffer
	var archiveFileBuf bytes.Buffer
	tarball := tar.NewWriter(&buf)
	if err != nil {
		return "", err
	}
	n, err := archiveFileBuf.ReadFrom(archiveFile)
	if err != nil {
		return "", err
	}
	header := tar.Header{
		Name: "archive.tar.gz",
		Mode: 0666,
		Size: n,
	}
	tarball.WriteHeader(&header)
	archiveReader := bytes.NewReader(archiveFileBuf.Bytes())
	_, err = io.Copy(&buf, archiveReader)
	if err != nil {
		return "", err
	}
	defer tarball.Close()
	uploadOpts := docker.UploadToContainerOptions{
		InputStream: &buf,
		Path:        dirPath,
	}
	err = cluster.UploadToContainer(cont.ID, uploadOpts)
	if err != nil {
		return "", err
	}
	err = cluster.StopContainer(cont.ID, 10)
	if err != nil {
		return "", err
	}
	image, err := cluster.CommitContainer(docker.CommitContainerOptions{Container: cont.ID})
	return image.ID, err
}
예제 #4
0
파일: provisioner.go 프로젝트: tsuru/tsuru
func (p *dockerProvisioner) UploadDeploy(app provision.App, archiveFile io.ReadCloser, fileSize int64, build bool, evt *event.Event) (string, error) {
	if build {
		return "", errors.New("running UploadDeploy with build=true is not yet supported")
	}
	user, err := config.GetString("docker:user")
	if err != nil {
		user, _ = config.GetString("docker:ssh:user")
	}
	defer archiveFile.Close()
	imageName := image.GetBuildImage(app)
	options := docker.CreateContainerOptions{
		Config: &docker.Config{
			AttachStdout: true,
			AttachStderr: true,
			AttachStdin:  true,
			OpenStdin:    true,
			StdinOnce:    true,
			User:         user,
			Image:        imageName,
			Cmd:          []string{"/bin/bash", "-c", "tail -f /dev/null"},
		},
	}
	cluster := p.Cluster()
	schedOpts := &container.SchedulerOpts{
		AppName:       app.GetName(),
		ActionLimiter: p.ActionLimiter(),
	}
	addr, cont, err := cluster.CreateContainerSchedulerOpts(options, schedOpts, net.StreamInactivityTimeout)
	hostAddr := net.URLToHost(addr)
	if schedOpts.LimiterDone != nil {
		schedOpts.LimiterDone()
	}
	if err != nil {
		return "", err
	}
	defer func() {
		done := p.ActionLimiter().Start(hostAddr)
		cluster.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})
		done()
	}()
	done := p.ActionLimiter().Start(hostAddr)
	err = cluster.StartContainer(cont.ID, nil)
	done()
	if err != nil {
		return "", err
	}
	intermediateImageID, fileURI, err := dockercommon.UploadToContainer(cluster, cont.ID, archiveFile, fileSize)
	done = p.ActionLimiter().Start(hostAddr)
	stopErr := cluster.StopContainer(cont.ID, 10)
	done()
	if stopErr != nil {
		return "", stopErr
	}
	if err != nil {
		return "", err
	}
	imageId, err := p.archiveDeploy(app, intermediateImageID, fileURI, evt)
	if err != nil {
		return "", err
	}
	return imageId, p.deployAndClean(app, imageId, evt)
}