Merge pull request #514 from technolo-g/Issue_499_Automate_golint_pr

Issue #500 Run golint on codebase
This commit is contained in:
Victor Vieux 2015-03-30 12:14:15 -07:00
commit b655cbb7c5
39 changed files with 164 additions and 73 deletions

View File

@ -22,6 +22,7 @@ import (
"github.com/samalba/dockerclient"
)
// APIVERSION is exported
const APIVERSION = "1.16"
type context struct {
@ -55,14 +56,14 @@ func getInfo(c *context, w http.ResponseWriter, r *http.Request) {
func getVersion(c *context, w http.ResponseWriter, r *http.Request) {
version := struct {
Version string
ApiVersion string
APIVersion string
GoVersion string
GitCommit string
Os string
Arch string
}{
Version: "swarm/" + version.VERSION,
ApiVersion: APIVERSION,
APIVersion: APIVERSION,
GoVersion: runtime.Version(),
GitCommit: version.GITCOMMIT,
Os: runtime.GOOS,
@ -316,7 +317,7 @@ func postContainersExec(c *context, w http.ResponseWriter, r *http.Request) {
return
}
id := struct{ Id string }{}
id := struct{ ID string }{}
if err := json.Unmarshal(data, &id); err != nil {
httpError(w, err.Error(), http.StatusInternalServerError)
@ -324,7 +325,7 @@ func postContainersExec(c *context, w http.ResponseWriter, r *http.Request) {
}
// add execID to the container, so the later exec/start will work
container.Info.ExecIDs = append(container.Info.ExecIDs, id.Id)
container.Info.ExecIDs = append(container.Info.ExecIDs, id.ID)
w.Header().Set("Content-Type", "application/json")
w.Write(data)

View File

@ -15,6 +15,7 @@ type eventsHandler struct {
cs map[string]chan struct{}
}
// NewEventsHandler is exported
func NewEventsHandler() *eventsHandler {
return &eventsHandler{
ws: make(map[string]io.Writer),

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/docker/pkg/ioutils"
)
// WriteFlusher is exported
type WriteFlusher struct {
sync.Mutex
w io.Writer
@ -29,6 +30,7 @@ func (wf *WriteFlusher) Flush() {
wf.flusher.Flush()
}
// NewWriteFlusher is exported
func NewWriteFlusher(w io.Writer) *WriteFlusher {
var flusher http.Flusher
if f, ok := w.(http.Flusher); ok {

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/swarm/cluster"
)
// DefaultDockerPort is exported
const DefaultDockerPort = ":2375"
func newListener(proto, addr string, tlsConfig *tls.Config) (net.Listener, error) {
@ -28,6 +29,7 @@ func newListener(proto, addr string, tlsConfig *tls.Config) (net.Listener, error
return l, nil
}
// ListenAndServe is exported
func ListenAndServe(c cluster.Cluster, hosts []string, enableCors bool, tlsConfig *tls.Config, eventsHandler *eventsHandler) error {
context := &context{
cluster: c,

View File

@ -4,6 +4,7 @@ import (
"github.com/samalba/dockerclient"
)
// ContainerSorter is exported
type ContainerSorter []*dockerclient.Container
func (s ContainerSorter) Len() int {

View File

@ -2,6 +2,7 @@ package cluster
import "github.com/samalba/dockerclient"
// Cluster is exported
type Cluster interface {
// Create a container
CreateContainer(config *dockerclient.ContainerConfig, name string) (*Container, error)
@ -12,8 +13,8 @@ type Cluster interface {
// Return all images
Images() []*Image
// Return one image matching `IdOrName`
Image(IdOrName string) *Image
// Return one image matching `IDOrName`
Image(IDOrName string) *Image
// Remove an image from the cluster
RemoveImage(image *Image) ([]*dockerclient.ImageDelete, error)
@ -21,8 +22,8 @@ type Cluster interface {
// Return all containers
Containers() []*Container
// Return container the matching `IdOrName`
Container(IdOrName string) *Container
// Return container the matching `IDOrName`
Container(IDOrName string) *Container
// Pull images
// `callback` can be called multiple time

View File

@ -2,6 +2,7 @@ package cluster
import "github.com/samalba/dockerclient"
// Container is exported
type Container struct {
dockerclient.Container

View File

@ -2,11 +2,13 @@ package cluster
import "github.com/samalba/dockerclient"
// Event is exported
type Event struct {
dockerclient.Event
Node Node
}
// EventHandler is exported
type EventHandler interface {
Handle(*Event) error
}

View File

@ -6,20 +6,22 @@ import (
"github.com/samalba/dockerclient"
)
// Image is exported
type Image struct {
dockerclient.Image
Node Node
}
func (image *Image) Match(IdOrName string) bool {
size := len(IdOrName)
// Match is exported
func (image *Image) Match(IDOrName string) bool {
size := len(IDOrName)
if image.Id == IdOrName || (size > 2 && strings.HasPrefix(image.Id, IdOrName)) {
if image.Id == IDOrName || (size > 2 && strings.HasPrefix(image.Id, IDOrName)) {
return true
}
for _, repoTag := range image.RepoTags {
if repoTag == IdOrName || (size > 2 && strings.HasPrefix(repoTag, IdOrName)) {
if repoTag == IDOrName || (size > 2 && strings.HasPrefix(repoTag, IDOrName)) {
return true
}
}

View File

@ -2,6 +2,7 @@ package cluster
import "fmt"
// Node is exported
type Node interface {
ID() string
Name() string
@ -10,9 +11,9 @@ type Node interface {
Addr() string //to know where to connect with the proxy
Images() []*Image //used by the API
Image(IdOrName string) *Image //used by the filters
Image(IDOrName string) *Image //used by the filters
Containers() []*Container //used by the filters
Container(IdOrName string) *Container //used by the filters
Container(IDOrName string) *Container //used by the filters
TotalCpus() int64 //used by the strategy
UsedCpus() int64 //used by the strategy
@ -24,6 +25,7 @@ type Node interface {
IsHealthy() bool
}
// SerializeNode is exported
func SerializeNode(node Node) string {
return fmt.Sprintf("{%q:%q,%q:%q,%q:%q,%q:%q}",
"Name", node.Name(),

View File

@ -2,6 +2,7 @@ package cluster
import "crypto/tls"
// Options is exported
type Options struct {
TLSConfig *tls.Config
OvercommitRatio float64

View File

@ -13,6 +13,7 @@ import (
"github.com/samalba/dockerclient"
)
// Cluster is exported
type Cluster struct {
sync.RWMutex
@ -23,6 +24,7 @@ type Cluster struct {
store *state.Store
}
// NewCluster is exported
func NewCluster(scheduler *scheduler.Scheduler, store *state.Store, eventhandler cluster.EventHandler, options *cluster.Options) cluster.Cluster {
log.WithFields(log.Fields{"name": "swarm"}).Debug("Initializing cluster")
@ -54,7 +56,7 @@ func NewCluster(scheduler *scheduler.Scheduler, store *state.Store, eventhandler
return cluster
}
// callback for the events
// Handle callbacks for the events
func (c *Cluster) Handle(e *cluster.Event) error {
if err := c.eventHandler.Handle(e); err != nil {
log.Error(err)
@ -62,7 +64,7 @@ func (c *Cluster) Handle(e *cluster.Event) error {
return nil
}
// Schedule a brand new container into the cluster.
// CreateContainer aka schedule a brand new container into the cluster.
func (c *Cluster) CreateContainer(config *dockerclient.ContainerConfig, name string) (*cluster.Container, error) {
c.RLock()
@ -108,8 +110,8 @@ retry:
return nil, nil
}
// Remove a container from the cluster. Containers should always be destroyed
// through the scheduler to guarantee atomicity.
// RemoveContainer aka Remove a container from the cluster. Containers should
// always be destroyed through the scheduler to guarantee atomicity.
func (c *Cluster) RemoveContainer(container *cluster.Container, force bool) error {
c.Lock()
defer c.Unlock()
@ -186,17 +188,17 @@ func (c *Cluster) Images() []*cluster.Image {
return out
}
// Image returns an image with IdOrName in the cluster
func (c *Cluster) Image(IdOrName string) *cluster.Image {
// Image returns an image with IDOrName in the cluster
func (c *Cluster) Image(IDOrName string) *cluster.Image {
// Abort immediately if the name is empty.
if len(IdOrName) == 0 {
if len(IDOrName) == 0 {
return nil
}
c.RLock()
defer c.RUnlock()
for _, n := range c.nodes {
if image := n.Image(IdOrName); image != nil {
if image := n.Image(IDOrName); image != nil {
return image
}
}
@ -214,6 +216,7 @@ func (c *Cluster) RemoveImage(image *cluster.Image) ([]*dockerclient.ImageDelete
return nil, nil
}
// Pull is exported
func (c *Cluster) Pull(name string, callback func(what, status string)) {
size := len(c.nodes)
done := make(chan bool, size)
@ -251,17 +254,17 @@ func (c *Cluster) Containers() []*cluster.Container {
return out
}
// Container returns the container with IdOrName in the cluster
func (c *Cluster) Container(IdOrName string) *cluster.Container {
// Container returns the container with IDOrName in the cluster
func (c *Cluster) Container(IDOrName string) *cluster.Container {
// Abort immediately if the name is empty.
if len(IdOrName) == 0 {
if len(IDOrName) == 0 {
return nil
}
c.RLock()
defer c.RUnlock()
for _, n := range c.nodes {
if container := n.Container(IdOrName); container != nil {
if container := n.Container(IDOrName); container != nil {
return container
}
}
@ -282,6 +285,7 @@ func (c *Cluster) listNodes() []cluster.Node {
return out
}
// Info is exported
func (c *Cluster) Info() [][2]string {
info := [][2]string{{"\bNodes", fmt.Sprintf("%d", len(c.nodes))}}

View File

@ -22,6 +22,7 @@ const (
requestTimeout = 10 * time.Second
)
// NewNode is exported
func NewNode(addr string, overcommitRatio float64) *node {
e := &node{
addr: addr,
@ -144,7 +145,7 @@ func (n *node) updateSpecs() error {
// Older versions of Docker don't expose the ID field and are not supported
// by Swarm. Catch the error ASAP and refuse to connect.
if len(info.ID) == 0 {
return fmt.Errorf("node %s is running an unsupported version of Docker Engine. Please upgrade.", n.addr)
return fmt.Errorf("node %s is running an unsupported version of Docker Engine. Please upgrade", n.addr)
}
n.id = info.ID
n.name = info.Name
@ -327,7 +328,7 @@ func (n *node) emitEvent(event string) {
// Return the sum of memory reserved by containers.
func (n *node) UsedMemory() int64 {
var r int64 = 0
var r int64
n.RLock()
for _, c := range n.containers {
r += c.Info.Config.Memory
@ -338,7 +339,7 @@ func (n *node) UsedMemory() int64 {
// Return the sum of CPUs reserved by containers.
func (n *node) UsedCpus() int64 {
var r int64 = 0
var r int64
n.RLock()
for _, c := range n.containers {
r += c.Info.Config.CpuShares
@ -437,10 +438,10 @@ func (n *node) Containers() []*cluster.Container {
return containers
}
// Container returns the container with IdOrName in the node.
func (n *node) Container(IdOrName string) *cluster.Container {
// Container returns the container with IDOrName in the node.
func (n *node) Container(IDOrName string) *cluster.Container {
// Abort immediately if the name is empty.
if len(IdOrName) == 0 {
if len(IDOrName) == 0 {
return nil
}
@ -449,13 +450,13 @@ func (n *node) Container(IdOrName string) *cluster.Container {
for _, container := range n.Containers() {
// Match ID prefix.
if strings.HasPrefix(container.Id, IdOrName) {
if strings.HasPrefix(container.Id, IDOrName) {
return container
}
// Match name, /name or engine/name.
for _, name := range container.Names {
if name == IdOrName || name == "/"+IdOrName || container.Node.ID()+name == IdOrName || container.Node.Name()+name == IdOrName {
if name == IDOrName || name == "/"+IDOrName || container.Node.ID()+name == IDOrName || container.Node.Name()+name == IDOrName {
return container
}
}
@ -476,13 +477,13 @@ func (n *node) Images() []*cluster.Image {
return images
}
// Image returns the image with IdOrName in the node
func (n *node) Image(IdOrName string) *cluster.Image {
// Image returns the image with IDOrName in the node
func (n *node) Image(IDOrName string) *cluster.Image {
n.RLock()
defer n.RUnlock()
for _, image := range n.images {
if image.Match(IdOrName) {
if image.Match(IDOrName) {
return image
}
}

View File

@ -11,6 +11,7 @@ import (
consul "github.com/hashicorp/consul/api"
)
// ConsulDiscoveryService is exported
type ConsulDiscoveryService struct {
heartbeat time.Duration
client *consul.Client
@ -22,6 +23,7 @@ func init() {
discovery.Register("consul", &ConsulDiscoveryService{})
}
// Initialize is exported
func (s *ConsulDiscoveryService) Initialize(uris string, heartbeat int) error {
parts := strings.SplitN(uris, "/", 2)
if len(parts) < 2 {
@ -52,6 +54,8 @@ func (s *ConsulDiscoveryService) Initialize(uris string, heartbeat int) error {
s.lastIndex = meta.LastIndex
return nil
}
// Fetch is exported
func (s *ConsulDiscoveryService) Fetch() ([]*discovery.Entry, error) {
kv := s.client.KV()
pairs, _, err := kv.List(s.prefix, nil)
@ -70,6 +74,7 @@ func (s *ConsulDiscoveryService) Fetch() ([]*discovery.Entry, error) {
return discovery.CreateEntries(addrs)
}
// Watch is exported
func (s *ConsulDiscoveryService) Watch(callback discovery.WatchCallback) {
for _ = range s.waitForChange() {
log.WithField("name", "consul").Debug("Discovery watch triggered")
@ -80,6 +85,7 @@ func (s *ConsulDiscoveryService) Watch(callback discovery.WatchCallback) {
}
}
// Register is exported
func (s *ConsulDiscoveryService) Register(addr string) error {
kv := s.client.KV()
p := &consul.KVPair{Key: path.Join(s.prefix, addr), Value: []byte(addr)}

View File

@ -9,11 +9,13 @@ import (
log "github.com/Sirupsen/logrus"
)
// Entry is exported
type Entry struct {
Host string
Port string
}
// NewEntry is exported
func NewEntry(url string) (*Entry, error) {
host, port, err := net.SplitHostPort(url)
if err != nil {
@ -26,8 +28,10 @@ func (m Entry) String() string {
return fmt.Sprintf("%s:%s", m.Host, m.Port)
}
// WatchCallback is exported
type WatchCallback func(entries []*Entry)
// DiscoveryService is exported
type DiscoveryService interface {
Initialize(string, int) error
Fetch() ([]*Entry, error)
@ -36,8 +40,10 @@ type DiscoveryService interface {
}
var (
discoveries map[string]DiscoveryService
ErrNotSupported = errors.New("discovery service not supported")
discoveries map[string]DiscoveryService
// ErrNotSupported is exported
ErrNotSupported = errors.New("discovery service not supported")
// ErrNotImplemented is exported
ErrNotImplemented = errors.New("not implemented in this discovery service")
)
@ -45,6 +51,7 @@ func init() {
discoveries = make(map[string]DiscoveryService)
}
// Register is exported
func Register(scheme string, d DiscoveryService) error {
if _, exists := discoveries[scheme]; exists {
return fmt.Errorf("scheme already registered %s", scheme)
@ -65,6 +72,7 @@ func parse(rawurl string) (string, string) {
return parts[0], parts[1]
}
// New is exported
func New(rawurl string, heartbeat int) (DiscoveryService, error) {
scheme, uri := parse(rawurl)
@ -77,6 +85,7 @@ func New(rawurl string, heartbeat int) (DiscoveryService, error) {
return nil, ErrNotSupported
}
// CreateEntries is exported
func CreateEntries(addrs []string) ([]*Entry, error) {
entries := []*Entry{}
if addrs == nil {

View File

@ -10,6 +10,7 @@ import (
"github.com/docker/swarm/discovery"
)
// EtcdDiscoveryService is exported
type EtcdDiscoveryService struct {
ttl uint64
client *etcd.Client
@ -20,6 +21,7 @@ func init() {
discovery.Register("etcd", &EtcdDiscoveryService{})
}
// Initialize is exported
func (s *EtcdDiscoveryService) Initialize(uris string, heartbeat int) error {
var (
// split here because uris can contain multiples ips
@ -51,6 +53,8 @@ func (s *EtcdDiscoveryService) Initialize(uris string, heartbeat int) error {
}
return nil
}
// Fetch is exported
func (s *EtcdDiscoveryService) Fetch() ([]*discovery.Entry, error) {
resp, err := s.client.Get(s.path, true, true)
if err != nil {
@ -64,6 +68,7 @@ func (s *EtcdDiscoveryService) Fetch() ([]*discovery.Entry, error) {
return discovery.CreateEntries(addrs)
}
// Watch is exported
func (s *EtcdDiscoveryService) Watch(callback discovery.WatchCallback) {
watchChan := make(chan *etcd.Response)
go s.client.Watch(s.path, 0, true, watchChan, nil)
@ -76,6 +81,7 @@ func (s *EtcdDiscoveryService) Watch(callback discovery.WatchCallback) {
}
}
// Register is exported
func (s *EtcdDiscoveryService) Register(addr string) error {
_, err := s.client.Set(path.Join(s.path, addr), addr, s.ttl)
return err

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/swarm/discovery"
)
// FileDiscoveryService is exported
type FileDiscoveryService struct {
heartbeat int
path string
@ -17,6 +18,7 @@ func init() {
discovery.Register("file", &FileDiscoveryService{})
}
// Initialize is exported
func (s *FileDiscoveryService) Initialize(path string, heartbeat int) error {
s.path = path
s.heartbeat = heartbeat
@ -33,6 +35,7 @@ func parseFileContent(content []byte) []string {
return result
}
// Fetch is exported
func (s *FileDiscoveryService) Fetch() ([]*discovery.Entry, error) {
fileContent, err := ioutil.ReadFile(s.path)
if err != nil {
@ -41,6 +44,7 @@ func (s *FileDiscoveryService) Fetch() ([]*discovery.Entry, error) {
return discovery.CreateEntries(parseFileContent(fileContent))
}
// Watch is exported
func (s *FileDiscoveryService) Watch(callback discovery.WatchCallback) {
for _ = range time.Tick(time.Duration(s.heartbeat) * time.Second) {
entries, err := s.Fetch()
@ -50,6 +54,7 @@ func (s *FileDiscoveryService) Watch(callback discovery.WatchCallback) {
}
}
// Register is exported
func (s *FileDiscoveryService) Register(addr string) error {
return discovery.ErrNotImplemented
}

View File

@ -6,9 +6,7 @@ import (
"strconv"
)
//
// IP generator
//
// Generate takes care of IP generation
func Generate(pattern string) []string {
re, _ := regexp.Compile(`\[(.+):(.+)\]`)
submatch := re.FindStringSubmatch(pattern)

View File

@ -6,6 +6,7 @@ import (
"github.com/docker/swarm/discovery"
)
// NodesDiscoveryService is exported
type NodesDiscoveryService struct {
entries []*discovery.Entry
}
@ -14,6 +15,7 @@ func init() {
discovery.Register("nodes", &NodesDiscoveryService{})
}
// Initialize is exported
func (s *NodesDiscoveryService) Initialize(uris string, _ int) error {
for _, input := range strings.Split(uris, ",") {
for _, ip := range discovery.Generate(input) {
@ -27,13 +29,17 @@ func (s *NodesDiscoveryService) Initialize(uris string, _ int) error {
return nil
}
// Fetch is exported
func (s *NodesDiscoveryService) Fetch() ([]*discovery.Entry, error) {
return s.entries, nil
}
// Watch is exported
func (s *NodesDiscoveryService) Watch(callback discovery.WatchCallback) {
}
// Register is exported
func (s *NodesDiscoveryService) Register(addr string) error {
return discovery.ErrNotImplemented
}

View File

@ -12,8 +12,10 @@ import (
"github.com/docker/swarm/discovery"
)
const DISCOVERY_URL = "https://discovery-stage.hub.docker.com/v1"
// DiscoveryUrl is exported
const DiscoveryURL = "https://discovery-stage.hub.docker.com/v1"
// TokenDiscoveryService is exported
type TokenDiscoveryService struct {
heartbeat int
url string
@ -24,12 +26,13 @@ func init() {
discovery.Register("token", &TokenDiscoveryService{})
}
// Initialize is exported
func (s *TokenDiscoveryService) Initialize(urltoken string, heartbeat int) error {
if i := strings.LastIndex(urltoken, "/"); i != -1 {
s.url = "https://" + urltoken[:i]
s.token = urltoken[i+1:]
} else {
s.url = DISCOVERY_URL
s.url = DiscoveryURL
s.token = urltoken
}
@ -63,6 +66,7 @@ func (s *TokenDiscoveryService) Fetch() ([]*discovery.Entry, error) {
return discovery.CreateEntries(addrs)
}
// Watch is exported
func (s *TokenDiscoveryService) Watch(callback discovery.WatchCallback) {
for _ = range time.Tick(time.Duration(s.heartbeat) * time.Second) {
entries, err := s.Fetch()
@ -72,7 +76,7 @@ func (s *TokenDiscoveryService) Watch(callback discovery.WatchCallback) {
}
}
// RegisterEntry adds a new entry identified by the into the discovery service
// Register adds a new entry identified by the into the discovery service
func (s *TokenDiscoveryService) Register(addr string) error {
buf := strings.NewReader(addr)

View File

@ -11,7 +11,7 @@ func TestInitialize(t *testing.T) {
err := discovery.Initialize("token", 0)
assert.NoError(t, err)
assert.Equal(t, discovery.token, "token")
assert.Equal(t, discovery.url, DISCOVERY_URL)
assert.Equal(t, discovery.url, DiscoveryURL)
err = discovery.Initialize("custom/path/token", 0)
assert.NoError(t, err)
@ -23,7 +23,7 @@ func TestInitialize(t *testing.T) {
}
func TestRegister(t *testing.T) {
discovery := &TokenDiscoveryService{token: "TEST_TOKEN", url: DISCOVERY_URL}
discovery := &TokenDiscoveryService{token: "TEST_TOKEN", url: DiscoveryURL}
expected := "127.0.0.1:2675"
assert.NoError(t, discovery.Register(expected))

View File

@ -11,6 +11,7 @@ import (
"github.com/samuel/go-zookeeper/zk"
)
// ZkDiscoveryService is exported
type ZkDiscoveryService struct {
conn *zk.Conn
path []string
@ -39,6 +40,7 @@ func (s *ZkDiscoveryService) createFullpath() error {
return nil
}
// Initialize is exported
func (s *ZkDiscoveryService) Initialize(uris string, heartbeat int) error {
var (
// split here because uris can contain multiples ips
@ -72,6 +74,7 @@ func (s *ZkDiscoveryService) Initialize(uris string, heartbeat int) error {
return nil
}
// Fetch is exported
func (s *ZkDiscoveryService) Fetch() ([]*discovery.Entry, error) {
addrs, _, err := s.conn.Children(s.fullpath())
@ -82,6 +85,7 @@ func (s *ZkDiscoveryService) Fetch() ([]*discovery.Entry, error) {
return discovery.CreateEntries(addrs)
}
// Watch is exported
func (s *ZkDiscoveryService) Watch(callback discovery.WatchCallback) {
addrs, _, eventChan, err := s.conn.ChildrenW(s.fullpath())
@ -107,6 +111,7 @@ func (s *ZkDiscoveryService) Watch(callback discovery.WatchCallback) {
}
// Register is exported
func (s *ZkDiscoveryService) Register(addr string) error {
nodePath := path.Join(s.fullpath(), addr)

View File

@ -54,23 +54,23 @@ var (
Name: "api-enable-cors, cors",
Usage: "enable CORS headers in the remote API",
}
flTls = cli.BoolFlag{
flTLS = cli.BoolFlag{
Name: "tls",
Usage: "use TLS; implied by --tlsverify=true",
}
flTlsCaCert = cli.StringFlag{
flTLSCaCert = cli.StringFlag{
Name: "tlscacert",
Usage: "trust only remotes providing a certificate signed by the CA given here",
}
flTlsCert = cli.StringFlag{
flTLSCert = cli.StringFlag{
Name: "tlscert",
Usage: "path to TLS certificate file",
}
flTlsKey = cli.StringFlag{
flTLSKey = cli.StringFlag{
Name: "tlskey",
Usage: "path to TLS key file",
}
flTlsVerify = cli.BoolFlag{
flTLSVerify = cli.BoolFlag{
Name: "tlsverify",
Usage: "use TLS and verify the remote",
}
@ -86,8 +86,9 @@ var (
}
// hack for go vet
flFilterValue = cli.StringSlice([]string{"constraint", "affinity", "health", "port", "dependency"})
DEFAULT_FILTER_NUMBER = len(flFilterValue)
flFilterValue = cli.StringSlice([]string{"constraint", "affinity", "health", "port", "dependency"})
// DefaultFilterNumber is exported
DefaultFilterNumber = len(flFilterValue)
flFilter = cli.StringSliceFlag{
Name: "filter, f",

View File

@ -108,7 +108,7 @@ func main() {
flStore, flCluster,
flStrategy, flFilter,
flHosts, flHeartBeat, flOverCommit,
flTls, flTlsCaCert, flTlsCert, flTlsKey, flTlsVerify,
flTLS, flTLSCaCert, flTLSCert, flTLSKey, flTLSVerify,
flEnableCors},
Action: manage,
},

View File

@ -32,7 +32,7 @@ func (h *logHandler) Handle(e *cluster.Event) error {
}
// Load the TLS certificates/keys and, if verify is true, the CA.
func loadTlsConfig(ca, cert, key string, verify bool) (*tls.Config, error) {
func loadTLSConfig(ca, cert, key string, verify bool) (*tls.Config, error) {
c, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
return nil, fmt.Errorf("Couldn't load X509 key pair (%s, %s): %s. Key encrypted?",
@ -64,7 +64,7 @@ func loadTlsConfig(ca, cert, key string, verify bool) (*tls.Config, error) {
func manage(c *cli.Context) {
var (
tlsConfig *tls.Config = nil
tlsConfig *tls.Config
err error
)
@ -76,7 +76,7 @@ func manage(c *cli.Context) {
if c.Bool("tlsverify") && !c.IsSet("tlscacert") {
log.Fatal("--tlscacert must be provided when using --tlsverify")
}
tlsConfig, err = loadTlsConfig(
tlsConfig, err = loadTLSConfig(
c.String("tlscacert"),
c.String("tlscert"),
c.String("tlskey"),
@ -110,7 +110,7 @@ func manage(c *cli.Context) {
// see https://github.com/codegangsta/cli/issues/160
names := c.StringSlice("filter")
if c.IsSet("filter") || c.IsSet("f") {
names = names[DEFAULT_FILTER_NUMBER:]
names = names[DefaultFilterNumber:]
}
fs, err := filter.New(names)
if err != nil {

View File

@ -13,6 +13,7 @@ import (
type AffinityFilter struct {
}
// Filter is exported
func (f *AffinityFilter) Filter(config *dockerclient.ContainerConfig, nodes []cluster.Node) ([]cluster.Node, error) {
affinities, err := parseExprs("affinity", config.Env)
if err != nil {

View File

@ -12,6 +12,7 @@ import (
type ConstraintFilter struct {
}
// Filter is exported
func (f *ConstraintFilter) Filter(config *dockerclient.ContainerConfig, nodes []cluster.Node) ([]cluster.Node, error) {
constraints, err := parseExprs("constraint", config.Env)
if err != nil {

View File

@ -12,6 +12,7 @@ import (
type DependencyFilter struct {
}
// Filter is exported
func (f *DependencyFilter) Filter(config *dockerclient.ContainerConfig, nodes []cluster.Node) ([]cluster.Node, error) {
if len(nodes) == 0 {
return nodes, nil

View File

@ -9,10 +9,13 @@ import (
)
const (
// EQ is exported
EQ = iota
// NOTEQ is exported
NOTEQ
)
// OPERATORS is exported
var OPERATORS = []string{"==", "!="}
type expr struct {
@ -109,7 +112,6 @@ func (e *expr) Match(whats ...string) bool {
func isSoft(value string) bool {
if value[0] == '~' {
return true
} else {
return false
}
return false
}

View File

@ -8,13 +8,15 @@ import (
"github.com/samalba/dockerclient"
)
// Filter is exported
type Filter interface {
// Return a subset of nodes that were accepted by the filtering policy.
Filter(*dockerclient.ContainerConfig, []cluster.Node) ([]cluster.Node, error)
}
var (
filters map[string]Filter
filters map[string]Filter
// ErrNotSupported is exported
ErrNotSupported = errors.New("filter not supported")
)
@ -28,6 +30,7 @@ func init() {
}
}
// New is exported
func New(names []string) ([]Filter, error) {
var selectedFilters []Filter
@ -42,7 +45,7 @@ func New(names []string) ([]Filter, error) {
return selectedFilters, nil
}
// Apply a set of filters in batch.
// ApplyFilters applies a set of filters in batch.
func ApplyFilters(filters []Filter, config *dockerclient.ContainerConfig, nodes []cluster.Node) ([]cluster.Node, error) {
var err error

View File

@ -8,6 +8,7 @@ import (
)
var (
// ErrNoHealthyNodeAvailable is exported
ErrNoHealthyNodeAvailable = errors.New("No healthy node available in the cluster")
)
@ -15,6 +16,7 @@ var (
type HealthFilter struct {
}
// Filter is exported
func (f *HealthFilter) Filter(_ *dockerclient.ContainerConfig, nodes []cluster.Node) ([]cluster.Node, error) {
result := []cluster.Node{}
for _, node := range nodes {

View File

@ -13,6 +13,7 @@ import (
type PortFilter struct {
}
// Filter is exported
func (p *PortFilter) Filter(config *dockerclient.ContainerConfig, nodes []cluster.Node) ([]cluster.Node, error) {
for _, port := range config.HostConfig.PortBindings {
for _, binding := range port {

View File

@ -7,11 +7,13 @@ import (
"github.com/samalba/dockerclient"
)
// Scheduler is exported
type Scheduler struct {
strategy strategy.PlacementStrategy
filters []filter.Filter
}
// New is exported
func New(strategy strategy.PlacementStrategy, filters []filter.Filter) *Scheduler {
return &Scheduler{
strategy: strategy,
@ -19,7 +21,7 @@ func New(strategy strategy.PlacementStrategy, filters []filter.Filter) *Schedule
}
}
// Find a nice home for our container.
// SelectNodeForContainer will find a nice home for our container.
func (s *Scheduler) SelectNodeForContainer(nodes []cluster.Node, config *dockerclient.ContainerConfig) (cluster.Node, error) {
accepted, err := filter.ApplyFilters(s.filters, config, nodes)
if err != nil {

View File

@ -7,13 +7,16 @@ import (
"github.com/samalba/dockerclient"
)
// BinpackPlacementStrategy is exported
type BinpackPlacementStrategy struct {
}
// Initialize is exported
func (p *BinpackPlacementStrategy) Initialize() error {
return nil
}
// PlaceContainer is exported
func (p *BinpackPlacementStrategy) PlaceContainer(config *dockerclient.ContainerConfig, nodes []cluster.Node) (cluster.Node, error) {
weightedNodes, err := weighNodes(config, nodes)
if err != nil {

View File

@ -9,14 +9,16 @@ import (
"github.com/samalba/dockerclient"
)
// Randomly place the container into the cluster.
// RandomPlacementStrategy randomly places the container into the cluster.
type RandomPlacementStrategy struct{}
// Initialize is exported
func (p *RandomPlacementStrategy) Initialize() error {
rand.Seed(time.Now().UTC().UnixNano())
return nil
}
// PlaceContainer is exported
func (p *RandomPlacementStrategy) PlaceContainer(config *dockerclient.ContainerConfig, nodes []cluster.Node) (cluster.Node, error) {
if size := len(nodes); size > 0 {
n := rand.Intn(len(nodes))

View File

@ -7,13 +7,16 @@ import (
"github.com/samalba/dockerclient"
)
// SpreadPlacementStrategy is exported
type SpreadPlacementStrategy struct {
}
// Initialize is exported
func (p *SpreadPlacementStrategy) Initialize() error {
return nil
}
// PlaceContainer is exported
func (p *SpreadPlacementStrategy) PlaceContainer(config *dockerclient.ContainerConfig, nodes []cluster.Node) (cluster.Node, error) {
weightedNodes, err := weighNodes(config, nodes)
if err != nil {

View File

@ -8,6 +8,7 @@ import (
"github.com/samalba/dockerclient"
)
// PlacementStrategy is exported
type PlacementStrategy interface {
Initialize() error
// Given a container configuration and a set of nodes, select the target
@ -16,8 +17,10 @@ type PlacementStrategy interface {
}
var (
strategies map[string]PlacementStrategy
ErrNotSupported = errors.New("strategy not supported")
strategies map[string]PlacementStrategy
// ErrNotSupported is exported
ErrNotSupported = errors.New("strategy not supported")
// ErrNoResourcesAvailable is exported
ErrNoResourcesAvailable = errors.New("no resources available to schedule container")
)
@ -30,6 +33,7 @@ func init() {
}
}
// New is exported
func New(name string) (PlacementStrategy, error) {
if strategy, exists := strategies[name]; exists {
log.WithField("name", name).Debugf("Initializing strategy")

View File

@ -4,6 +4,7 @@ import (
"github.com/samalba/dockerclient"
)
// RequestedState is exported
type RequestedState struct {
ID string
Name string

View File

@ -14,12 +14,15 @@ import (
)
var (
ErrNotFound = errors.New("not found")
// ErrNotFound is exported
ErrNotFound = errors.New("not found")
// ErrAlreadyExists is exported
ErrAlreadyExists = errors.New("already exists")
ErrInvalidKey = errors.New("invalid key")
// ErrInvalidKey is exported
ErrInvalidKey = errors.New("invalid key")
)
// A simple key<->RequestedState store.
// Store is a simple key<->RequestedState store.
type Store struct {
RootDir string
values map[string]*RequestedState
@ -27,6 +30,7 @@ type Store struct {
sync.RWMutex
}
// NewStore is exported
func NewStore(rootdir string) *Store {
return &Store{
RootDir: rootdir,
@ -102,7 +106,7 @@ func (s *Store) load(file string) (*RequestedState, error) {
return value, nil
}
// Retrieves an object from the store keyed by `key`.
// Get an object from the store keyed by `key`.
func (s *Store) Get(key string) (*RequestedState, error) {
s.RLock()
defer s.RUnlock()
@ -113,7 +117,7 @@ func (s *Store) Get(key string) (*RequestedState, error) {
return nil, ErrNotFound
}
// Return all objects of the store.
// All objects of the store are returned.
func (s *Store) All() []*RequestedState {
s.RLock()
defer s.RUnlock()
@ -157,7 +161,7 @@ func (s *Store) Add(key string, value *RequestedState) error {
return s.set(key, value)
}
// Replaces an already existing object from the store.
// Replace an already existing object from the store.
func (s *Store) Replace(key string, value *RequestedState) error {
s.Lock()
defer s.Unlock()