Example #1
0
func (p *swarmProvisioner) RoutableAddresses(a provision.App) ([]url.URL, error) {
	client, err := chooseDBSwarmNode()
	if err != nil {
		return nil, err
	}
	imgID, err := image.AppCurrentImageName(a.GetName())
	if err != nil {
		if err != image.ErrNoImagesAvailable {
			return nil, err
		}
		return nil, nil
	}
	webProcessName, err := image.GetImageWebProcessName(imgID)
	if err != nil {
		return nil, err
	}
	if webProcessName == "" {
		return nil, nil
	}
	srvName := serviceNameForApp(a, webProcessName)
	srv, err := client.InspectService(srvName)
	if err != nil {
		return nil, err
	}
	var pubPort uint32
	if len(srv.Endpoint.Ports) > 0 {
		pubPort = srv.Endpoint.Ports[0].PublishedPort
	}
	if pubPort == 0 {
		return nil, nil
	}
	nodes, err := listValidNodes(client)
	if err != nil {
		return nil, err
	}
	for i := len(nodes) - 1; i >= 0; i-- {
		if nodes[i].Spec.Annotations.Labels[labelNodePoolName.String()] != a.GetPool() {
			nodes[i], nodes[len(nodes)-1] = nodes[len(nodes)-1], nodes[i]
			nodes = nodes[:len(nodes)-1]
		}
	}
	addrs := make([]url.URL, len(nodes))
	for i, n := range nodes {
		addr := n.Spec.Labels[labelNodeDockerAddr.String()]
		host := tsuruNet.URLToHost(addr)
		addrs[i] = url.URL{
			Scheme: "http",
			Host:   fmt.Sprintf("%s:%d", host, pubPort),
		}
	}
	return addrs, nil
}
Example #2
0
func (p *dockerProvisioner) LogsEnabled(app provision.App) (bool, string, error) {
	const (
		logBackendsEnv      = "LOG_BACKENDS"
		logDocKeyFormat     = "LOG_%s_DOC"
		tsuruLogBackendName = "tsuru"
	)
	logConf := container.DockerLog{}
	isBS, err := logConf.IsBS(app.GetPool())
	if err != nil {
		return false, "", err
	}
	if !isBS {
		driver, _, _ := logConf.LogOpts(app.GetPool())
		msg := fmt.Sprintf("Logs not available through tsuru. Enabled log driver is %q.", driver)
		return false, msg, nil
	}
	config, err := bs.LoadConfig([]string{app.GetPool()})
	if err != nil {
		return false, "", err
	}
	enabledBackends := config.PoolEntry(app.GetPool(), logBackendsEnv)
	if enabledBackends == "" {
		return true, "", nil
	}
	backendsList := strings.Split(enabledBackends, ",")
	for i := range backendsList {
		backendsList[i] = strings.TrimSpace(backendsList[i])
		if backendsList[i] == tsuruLogBackendName {
			return true, "", nil
		}
	}
	var docs []string
	for _, backendName := range backendsList {
		keyName := fmt.Sprintf(logDocKeyFormat, strings.ToUpper(backendName))
		backendDoc := config.PoolEntry(app.GetPool(), keyName)
		var docLine string
		if backendDoc == "" {
			docLine = fmt.Sprintf("* %s", backendName)
		} else {
			docLine = fmt.Sprintf("* %s: %s", backendName, backendDoc)
		}
		docs = append(docs, docLine)
	}
	fullDoc := fmt.Sprintf("Logs not available through tsuru. Enabled log backends are:\n%s",
		strings.Join(docs, "\n"))
	return false, fullDoc, nil
}
Example #3
0
func (c *Container) hostConfig(app provision.App, isDeploy bool) (*docker.HostConfig, error) {
	sharedBasedir, _ := config.GetString("docker:sharedfs:hostdir")
	sharedMount, _ := config.GetString("docker:sharedfs:mountpoint")
	sharedIsolation, _ := config.GetBool("docker:sharedfs:app-isolation")
	sharedSalt, _ := config.GetString("docker:sharedfs:salt")
	hostConfig := docker.HostConfig{
		CPUShares: int64(app.GetCpuShare()),
	}

	if !isDeploy {
		hostConfig.Memory = app.GetMemory()
		hostConfig.MemorySwap = app.GetMemory() + app.GetSwap()
		hostConfig.RestartPolicy = docker.AlwaysRestart()
		hostConfig.PortBindings = map[docker.Port][]docker.PortBinding{
			docker.Port(c.ExposedPort): {{HostIP: "", HostPort: ""}},
		}
		pool := app.GetPool()
		driver, opts, logErr := LogOpts(pool)
		if logErr != nil {
			return nil, logErr
		}
		hostConfig.LogConfig = docker.LogConfig{
			Type:   driver,
			Config: opts,
		}
	} else {
		hostConfig.OomScoreAdj = 1000
	}

	hostConfig.SecurityOpt, _ = config.GetList("docker:security-opts")
	if sharedBasedir != "" && sharedMount != "" {
		if sharedIsolation {
			var appHostDir string
			if sharedSalt != "" {
				h := crypto.SHA1.New()
				io.WriteString(h, sharedSalt+c.AppName)
				appHostDir = fmt.Sprintf("%x", h.Sum(nil))
			} else {
				appHostDir = c.AppName
			}
			hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s/%s:%s:rw", sharedBasedir, appHostDir, sharedMount))
		} else {
			hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:%s:rw", sharedBasedir, sharedMount))
		}
	}
	return &hostConfig, nil
}
Example #4
0
func (p *dockerProvisioner) Nodes(app provision.App) ([]cluster.Node, error) {
	poolName := app.GetPool()
	nodes, err := p.Cluster().NodesForMetadata(map[string]string{"pool": poolName})
	if err != nil {
		return nil, err
	}
	if len(nodes) > 0 {
		return nodes, nil
	}
	return nil, errors.Errorf("No nodes found with one of the following metadata: pool=%s", poolName)
}
Example #5
0
func (p *dockerProvisioner) MetricEnvs(app provision.App) map[string]string {
	bsContainer, err := nodecontainer.LoadNodeContainer(app.GetPool(), nodecontainer.BsDefaultName)
	if err != nil {
		return map[string]string{}
	}
	envs := bsContainer.EnvMap()
	for envName := range envs {
		if !strings.HasPrefix(envName, "METRICS_") {
			delete(envs, envName)
		}
	}
	return envs
}
Example #6
0
func (p *dockerProvisioner) MetricEnvs(app provision.App) map[string]string {
	envMap := map[string]string{}
	envs, err := bs.EnvListForEndpoint("", app.GetPool())
	if err != nil {
		return envMap
	}
	for _, env := range envs {
		// TODO(cezarsa): ugly as hell
		if strings.HasPrefix(env, "METRICS_") {
			slice := strings.SplitN(env, "=", 2)
			envMap[slice[0]] = slice[1]
		}
	}
	return envMap
}
Example #7
0
func (p *dockerProvisioner) ImageDeploy(app provision.App, imageId string, evt *event.Event) (string, error) {
	cluster := p.Cluster()
	if !strings.Contains(imageId, ":") {
		imageId = fmt.Sprintf("%s:latest", imageId)
	}
	w := evt
	fmt.Fprintln(w, "---- Pulling image to tsuru ----")
	pullOpts := docker.PullImageOptions{
		Repository:        imageId,
		OutputStream:      w,
		InactivityTimeout: net.StreamInactivityTimeout,
	}
	nodes, err := cluster.NodesForMetadata(map[string]string{"pool": app.GetPool()})
	if err != nil {
		return "", err
	}
	node, _, err := p.scheduler.minMaxNodes(nodes, app.GetName(), "")
	if err != nil {
		return "", err
	}
	err = cluster.PullImage(pullOpts, docker.AuthConfiguration{}, node)
	if err != nil {
		return "", err
	}
	fmt.Fprintln(w, "---- Getting process from image ----")
	cmd := "cat /home/application/current/Procfile || cat /app/user/Procfile || cat /Procfile"
	var outBuf bytes.Buffer
	err = p.runCommandInContainer(imageId, cmd, app, &outBuf, nil)
	if err != nil {
		return "", err
	}
	newImage, err := dockercommon.PrepareImageForDeploy(dockercommon.PrepareImageArgs{
		Client:      cluster,
		App:         app,
		ProcfileRaw: outBuf.String(),
		ImageId:     imageId,
		AuthConfig:  p.RegistryAuthConfig(),
		Out:         w,
	})
	if err != nil {
		return "", err
	}
	app.SetUpdatePlatform(true)
	return newImage, p.deploy(app, newImage, evt)
}
Example #8
0
func (p *dockerProvisioner) MetricEnvs(app provision.App) map[string]string {
	envMap := map[string]string{}
	bsConf, err := bs.LoadConfig()
	if err != nil {
		return envMap
	}
	envs, err := bsConf.EnvListForEndpoint("", app.GetPool())
	if err != nil {
		return envMap
	}
	for _, env := range envs {
		if strings.HasPrefix(env, "METRICS_") {
			slice := strings.SplitN(env, "=", 2)
			envMap[slice[0]] = slice[1]
		}
	}
	return envMap
}
Example #9
0
func (p *dockerProvisioner) Nodes(app provision.App) ([]cluster.Node, error) {
	pool := app.GetPool()
	var (
		pools []provision.Pool
		err   error
	)
	if pool == "" {
		pools, err = provision.ListPools(bson.M{"$or": []bson.M{{"teams": app.GetTeamOwner()}, {"teams": bson.M{"$in": app.GetTeamsName()}}}})
	} else {
		pools, err = provision.ListPools(bson.M{"_id": pool})
	}
	if err != nil {
		return nil, err
	}
	if len(pools) == 0 {
		query := bson.M{"default": true}
		pools, err = provision.ListPools(query)
		if err != nil {
			return nil, err
		}
	}
	if len(pools) == 0 {
		return nil, errNoDefaultPool
	}
	for _, pool := range pools {
		nodes, err := p.Cluster().NodesForMetadata(map[string]string{"pool": pool.Name})
		if err != nil {
			return nil, errNoDefaultPool
		}
		if len(nodes) > 0 {
			return nodes, nil
		}
	}
	var nameList []string
	for _, pool := range pools {
		nameList = append(nameList, pool.Name)
	}
	poolsStr := strings.Join(nameList, ", pool=")
	return nil, fmt.Errorf("No nodes found with one of the following metadata: pool=%s", poolsStr)
}