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

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


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

    RECONCILE_OPERATIONS = 1; // See 'ReconcileOperations' below.
  }

  message ReconcileOperations {
    repeated OperationStatus operation_statuses = 1;
  }

  optional Type type = 1;
  optional ReconcileOperations reconcile_operations = 2;
}


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

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

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

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

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

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