Commit f0e217a6 authored by James DeFelice's avatar James DeFelice

bump mesos-go to latest master

parent 76dda4fb
...@@ -418,43 +418,43 @@ ...@@ -418,43 +418,43 @@
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/auth", "ImportPath": "github.com/mesos/mesos-go/auth",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/detector", "ImportPath": "github.com/mesos/mesos-go/detector",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/executor", "ImportPath": "github.com/mesos/mesos-go/executor",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/mesosproto", "ImportPath": "github.com/mesos/mesos-go/mesosproto",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/mesosutil", "ImportPath": "github.com/mesos/mesos-go/mesosutil",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/messenger", "ImportPath": "github.com/mesos/mesos-go/messenger",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/scheduler", "ImportPath": "github.com/mesos/mesos-go/scheduler",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/mesos/mesos-go/upid", "ImportPath": "github.com/mesos/mesos-go/upid",
"Comment": "mesos-0.24.0-20-gb164c06", "Comment": "v0.0.2-5-ged907b1",
"Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" "Rev": "ed907b10717e66325cf2894eb90a0553a89fcb11"
}, },
{ {
"ImportPath": "github.com/miekg/dns", "ImportPath": "github.com/miekg/dns",
......
...@@ -18,8 +18,19 @@ ...@@ -18,8 +18,19 @@
package mesosproto; package mesosproto;
import "mesos.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message AuthenticateMessage { message AuthenticateMessage {
required string pid = 1; // PID that needs to be authenticated. required string pid = 1; // PID that needs to be authenticated.
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package mesosproto;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
/**
* ACLs used for local authorization (See authorization.md file in the
* docs).
*/
message ACL {
// Entity is used to describe a subject(s) or an object(s) of an ACL.
// NOTE:
// To allow everyone access to an Entity set its type to 'ANY'.
// To deny access to an Entity set its type to 'NONE'.
message Entity {
enum Type {
SOME = 0;
ANY = 1;
NONE = 2;
}
optional Type type = 1 [default = SOME];
repeated string values = 2; // Ignored for ANY/NONE.
}
// ACLs.
message RegisterFramework {
// Subjects.
required Entity principals = 1; // Framework principals.
// Objects.
required Entity roles = 2; // Roles for resource offers.
}
message RunTask {
// Subjects.
required Entity principals = 1; // Framework principals.
// Objects.
required Entity users = 2; // Users to run the tasks/executors as.
}
// Which principals are authorized to shutdown frameworks of other
// principals.
message ShutdownFramework {
// Subjects.
required Entity principals = 1;
// Objects.
required Entity framework_principals = 2;
}
}
/**
* Collection of ACL.
*
* Each authorization request is evaluated against the ACLs in the order
* they are defined.
*
* For simplicity, the ACLs for a given action are not aggregated even
* when they have the same subjects or objects. The first ACL that
* matches the request determines whether that request should be
* permitted or not. An ACL matches iff both the subjects
* (e.g., clients, principals) and the objects (e.g., urls, users,
* roles) of the ACL match the request.
*
* If none of the ACLs match the request, the 'permissive' field
* determines whether the request should be permitted or not.
*
* TODO(vinod): Do aggregation of ACLs when possible.
*
*/
message ACLs {
optional bool permissive = 1 [default = true];
repeated ACL.RegisterFramework register_frameworks = 2;
repeated ACL.RunTask run_tasks = 3;
repeated ACL.ShutdownFramework shutdown_frameworks = 4;
}
...@@ -21,6 +21,17 @@ package mesosproto; ...@@ -21,6 +21,17 @@ package mesosproto;
import "mesos.proto"; import "mesos.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
/** /**
* Encodes the launch command sent to the external containerizer * Encodes the launch command sent to the external containerizer
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -21,10 +21,22 @@ package mesosproto; ...@@ -21,10 +21,22 @@ package mesosproto;
import "mesos.proto"; import "mesos.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
// TODO(benh): Provide comments for each of these messages. Also, // TODO(benh): Provide comments for each of these messages. Also,
// consider splitting these messages into different "packages" which // consider splitting these messages into different "packages" which
// represent which messages get handled by which components (e.g., the // represent which messages get handled by which components (e.g., the
// "mesos.internal.executor" package includes messages that the // "mesos.executor" package includes messages that the
// executor handles). // executor handles).
...@@ -194,8 +206,15 @@ message RunTaskMessage { ...@@ -194,8 +206,15 @@ message RunTaskMessage {
// TODO(karya): Remove framework_id after MESOS-2559 has shipped. // TODO(karya): Remove framework_id after MESOS-2559 has shipped.
optional FrameworkID framework_id = 1 [deprecated = true]; optional FrameworkID framework_id = 1 [deprecated = true];
required FrameworkInfo framework = 2; required FrameworkInfo framework = 2;
required string pid = 3;
required TaskInfo task = 4; required TaskInfo task = 4;
// The pid of the framework. This was moved to 'optional' in
// 0.24.0 to support schedulers using the HTTP API. For now, we
// continue to always set pid since it was required in 0.23.x.
// When 'pid' is unset, or set to empty string, the slave will
// forward executor messages through the master. For schedulers
// still using the driver, this will remain set.
optional string pid = 3;
} }
...@@ -336,7 +355,9 @@ message ShutdownExecutorMessage { ...@@ -336,7 +355,9 @@ message ShutdownExecutorMessage {
message UpdateFrameworkMessage { message UpdateFrameworkMessage {
required FrameworkID framework_id = 1; required FrameworkID framework_id = 1;
required string pid = 2;
// See the comment on RunTaskMessage.pid.
optional string pid = 2;
} }
......
...@@ -21,6 +21,18 @@ package mesosproto; ...@@ -21,6 +21,18 @@ package mesosproto;
import "mesos.proto"; import "mesos.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message Registry { message Registry {
message Master { message Master {
required MasterInfo info = 1; required MasterInfo info = 1;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -21,6 +21,17 @@ package mesosproto; ...@@ -21,6 +21,17 @@ package mesosproto;
import "mesos.proto"; import "mesos.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
/** /**
* Scheduler event API. * Scheduler event API.
...@@ -40,11 +51,26 @@ message Event { ...@@ -40,11 +51,26 @@ message Event {
MESSAGE = 5; // See 'Message' below. MESSAGE = 5; // See 'Message' below.
FAILURE = 6; // See 'Failure' below. FAILURE = 6; // See 'Failure' below.
ERROR = 7; // See 'Error' below. ERROR = 7; // See 'Error' below.
// Periodic message sent by the Mesos master according to
// 'Subscribed.heartbeat_interval_seconds'. If the scheduler does
// not receive any events (including heartbeats) for an extended
// period of time (e.g., 5 x heartbeat_interval_seconds), there is
// likely a network partition. In such a case the scheduler should
// close the existing subscription connection and resubscribe
// using a backoff strategy.
HEARTBEAT = 8;
} }
// First event received when the scheduler subscribes. // First event received when the scheduler subscribes.
message Subscribed { message Subscribed {
required FrameworkID framework_id = 1; required FrameworkID framework_id = 1;
// This value will be set if the master is sending heartbeats. See
// the comment above on 'HEARTBEAT' for more details.
// TODO(vinod): Implement heartbeats in the master once the master
// can send HTTP events.
optional double heartbeat_interval_seconds = 2;
} }
// Received whenever there are new resources that are offered to the // Received whenever there are new resources that are offered to the
...@@ -152,6 +178,7 @@ message Call { ...@@ -152,6 +178,7 @@ message Call {
ACKNOWLEDGE = 8; // See 'Acknowledge' below. ACKNOWLEDGE = 8; // See 'Acknowledge' below.
RECONCILE = 9; // See 'Reconcile' below. RECONCILE = 9; // See 'Reconcile' below.
MESSAGE = 10; // See 'Message' below. MESSAGE = 10; // See 'Message' below.
REQUEST = 11; // See 'Request' below.
// TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for
// already subscribed frameworks as a way of stopping offers from // already subscribed frameworks as a way of stopping offers from
...@@ -282,6 +309,16 @@ message Call { ...@@ -282,6 +309,16 @@ message Call {
required bytes data = 3; required bytes data = 3;
} }
// Requests a specific set of resources from Mesos's allocator. If
// the allocator has support for this, corresponding offers will be
// sent asynchronously via the OFFERS event(s).
//
// NOTE: The built-in hierarchical allocator doesn't have support
// for this call and hence simply ignores it.
message Request {
repeated mesosproto.Request requests = 1;
}
// Identifies who generated this call. Master assigns a framework id // Identifies who generated this call. Master assigns a framework id
// when a new scheduler subscribes for the first time. Once assigned, // when a new scheduler subscribes for the first time. Once assigned,
// the scheduler must set the 'framework_id' here and within its // the scheduler must set the 'framework_id' here and within its
...@@ -302,4 +339,5 @@ message Call { ...@@ -302,4 +339,5 @@ message Call {
optional Acknowledge acknowledge = 8; optional Acknowledge acknowledge = 8;
optional Reconcile reconcile = 9; optional Reconcile reconcile = 9;
optional Message message = 10; optional Message message = 10;
optional Request request = 11;
} }
...@@ -32,7 +32,6 @@ option (gogoproto.marshaler_all) = true; ...@@ -32,7 +32,6 @@ option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true; option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true; option (gogoproto.unmarshaler_all) = true;
// Describes a state entry, a versioned (via a UUID) key/value pair. // Describes a state entry, a versioned (via a UUID) key/value pair.
message Entry { message Entry {
required string name = 1; required string name = 1;
......
...@@ -22,6 +22,12 @@ import ( ...@@ -22,6 +22,12 @@ import (
const ( const (
DefaultReadTimeout = 5 * time.Second DefaultReadTimeout = 5 * time.Second
DefaultWriteTimeout = 5 * time.Second DefaultWriteTimeout = 5 * time.Second
// writeFlushPeriod is the amount of time we're willing to wait for a single
// response buffer to be fully written to the underlying TCP connection; after
// this amount of time the remaining bytes of the response are discarded. see
// responseWriter().
writeFlushPeriod = 30 * time.Second
) )
type decoderID int32 type decoderID int32
...@@ -75,9 +81,9 @@ type httpDecoder struct { ...@@ -75,9 +81,9 @@ type httpDecoder struct {
cancelGuard sync.Mutex cancelGuard sync.Mutex
readTimeout time.Duration readTimeout time.Duration
writeTimeout time.Duration writeTimeout time.Duration
idtag string // useful for debugging idtag string // useful for debugging
sendError func(err error) // abstraction for error handling sendError func(err error) // abstraction for error handling
outCh chan *bytes.Buffer outCh chan *bytes.Buffer // chan of responses to be written to the connection
} }
// DecodeHTTP hijacks an HTTP server connection and generates mesos libprocess HTTP // DecodeHTTP hijacks an HTTP server connection and generates mesos libprocess HTTP
...@@ -135,27 +141,13 @@ func (d *httpDecoder) Cancel(graceful bool) { ...@@ -135,27 +141,13 @@ func (d *httpDecoder) Cancel(graceful bool) {
func (d *httpDecoder) run(res http.ResponseWriter) { func (d *httpDecoder) run(res http.ResponseWriter) {
defer func() { defer func() {
close(d.outCh) close(d.outCh) // we're finished generating response objects
log.V(2).Infoln(d.idtag + "run: terminating") log.V(2).Infoln(d.idtag + "run: terminating")
}() }()
go func() { for state := d.bootstrapState(res); state != nil; {
for buf := range d.outCh { next := state(d)
select { state = next
case <-d.forceQuit:
return
default:
}
//TODO(jdef) I worry about this busy-looping
for buf.Len() > 0 {
d.tryFlushResponse(buf)
}
}
}()
var next httpState
for state := d.bootstrapState(res); state != nil; state = next {
next = state(d)
} }
} }
...@@ -358,6 +350,7 @@ func limit(r *bufio.Reader, limit int64) *io.LimitedReader { ...@@ -358,6 +350,7 @@ func limit(r *bufio.Reader, limit int64) *io.LimitedReader {
// is ready to be hijacked at this point. // is ready to be hijacked at this point.
func (d *httpDecoder) bootstrapState(res http.ResponseWriter) httpState { func (d *httpDecoder) bootstrapState(res http.ResponseWriter) httpState {
log.V(2).Infoln(d.idtag + "bootstrap-state") log.V(2).Infoln(d.idtag + "bootstrap-state")
d.updateForRequest() d.updateForRequest()
// hijack // hijack
...@@ -373,11 +366,44 @@ func (d *httpDecoder) bootstrapState(res http.ResponseWriter) httpState { ...@@ -373,11 +366,44 @@ func (d *httpDecoder) bootstrapState(res http.ResponseWriter) httpState {
d.sendError(errHijackFailed) d.sendError(errHijackFailed)
return terminateState return terminateState
} }
d.rw = rw d.rw = rw
d.con = c d.con = c
go d.responseWriter()
return d.readBodyContent() return d.readBodyContent()
} }
func (d *httpDecoder) responseWriter() {
defer func() {
log.V(3).Infoln(d.idtag + "response-writer: closing connection")
d.con.Close()
}()
for buf := range d.outCh {
//TODO(jdef) I worry about this busy-looping
// write & flush the buffer until there's nothing left in it, or else
// we exceed the write/flush period.
now := time.Now()
for buf.Len() > 0 && time.Since(now) < writeFlushPeriod {
select {
case <-d.forceQuit:
return
default:
}
d.tryFlushResponse(buf)
}
if buf.Len() > 0 {
//TODO(jdef) should we abort the entire connection instead? a partially written
// response doesn't do anyone any good. That said, real libprocess agents don't
// really care about the response channel anyway - the entire system is fire and
// forget. So I've decided to err on the side that we might lose response bytes
// in favor of completely reading the connection request stream before we terminate.
log.Errorln(d.idtag + "failed to fully flush output buffer within write-flush period")
}
}
}
type body struct { type body struct {
*bytes.Buffer *bytes.Buffer
} }
......
...@@ -44,6 +44,18 @@ var ( ...@@ -44,6 +44,18 @@ var (
errNotStarted = errors.New("HTTP transport has not been started") errNotStarted = errors.New("HTTP transport has not been started")
errTerminal = errors.New("HTTP transport is terminated") errTerminal = errors.New("HTTP transport is terminated")
errAlreadyRunning = errors.New("HTTP transport is already running") errAlreadyRunning = errors.New("HTTP transport is already running")
httpTransport, httpClient = &http.Transport{
Dial: (&net.Dialer{
Timeout: 10 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
},
&http.Client{
Transport: httpTransport,
Timeout: DefaultReadTimeout,
}
) )
// httpTransporter is a subset of the Transporter interface // httpTransporter is a subset of the Transporter interface
...@@ -114,7 +126,7 @@ type HTTPTransporter struct { ...@@ -114,7 +126,7 @@ type HTTPTransporter struct {
listener net.Listener // TODO(yifan): Change to TCPListener. listener net.Listener // TODO(yifan): Change to TCPListener.
mux *http.ServeMux mux *http.ServeMux
tr *http.Transport tr *http.Transport
client *http.Client // TODO(yifan): Set read/write deadline. client *http.Client
messageQueue chan *Message messageQueue chan *Message
address net.IP // optional binding address address net.IP // optional binding address
shouldQuit chan struct{} shouldQuit chan struct{}
...@@ -124,13 +136,12 @@ type HTTPTransporter struct { ...@@ -124,13 +136,12 @@ type HTTPTransporter struct {
// NewHTTPTransporter creates a new http transporter with an optional binding address. // NewHTTPTransporter creates a new http transporter with an optional binding address.
func NewHTTPTransporter(upid upid.UPID, address net.IP) *HTTPTransporter { func NewHTTPTransporter(upid upid.UPID, address net.IP) *HTTPTransporter {
tr := &http.Transport{}
result := &HTTPTransporter{ result := &HTTPTransporter{
upid: upid, upid: upid,
messageQueue: make(chan *Message, defaultQueueSize), messageQueue: make(chan *Message, defaultQueueSize),
mux: http.NewServeMux(), mux: http.NewServeMux(),
client: &http.Client{Transport: tr}, client: httpClient,
tr: tr, tr: httpTransport,
address: address, address: address,
shouldQuit: make(chan struct{}), shouldQuit: make(chan struct{}),
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment