// 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/v1/mesos.proto";

package mesos.v1.scheduler;

option java_package = "org.apache.mesos.v1.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
  // 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 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 agent 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 v1/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 AgentID agent_id = 1;
    required ExecutorID executor_id = 2;
    required bytes data = 3;
  }

  // Received when an agent 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 agent or executor and receipt of
  // 'Rescind' events for any outstanding offers belonging to the
  // agent. Note that there is no guaranteed order between the
  // 'Failure', 'Update' and 'Rescind' events when an agent or executor
  // is removed.
  // TODO(vinod): Consider splitting the lost agent and terminated
  // executor into separate events and ensure it's reliably generated.
  message Failure {
    optional AgentID agent_id = 1;

    // If this was just a failure of an executor on an agent 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 [deprecated = true];
  }

  optional Type type = 1;

  // DEPRECATED.
  optional ReconcileOperations reconcile_operations = 2 [deprecated = true];
}


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

    // 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.
    repeated string suppressed_roles = 2;

    optional OfferConstraints offer_constraints = 3;
  }

  // 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 that 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.
  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 v1/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 AgentID agent_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' agent flag), the agent 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 AgentID agent_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 agent until they are acknowledged by
  // the scheduler.
  message Acknowledge {
    required AgentID agent_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
    // `agent_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 AgentID agent_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 AgentID agent_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;

      // If `agent_id` is not set and the master doesn't know the operation,
      // then it will return `OPERATION_UNKNOWN`; if `agent_id` is set, it can
      // return more fine-grained states depending on the state of the
      // corresponding agent.
      optional AgentID agent_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 AgentID agent_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.v1.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;
}

/**
 * EXPERIMENTAL.
 *
 * This message is used by the C++ Scheduler HTTP API library as the return
 * type of the `call()` method. The message includes the HTTP status code with
 * which the master responded, and optionally a `scheduler::Response` message.
 *
 * There are three cases to consider depending on the HTTP response status code:
 *
 *  (1) '202 ACCEPTED': Indicates the call was accepted for processing and
 *        neither `response` nor `error` will be set.
 *
 *  (2) '200 OK': Indicates the call completed successfully, and the `response`
 *        field will be set if the `scheduler::Call::Type` has a corresponding
 *        `scheduler::Response::Type`; `error` will not be set.
 *
 *  (3) For all other HTTP status codes, the `response` field will not be set
 *      and the `error` field may be set to provide more information.
 *
 * NOTE: This message is used by the C++ Scheduler HTTP API library and is not
 * part of the API specification.
 */
message APIResult {
  // HTTP status code with which the master responded.
  required uint32 status_code = 1;

  // NOTE: After resolution of MESOS-9648, this field is not currently used by
  // Mesos. It is left in place in anticipation of future use.
  //
  // This field will only be set if the call completed successfully and the
  // master responded with `200 OK` and a non-empty body.
  optional Response response = 2;

  // This field will only be set if the call did not complete successfully and
  // the master responded with a status other than `202 Accepted` or `200 OK`,
  // and with a non-empty body.
  optional string error = 3;
}
