func (p *swarmProvisioner) UploadDeploy(a provision.App, archiveFile io.ReadCloser, fileSize int64, build bool, evt *event.Event) (string, error) { defer archiveFile.Close() if build { return "", errors.New("running UploadDeploy with build=true is not yet supported") } client, err := chooseDBSwarmNode() if err != nil { return "", err } baseImage := image.GetBuildImage(a) buildingImage, err := image.AppNewImageName(a.GetName()) if err != nil { return "", errors.WithStack(err) } spec, err := serviceSpecForApp(tsuruServiceOpts{ app: a, image: baseImage, isDeploy: true, buildImage: buildingImage, }) if err != nil { return "", err } spec.TaskTemplate.ContainerSpec.Command = []string{"/usr/bin/tail", "-f", "/dev/null"} spec.TaskTemplate.RestartPolicy.Condition = swarm.RestartPolicyConditionNone srv, err := client.CreateService(docker.CreateServiceOptions{ ServiceSpec: *spec, }) if err != nil { return "", errors.WithStack(err) } tasks, err := waitForTasks(client, srv.ID, swarm.TaskStateRunning) if err != nil { return "", err } client, err = clientForNode(client, tasks[0].NodeID) if err != nil { return "", err } contID := tasks[0].Status.ContainerStatus.ContainerID imageID, fileURI, err := dockercommon.UploadToContainer(client, contID, archiveFile, fileSize) removeErr := client.RemoveService(docker.RemoveServiceOptions{ ID: srv.ID, }) if removeErr != nil { return "", errors.WithStack(removeErr) } if err != nil { return "", errors.WithStack(err) } cmds := dockercommon.ArchiveDeployCmds(a, fileURI) opts := tsuruServiceOpts{ app: a, image: imageID, isDeploy: true, buildImage: buildingImage, constraints: []string{ fmt.Sprintf("node.id == %s", tasks[0].NodeID), }, } srvID, task, err := runOnceCmds(client, opts, cmds, evt, evt) if srvID != "" { defer removeServiceAndLog(client, srvID) } if err != nil { return "", err } _, err = commitPushBuildImage(client, buildingImage, task.Status.ContainerStatus.ContainerID, a) if err != nil { return "", err } err = deployProcesses(client, a, buildingImage, nil) if err != nil { return "", errors.WithStack(err) } return buildingImage, nil }
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) }