func (u *Unit) Available() bool {
	return u.Status == StatusStarted ||
		u.Status == StatusStarting ||
		u.Status == StatusError
}
Available returns true if the unit is available. It will return true
whenever the unit itself is available, even when the application process is
not.
package provision
import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net"
	"net/url"
	"strconv"
	"strings"
	"time"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/pkg/errors"
	"github.com/tsuru/tsuru/app/bind"
	"github.com/tsuru/tsuru/event"
	appTypes "github.com/tsuru/tsuru/types/app"
	imgTypes "github.com/tsuru/tsuru/types/app/image"
	provTypes "github.com/tsuru/tsuru/types/provision"
)
const (
	defaultDockerProvisioner = "docker"
	DefaultHealthcheckScheme = "http"
	PoolMetadataName   = "pool"
	IaaSIDMetadataName = "iaas-id"
	IaaSMetadataName   = "iaas"
)
var (
	ErrInvalidStatus = errors.New("invalid status")
	ErrEmptyApp      = errors.New("no units for this app")
	ErrNodeNotFound  = errors.New("node not found")
	ErrLogsUnavailable = errors.New("logs from provisioner are unavailable")
	DefaultProvisioner = defaultDockerProvisioner
)
type UnitNotFoundError struct {
	ID string
}
func (e *UnitNotFoundError) Error() string {
	return fmt.Sprintf("unit %q not found", e.ID)
}
type InvalidProcessError struct {
	Msg string
}
func (e InvalidProcessError) Error() string {
	return fmt.Sprintf("process error: %s", e.Msg)
}
type ProvisionerNotSupported struct {
	Prov   Provisioner
	Action string
}
func (e ProvisionerNotSupported) Error() string {
	return fmt.Sprintf("provisioner %q does not support %s", e.Prov.GetName(), e.Action)
}
type Status string
func (s Status) String() string {
	return string(s)
}
func ParseStatus(status string) (Status, error) {
	switch status {
	case "created":
		return StatusCreated, nil
	case "building":
		return StatusBuilding, nil
	case "error":
		return StatusError, nil
	case "started":
		return StatusStarted, nil
	case "starting":
		return StatusStarting, nil
	case "stopped":
		return StatusStopped, nil
	case "asleep":
		return StatusAsleep, nil
	}
	return Status(""), ErrInvalidStatus
}
const (
	StatusCreated = Status("created")
	StatusBuilding = Status("building")
	StatusError = Status("error")
	StatusStarting = Status("starting")
	StatusStarted = Status("started")
	StatusStopped = Status("stopped")
	StatusAsleep = Status("asleep")
)
type Unit struct {
	ID          string
	Name        string
	AppName     string
	ProcessName string
	Type        string
	IP          string
	Status      Status
	Address     *url.URL
	Addresses   []url.URL
	Version     int
	Routable    bool
	Restarts    *int32
	CreatedAt   *time.Time
	Ready       *bool
}
func (u *Unit) GetID() string {
	return u.ID
}
func (u *Unit) GetIp() string {
	return u.IP
}
func (u *Unit) MarshalJSON() ([]byte, error) {
	type UnitForMarshal Unit
	host, port, _ := net.SplitHostPort(u.Address.Host)
	return json.Marshal(&struct {
		*UnitForMarshal
		HostAddr string
		HostPort string
		IP       string
	}{
		UnitForMarshal: (*UnitForMarshal)(u),
		HostAddr:       host,
		HostPort:       port,
		IP:             u.IP,
	})
}