// 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.

syntax = "proto2";

import "mesos/mesos.proto";

package mesos.scheduler;

option cc_enable_arenas = true;

option java_package = "org.apache.mesos.scheduler";
option java_outer_classname = "Protos";


/**
 * Scheduler event API.
 *
 * An event is described using the standard protocol buffer "union"
 * trick, see:
 * https://developers.google.com/protocol-buffers/docs/techniques#union.
 */
message Event {
  // Possible event types, followed by message definitions if
  // applicable.
  enum Type {
    // This must be the first enum value in this list, to
    // ensure that if 'type' is not set, the default value
    // is UNKNOWN. This enables enum values to be added
    // in a backwards-compatible way. See: MESOS-4997.
    UNKNOWN = 0;

    SUBSCRIBED = 1;               // See 'Subscribed' below.
    OFFERS = 2;                   // See 'Offers' below.
    INVERSE_OFFERS = 9;           // See 'InverseOffers' below.
    RESCIND = 3;                  // See 'Rescind' below.
    RESCIND_INVERSE_OFFER = 10;   // See 'RescindInverseOffer' below.
    UPDATE = 4;                   // See 'Update' below.
    UPDATE_OPERATION_STATUS = 11; // See 'UpdateOperationStatus' below.
    MESSAGE = 5;                  // See 'Message' below.
    FAILURE = 6;                  // See 'Failure' 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.
  message Subscribed {
    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.
    optional double heartbeat_interval_seconds = 2;

    // Since Mesos 1.1.
    optional MasterInfo master_info = 3;
  }

  // Received whenever there are new resources that are offered to the
  // scheduler. Each offer corresponds to a set of resources on an
  // agent. Until the scheduler accepts or declines an offer the
  // resources are considered allocated to the scheduler.
  message Offers {
    repeated Offer offers = 1;
  }

  // Received whenever there are resources requested back from the
  // scheduler. Each inverse offer specifies the agent, and
  // optionally specific resources. Accepting or Declining an inverse
  // offer informs the allocator of the scheduler's ability to release
  // the specified resources without violating an SLA. If no resources
  // are specified then all resources on the agent are requested to be
  // released.
  message InverseOffers {
    repeated InverseOffer inverse_offers = 1;
  }

  // Received when a particular offer is no longer valid (e.g., the
  // slave corresponding to the offer has been removed) and hence
  // needs to be rescinded. Any future calls ('Accept' / 'Decline') made
  // by the scheduler regarding this offer will be invalid.
  message Rescind {
    required OfferID offer_id = 1;
  }

  // Received when a particular inverse offer is no longer valid
  // (e.g., the agent corresponding to the offer has been removed)
  // and hence needs to be rescinded. Any future calls ('Accept' /
  // 'Decline') made by the scheduler regarding this inverse offer
  // will be invalid.
  message RescindInverseOffer {
    required OfferID inverse_offer_id = 1;
  }

  // Received whenever there is a status update that is generated by
  // the executor or slave or master. Status updates should be used by
  // executors to reliably communicate the status of the tasks that
  // they manage. It is crucial that a terminal update (see TaskState
  // in mesos.proto) is sent by the executor as soon as the task
  // terminates, in order for Mesos to release the resources allocated
  // to the task. It is also the responsibility of the scheduler to
  // explicitly acknowledge the receipt of a status update. See
  // 'Acknowledge' in the 'Call' section below for the semantics.
  //
  // A task status update may be used for guaranteed delivery of some
  // task-related information, e.g., task's health update. Such
  // information may be shadowed by subsequent task status updates, that
  // do not preserve fields of the previously sent message.
  message Update {
    required TaskStatus status = 1;
  }

  // EXPERIMENTAL.
  //
  // Received when there is an operation status update generated by the master,
  // agent, or resource provider. These updates are only sent to the framework
  // for operations which had the operation ID set by the framework. It is the
  // responsibility of the scheduler to explicitly acknowledge the receipt of a
  // status update.
  // See 'AcknowledgeOperationStatus' in the 'Call' section below for the
  // semantics.
  message UpdateOperationStatus {
    required OperationStatus status = 1;
  }

  // Received when a custom message generated by the executor is
  // forwarded by the master. Note that this message is not
  // interpreted by Mesos and is only forwarded (without reliability
  // guarantees) to the scheduler. It is up to the executor to retry
  // if the message is dropped for any reason.
  message Message {
    required SlaveID slave_id = 1;
    required ExecutorID executor_id = 2;
    required bytes data = 3;
  }

  // Received when a slave is removed from the cluster (e.g., failed
  // health checks) or when an executor is terminated. Note that, this
  // event coincides with receipt of terminal UPDATE events for any
  // active tasks belonging to the slave or executor and receipt of
  // 'Rescind' events for any outstanding offers belonging to the
  // slave. Note that there is no guaranteed order between the
  // 'Failure', 'Update' and 'Rescind' events when a slave or executor
  // is removed.
  // TODO(vinod): Consider splitting the lost slave and terminated
  // executor into separate events and ensure it's reliably generated.
  message Failure {
    optional SlaveID slave_id = 1;

    // If this was just a failure of an executor on a slave then
    // 'executor_id' will be set and possibly 'status' (if we were
    // able to determine the exit status).
    optional ExecutorID executor_id = 2;

    // On Posix, `status` corresponds to termination information in the
    // `stat_loc` area returned from a `waitpid` call. On Windows, `status`
    // is obtained via calling the `GetExitCodeProcess()` function. For
    // messages coming from Posix agents, schedulers need to apply
    // `WEXITSTATUS` family macros or equivalent transformations to obtain
    // exit codes.
    //
    // TODO(alexr): Consider unifying Windows and Posix behavior by returning
    // exit code here, see MESOS-7241.
    optional int32 status = 3;
  }

  // Received when there is an unrecoverable error in the scheduler (e.g.,
  // scheduler failed over, rate limiting, authorization errors etc.). The
  // scheduler should abort on receiving this event.
  message Error {
    required string message = 1;
  }

  // Type of the event, indicates which optional field below should be
  // present if that type has a nested message definition.
  // Enum fields should be optional, see: MESOS-4997.
  optional Type type = 1;

  optional Subscribed subscribed = 2;
  optional Offers offers = 3;
  optional InverseOffers inverse_offers = 9;
  optional Rescind rescind = 4;
  optional RescindInverseOffer rescind_inverse_offer = 10;
  optional Update update = 5;
  optional UpdateOperationStatus update_operation_status = 11;
  optional Message message = 6;
  optional Failure failure = 7;
  optional Error error = 8;
}


/**
 * NOTE: After resolution of MESOS-9648, this message is not currently used by
 * Mesos. It is left in place in anticipation of future use.
 *
 * Synchronous responses for calls made to the scheduler API.
 */
message Response {
  // Each of the responses of type `FOO` corresponds to `Foo` message below.
  enum Type {
    UNKNOWN = 0;

    // DEPRECATED.
    //
    // See 'ReconcileOperations' below.
    RECONCILE_OPERATIONS = 1 [deprecated = true];
  }

  // DEPRECATED.
  message ReconcileOperations {
    repeated OperationStatus operation_statuses = 1;
  }

  optional Type type = 1;

  // DEPRECATED.
  optional ReconcileOperations reconcile_operations = 2;
}


// An attribute constraint consists of a Predicate: a boolean function of
// an attribute or an attribute-like property of an agent (a pseudoattribute),
// and a Selector: a rule for obtaining this (pseudo)attribute value from
// AgentInfo.
//
// The attribute constraint evaluates to `true` for a given agent if and only
// if the predicate yields `true` for the specified (pseudo)attribute.
message AttributeConstraint {
  message Selector {
    enum PseudoattributeType {
      UNKNOWN = 0;
      HOSTNAME = 1;
      REGION = 2;
      ZONE = 3;
    }

    oneof selector {
      // The predicate will be applied to the specified pseudoattribute.
      PseudoattributeType pseudoattribute_type = 1;

      // The predicate will be applied to the first attribute with the specified
      // name. Note that an agent can have multiple attributes with the same
      // name, and that the order of attributes is preserved by Mesos.
      //
      // TODO(asekretenko): If a need to handle the multiple-attribute
      // case differently arises, in simple cases it can be addressed by adding
      // a Selector-wide flag or one more oneof member here.
      string attribute_name = 2;
    }
  }

  message Predicate {
    // Yields `true` if the (pseudo)attribute exists.
    message Exists {}

    // Yields `true` if the (pseudo)attribute does not exist.
    message NotExists {}

    // Predicates for (pseudo)attribute value equality.
    //
    // Given that existing schedulers tend to test SCALAR and RANGES attributes
    // of offered agents for equality in ways that are not entirely trivial,
    // we currently only support TEXT (string for pseudoattributes)
    // equality.
    //
    // Both equality predicates will match (yield `true`) for attributes of
    // SCALAR and RANGES types. This way, schedulers will still receive offers
    // for SCALAR and RANGES attributes if a string equality constraint was
    // specified to Mesos, and the scheduler's own logic will determine how to
    // filter attributes of these types.
    //
    // For example: if a scheduler sets a constraint
    //
    //   { "selector": {"attribute_name": "foo"},
    //     "predicate": {"text_equals": {"value":"2.0"}} }
    //
    // then agents with a SCALAR attribute
    // {"name": "foo", "scalar": {"value": 1.0}}
    // will match (since it's SCALAR, not TEXT!) and the scheduler side
    // filtering will need to filter it according to its desired semantics.
    //
    // That said, it is strongly recommended to only use TEXT attributes
    // on agents. For users with existing attributes, this can be done
    // by adding a variant of the existing attribute that uses TEXT instead:
    //
    //   --attributes=foo2:v1.0
    //   which gets parsed into
    //   {"name": "foo2", "text": {"value": "v1.0"}}, etc.

    // Yields `true` if the (pseudo)attribute exists and is a string/TEXT
    // equal to the specified `value`.
    //
    // Always yields `true` for existing non-TEXT attributes (and non-string
    // pseudoattributes) for the reason explained above.
    message TextEquals {
      required string value = 1;
    }

    // Yields `true` if the (pseudo)attribute does not exist or is a string/TEXT
    // NOT equal to the specified `value`.
    //
    // Always yields `true` for existing non-TEXT attributes (and non-string
    // pseudoattributes) for the reason explained above.
    message TextNotEquals {
      required string value = 1;
    }

    // Predicates for regular expression constraints.
    //
    // The regular expressions are interpreted according to
    // RE2 regular expression syntax and semantics:
    // https://github.com/google/re2/blob/master/doc/syntax.txt
    //
    // The call using the constraints is invalid if the specified string is not
    // a valid RE2 regex, or the regex is deemed too expensive to
    // construct/store/execute, namely:
    //
    //  - the RE2 object cannot be constructed from the regex without breaching
    //    the limit on the estimated memory footprint of an individual RE2
    //    (controlled by the --offer_constraints_re2_max_mem master flag), or
    //
    //  - the regex program size reported by `RE2::ProgramSize()`
    //    exceeds the value of --offer_constraints_re2_max_program_size flag.
    //
    // Frameworks using the C++ implementation of RE2 (directly or via the JNI
    // wrapper) for regexp validation on their side, are advised to set
    // the `max_mem` RE2 option and limit `ProgramSize()` to values no larger
    // than the defaults for the corresonding Mesos master flags.
    //
    // TODO(asekretenko): Provide an API for the frameworks and/or operators
    // to validate regexp constraints against the Mesos master setup.
    //
    // Similarly to the string equality predicates, both regexp predicates match
    // (evaluate to `true`) when the (pseudo)attribute is not a TEXT/string.
    // This way, schedulers will have to apply purely on their own
    // whatever filtration they do for non-TEXT attributes which happen
    // to be selected by the constraint's `Selector`

    // Yields `true` if the (pseudo)attribute exists and is a TEXT/string
    // matching the specified regex.
    //
    // Always yields `true` for existing non-TEXT attributes (and non-string
    // pseudoattributes) for the reasons explained above.
    message TextMatches {
      required string regex = 1;
    }

    // Yields `true` if the (pseudo)attribute either does not exists or is
    // not a TEXT/string matching the specified regex.
    //
    // Always yields `true` for existing non-TEXT attributes (and non-string
    // pseudoattributes) for the reasons explained above.
    message TextNotMatches {
      required string regex = 1;
    }

    oneof predicate {
      Exists exists = 1;
      NotExists not_exists = 2;

      TextEquals text_equals = 3;
      TextNotEquals text_not_equals = 4;

      TextMatches text_matches = 5;
      TextNotMatches text_not_matches = 6;
    }
  }

  required Selector selector = 1;
  required Predicate predicate = 2;
}

// Frameworks can express offer constraints for their roles.
//
// Constraints restrict which offers will be sent to the framework:
// if an offer does not match the provided constraints, it will not
// be sent to the framework.
//
// Constraints are expressed on a per role basis. If you consider a
// scheduler that has multiple apps to launch within a single role,
// the structure of the constraints for that role looks as follows:
//
//    app 1              app 2                         app N
// constraints   OR   constraints   OR   ...   OR   constraints
//                        /\
//                       /  \
//    constraint 1 AND constraint 2 AND ... AND constraint M
//
// That is, at least one of the constraint groups must match for an offer to
// be generated, and within a group all the constraints must match.
//
// As a concrete example, consider a scheduler with two applications
// with multiple tasks it wants to launch within a role:
//
// application 1: all tasks on an agent with a hostname == "foo"
// application 2: each task on an agent with an unique "rack" attribute
//
// Assuming there are already some instances of application 2 launched,
// the constraints might look like the following:
//
//      app 1              app 2
//  constraints    OR    constraints
//       /\                 /\
//      /  \               /  \
// hostname == "foo"    rack != "X" AND
//                      rack != "Y" AND
//                      rack != "Z"
//
//                   ==
//
//         (hostname == "foo")
//                   OR
// (rack != "X" AND rack != "Y" AND rack != "Z")
//
// The benefits of expressing constraints are:
//
// (1) reduced fraction of unusable offers received, and hence:
// (2) reduced traffic and processing overhead due to unusable
// offer / DECLINE back and forth churn
// (3) most importantly, reduced latency to receive the desired
// offer for a particular task
//
// NOTE: Even if a particular resource matches offer constraints of a
// framework's role, there is still no guarantee that it will ever be offered
// to this role of the framework.
//
// NOTE: Each `Group` must contain at least one constraint, and
// `RoleConstraints` must contain at least one `Group`, otherwise
// the message is not valid.
//
// NOTE: Frameworks are allowed to use default-constructed
// `OfferConstraints` (instead of not setting the `offer_constraints` field)
// in the SUBSCRIBE/UPDATE_FRAMEWORK calls to indicate subscription without
// any offer constraints.
message OfferConstraints {
  message RoleConstraints {
    message Group {
      repeated AttributeConstraint attribute_constraints = 1;

      // TODO(asekretenko): Implement resource-based constraints to extend
      // functionality of OfferFilters and to allow for precise filtering
      // of reservations.
    }

    repeated Group groups = 1;
  }

  map<string, RoleConstraints> role_constraints = 1;
}


/**
 * Scheduler call API.
 *
 * Like Event, a Call is described using the standard protocol buffer
 * "union" trick (see above).
 */
message Call {
  // Possible call types, followed by message definitions if
  // applicable.
  enum Type {
    // See comments above on `Event::Type` for more details on this enum value.
    UNKNOWN = 0;

    SUBSCRIBE = 1;   // See 'Subscribe' below.
    TEARDOWN = 2;    // Shuts down all tasks/executors and removes framework.
    ACCEPT = 3;      // See 'Accept' below.
    DECLINE = 4;     // See 'Decline' below.
    ACCEPT_INVERSE_OFFERS = 13;  // See 'AcceptInverseOffers' below.
    DECLINE_INVERSE_OFFERS = 14; // See 'DeclineInverseOffers' below.
    REVIVE = 5;      // Removes any previous filters set via ACCEPT or DECLINE.
    KILL = 6;        // See 'Kill' below.
    SHUTDOWN = 7;    // See 'Shutdown' below.
    ACKNOWLEDGE = 8; // See 'Acknowledge' below.
    ACKNOWLEDGE_OPERATION_STATUS = 15; // See message below.
    RECONCILE = 9;   // See 'Reconcile' below.
    RECONCILE_OPERATIONS = 16; // See 'ReconcileOperations' below.
    MESSAGE = 10;    // See 'Message' below.
    REQUEST = 11;    // See 'Request' below.
    SUPPRESS = 12;   // Inform master to stop sending offers to the framework.
    UPDATE_FRAMEWORK = 17; // See `UpdateFramework` below.

    // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for
    // already subscribed frameworks as a way of stopping offers from
    // being generated and other events from being sent by the master.
    // Note that this functionality existed originally to support
    // SchedulerDriver::abort which was only necessary to handle
    // exceptions getting thrown from within Scheduler callbacks,
    // something that is not an issue with the Event/Call API.
  }

  // Subscribes the scheduler with the master to receive events. A
  // scheduler must send other calls only after it has received the
  // SUBCRIBED event.
  message Subscribe {
    // See the comments below on 'framework_id' on the semantics for
    // 'framework_info.id'.
    required FrameworkInfo framework_info = 1;

    // NOTE: 'force' field is not present in v1/scheduler.proto because it is
    // only used by the scheduler driver. The driver sets it to true when the
    // scheduler reregisters for the first time after a failover. Once
    // reregistered all subsequent re-registration attempts (e.g., due to ZK
    // blip) will have 'force' set to false. This is important because master
    // uses this field to know when it needs to send FrameworkRegisteredMessage
    // vs FrameworkReregisteredMessage.
    optional bool force = 2;

    // List of suppressed roles for which the framework does not wish to be
    // offered resources. The framework can decide to suppress all or a subset
    // of roles the framework (re)registers as.
    //
    // Note: This field is not set by scheduler driver, so will always be
    // empty. It is added here for transformation from `v1::Call::Subscribe`.
    repeated string suppressed_roles = 3;

    optional OfferConstraints offer_constraints = 4;
  }

  // Accepts an offer, performing the specified operations
  // in a sequential manner.
  //
  // E.g. Launch a task with a newly reserved persistent volume:
  //
  //   Accept {
  //     offer_ids: [ ... ]
  //     operations: [
  //       { type: RESERVE,
  //         reserve: { resources: [ disk(role):2 ] } }
  //       { type: CREATE,
  //         create: { volumes: [ disk(role):1+persistence ] } }
  //       { type: LAUNCH,
  //         launch: { task_infos ... disk(role):1;disk(role):1+persistence } }
  //     ]
  //   }
  //
  // NOTE: Any of the offer's resources not used in the `Accept` call
  // (e.g., to launch a task) are considered unused and might be
  // reoffered to other frameworks. In other words, the same `OfferID`
  // cannot be used in more than one `Accept` call.
  // NOTE: All offers must belong to the same agent.
  message Accept {
    repeated OfferID offer_ids = 1;
    repeated Offer.Operation operations = 2;
    optional Filters filters = 3;
  }

  // Declines an offer, signaling the master to potentially reoffer
  // the resources to a different framework. Note that this is same
  // as sending an Accept call with no operations. See comments on
  // top of 'Accept' for semantics.
  message Decline {
    repeated OfferID offer_ids = 1;
    optional Filters filters = 2;
  }

  // Accepts an inverse offer. Inverse offers should only be accepted
  // if the resources in the offer can be safely evacuated before the
  // provided unavailability.
  message AcceptInverseOffers {
    repeated OfferID inverse_offer_ids = 1;
    optional Filters filters = 2;
  }

  // Declines an inverse offer. Inverse offers should be declined if
  // the resources in the offer might not be safely evacuated before
  // the provided unavailability.
  message DeclineInverseOffers {
    repeated OfferID inverse_offer_ids = 1;
    optional Filters filters = 2;
  }

  // Revive offers for the specified roles. If `roles` is empty,
  // the `REVIVE` call will revive offers for all of the roles
  // the framework is currently subscribed to.
  message Revive {
    repeated string roles = 1;
  }

  // Kills a specific task. If the scheduler has a custom executor,
  // the kill is forwarded to the executor and it is up to the
  // executor to kill the task and send a TASK_KILLED (or TASK_FAILED)
  // update. Note that Mesos releases the resources for a task once it
  // receives a terminal update (See TaskState in mesos.proto) for it.
  // If the task is unknown to the master, a TASK_LOST update is
  // generated.
  //
  // If a task within a task group is killed before the group is
  // delivered to the executor, all tasks in the task group are
  // killed. When a task group has been delivered to the executor,
  // it is up to the executor to decide how to deal with the kill.
  // Note The default Mesos executor will currently kill all the
  // tasks in the task group if it gets a kill for any task.
  message Kill {
    required TaskID task_id = 1;
    optional SlaveID slave_id = 2;

    // If set, overrides any previously specified kill policy for this task.
    // This includes 'TaskInfo.kill_policy' and 'Executor.kill.kill_policy'.
    // Can be used to forcefully kill a task which is already being killed.
    optional KillPolicy kill_policy = 3;
  }

  // Shuts down a custom executor. When the executor gets a shutdown
  // event, it is expected to kill all its tasks (and send TASK_KILLED
  // updates) and terminate. If the executor doesn't terminate within
  // a certain timeout (configurable via
  // '--executor_shutdown_grace_period' slave flag), the slave will
  // forcefully destroy the container (executor and its tasks) and
  // transition its active tasks to TASK_LOST.
  message Shutdown {
    required ExecutorID executor_id = 1;
    required SlaveID slave_id = 2;
  }

  // Acknowledges the receipt of status update. Schedulers are
  // responsible for explicitly acknowledging the receipt of status
  // updates that have 'Update.status().uuid()' field set. Such status
  // updates are retried by the slave until they are acknowledged by
  // the scheduler.
  message Acknowledge {
    required SlaveID slave_id = 1;
    required TaskID task_id = 2;
    required bytes uuid = 3;
  }

  // EXPERIMENTAL.
  //
  // Acknowledges the receipt of an operation status update. Schedulers
  // are responsible for explicitly acknowledging the receipt of updates
  // which have the 'UpdateOperationStatus.status().uuid()' field set.
  // Such status updates are retried by the agent or resource provider until
  // they are acknowledged by the scheduler.
  message AcknowledgeOperationStatus {
    // If the operation affects resources that belong to a SLRP, both
    // `slave_id` and `resource_provider_id` have to be set.
    //
    // If the operation affects resources that belong to a SERP, only
    // `resource_provider_id` has to be set.
    optional SlaveID slave_id = 1;
    optional ResourceProviderID resource_provider_id = 2;

    required bytes uuid = 3;
    required OperationID operation_id = 4;
  }

  // Allows the scheduler to query the status for non-terminal tasks.
  // This causes the master to send back the latest task status for
  // each task in 'tasks', if possible. Tasks that are no longer known
  // will result in a TASK_LOST, TASK_UNKNOWN, or TASK_UNREACHABLE update.
  // If 'tasks' is empty, then the master will send the latest status
  // for each task currently known.
  message Reconcile {
    // TODO(vinod): Support arbitrary queries than just state of tasks.
    message Task {
      required TaskID task_id = 1;
      optional SlaveID slave_id = 2;
    }

    repeated Task tasks = 1;
  }

  // EXPERIMENTAL.
  //
  // Allows the scheduler to query the status of operations. This causes the
  // master to send back the latest status for each operation in 'operations',
  // if possible. If 'operations' is empty, then the master will send the
  // latest status for each operation currently known.
  message ReconcileOperations {
    message Operation {
      required OperationID operation_id = 1;
      optional SlaveID slave_id = 2;
      optional ResourceProviderID resource_provider_id = 3;
    }

    repeated Operation operations = 1;
  }

  // Sends arbitrary binary data to the executor. Note that Mesos
  // neither interprets this data nor makes any guarantees about the
  // delivery of this message to the executor.
  message Message {
    required SlaveID slave_id = 1;
    required ExecutorID executor_id = 2;
    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 mesos.Request requests = 1;
  }

  // Suppress offers for the specified roles. If `roles` is empty,
  // the `SUPPRESS` call will suppress offers for all of the roles
  // the framework is currently subscribed to.
  message Suppress {
    repeated string roles = 1;
  }

  // Updates the FrameworkInfo. All fields can be updated except for:
  //
  // * FrameworkInfo.checkpoint
  // * FrameworkInfo.principal
  // * FrameworkInfo.user
  //
  // The call returns after the update is either applied completely or
  // not applied at all. No incomplete updates occur.
  //
  // The HTTP response codes specific to this call are:
  //
  // * 200 OK: update operation was successfully completed.
  // * 400 Bad Request: the requested update is not valid.
  // * 403 Forbidden: framework is not authorized to use some entities
  //   requested by the update (e.g. not authorized to use some of the
  //   supplied roles).
  // * 409 Conflict: framework disappeared while this call was being processed
  //   (example: the framework was removed by a concurrent TEARDOWN call).
  //
  message UpdateFramework {
    required FrameworkInfo framework_info = 1;

    // List of suppressed roles for which the framework does not wish to be
    // offered resources. The framework can decide to suppress all or a subset
    // of roles provided in the new `framework_info`.
    repeated string suppressed_roles = 2;

    optional OfferConstraints offer_constraints = 3;
  }

  // Identifies who generated this call. Master assigns a framework id
  // when a new scheduler subscribes for the first time. Once assigned,
  // the scheduler must set the 'framework_id' here and within its
  // FrameworkInfo (in any further 'Subscribe' calls). This allows the
  // master to identify a scheduler correctly across disconnections,
  // failovers, etc.
  optional FrameworkID framework_id = 1;

  // Type of the call, indicates which optional field below should be
  // present if that type has a nested message definition.
  // See comments on `Event::Type` above on the reasoning behind this field
  // being optional.
  optional Type type = 2;

  optional Subscribe subscribe = 3;
  optional Accept accept = 4;
  optional Decline decline = 5;
  optional AcceptInverseOffers accept_inverse_offers = 13;
  optional DeclineInverseOffers decline_inverse_offers = 14;
  optional Revive revive = 15;
  optional Kill kill = 6;
  optional Shutdown shutdown = 7;
  optional Acknowledge acknowledge = 8;
  optional AcknowledgeOperationStatus acknowledge_operation_status = 17;
  optional Reconcile reconcile = 9;
  optional ReconcileOperations reconcile_operations = 18;
  optional Message message = 10;
  optional Request request = 11;
  optional Suppress suppress = 16;
  optional UpdateFramework update_framework = 19;
}
