blob: f76118bbf028610c330cebe937d81457fc67a6f3 [file] [log] [blame]
/**
* 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.
*/
#ifndef __MESOS_MASTER_ALLOCATOR_HPP__
#define __MESOS_MASTER_ALLOCATOR_HPP__
#include <string>
#include <vector>
// ONLY USEFUL AFTER RUNNING PROTOC.
#include <mesos/master/allocator.pb.h>
#include <mesos/maintenance/maintenance.hpp>
#include <mesos/quota/quota.hpp>
#include <mesos/resources.hpp>
#include <process/future.hpp>
#include <stout/duration.hpp>
#include <stout/hashmap.hpp>
#include <stout/hashset.hpp>
#include <stout/lambda.hpp>
#include <stout/option.hpp>
#include <stout/try.hpp>
namespace mesos {
namespace master {
namespace allocator {
/**
* Basic model of an allocator: resources are allocated to a framework
* in the form of offers. A framework can refuse some resources in
* offers and run tasks in others. Allocated resources can have offer
* operations applied to them in order for frameworks to alter the
* resource metadata (e.g. creating persistent volumes). Resources can
* be recovered from a framework when tasks finish/fail (or are lost
* due to an agent failure) or when an offer is rescinded.
*
* This is the public API for resource allocators.
*/
class Allocator
{
public:
/**
* Attempts either to create a built-in DRF allocator or to load an
* allocator instance from a module using the given name. If `Try`
* does not report an error, the wrapped `Allocator*` is not null.
*
* @param name Name of the allocator.
*/
static Try<Allocator*> create(const std::string& name);
Allocator() {}
virtual ~Allocator() {}
/**
* Initializes the allocator.
*
* Initializes the allocator, it is invoked when the master starts up.
* Any errors in initialization should fail fast and result in an ABORT.
* The master expects the allocator to be successfully initialized if
* this call returns.
*
* @param allocationInterval The allocate interval for the allocator, it
* determines how often the allocator should perform the batch
* allocation. An allocator may also perform allocation based on events
* (a framework is added and so on), this depends on the implementation.
* @param offerCallback A callback the allocator uses to send allocations
* to the frameworks.
* @param inverseOfferCallback A callback the allocator uses to send reclaim
* allocations from the frameworks.
* @param roles The roles are actually checked by the master (see
* Master::subscribe). All frameworks that are added to the allocator
* will fall into one of these roles.
*/
virtual void initialize(
const Duration& allocationInterval,
const lambda::function<
void(const FrameworkID&,
const hashmap<SlaveID, Resources>&)>& offerCallback,
const lambda::function<
void(const FrameworkID&,
const hashmap<SlaveID, UnavailableResources>&)>&
inverseOfferCallback,
const hashmap<std::string, RoleInfo>& roles) = 0;
/**
* Adds a framework.
*
* Adds a framework to the Mesos cluster. The allocator is invoked when
* a new framework joins the Mesos cluster and is entitled to participate
* in resource sharing.
*
* @param used Resources used by this framework. The allocator should
* account for these resources when updating the allocation of this
* framework.
*/
virtual void addFramework(
const FrameworkID& frameworkId,
const FrameworkInfo& frameworkInfo,
const hashmap<SlaveID, Resources>& used) = 0;
/**
* Removes a framework.
*
* Removes a framework from the Mesos cluster. It is up to an allocator to
* decide what to do with framework's resources. For example, they may be
* released and added back to the shared pool of resources.
*/
virtual void removeFramework(
const FrameworkID& frameworkId) = 0;
/**
* Activates a framework.
*
* Activates a framework in the Mesos cluster. Offers are only sent to
* active frameworks.
*/
virtual void activateFramework(
const FrameworkID& frameworkId) = 0;
/**
* Deactivates a framework.
*
* Deactivates a framework in the Mesos cluster. Resource offers are not
* sent to deactivated frameworks.
*/
virtual void deactivateFramework(
const FrameworkID& frameworkId) = 0;
/**
* Updates a framework.
*
* Updates capabilities of a framework in the Mesos cluster, it will be
* invoked when a framework is re-added. As some of the framework's
* capabilities may be updated when re-added, this API should update the
* capabilities of the newly added framework to Mesos cluster to reflect
* the latest framework info. Please refer to the design document here
* https://cwiki.apache.org/confluence/display/MESOS/Design+doc:+Updating+Framework+Info // NOLINT
* for more details related to framework update.
*/
virtual void updateFramework(
const FrameworkID& frameworkId,
const FrameworkInfo& frameworkInfo) = 0;
/**
* Adds an agent.
*
* Adds or re-adds an agent to the Mesos cluster. It is invoked when a
* new agent joins the cluster or in case of agent recovery.
*
* @param slaveId ID of the agent to be added or re-added.
* @param slaveInfo Detailed info of the agent. The slaveInfo resources
* correspond directly to the static --resources flag value on the agent.
* @param total The `total` resources are passed explicitly because it
* includes resources that are dynamically "checkpointed" on the agent
* (e.g. persistent volumes, dynamic reservations, etc).
* @param used Resources that are allocated on the current agent.
*/
virtual void addSlave(
const SlaveID& slaveId,
const SlaveInfo& slaveInfo,
const Option<Unavailability>& unavailability,
const Resources& total,
const hashmap<FrameworkID, Resources>& used) = 0;
/**
* Removes an agent.
*
* Removes an agent from the Mesos cluster. All resources belonging to this
* agent should be released by the allocator.
*/
virtual void removeSlave(
const SlaveID& slaveId) = 0;
/**
* Updates an agent.
*
* Updates the latest oversubscribed resources for an agent.
* TODO(vinod): Instead of just oversubscribed resources have this
* method take total resources. We can then reuse this method to
* update Agent's total resources in the future.
*
* @param oversubscribed The new oversubscribed resources estimate from
* the agent. The oversubscribed resources include the total amount
* of oversubscribed resources that are allocated and available.
*/
virtual void updateSlave(
const SlaveID& slave,
const Resources& oversubscribed) = 0;
/**
* Activates an agent.
*
* Activates an agent. This is invoked when an agent reregisters. Offers
* are only sent for activated agents.
*/
virtual void activateSlave(
const SlaveID& slaveId) = 0;
/**
* Deactivates an agent.
*
* This is triggered if an agent disconnects from the master. The allocator
* should treat all offers from the deactivated agent as rescinded. (There
* is no separate call to the allocator to handle this). Resources aren't
* "recovered" when an agent deactivates because the resources are lost.
*/
virtual void deactivateSlave(
const SlaveID& slaveId) = 0;
/**
* Updates the list of trusted agents.
*
* This is invoked when the master starts up with the --whitelist flag.
*
* @param whitelist A set of agents that are allowed to contribute
* their resources to the resource pool.
*/
virtual void updateWhitelist(
const Option<hashset<std::string>>& whitelist) = 0;
/**
* Requests resources for a framework.
*
* A framework may request resources via this call. It is up to the allocator
* how to react to this request. For example, a request may be ignored, or
* may influence internal priorities the allocator may keep for frameworks.
*/
virtual void requestResources(
const FrameworkID& frameworkId,
const std::vector<Request>& requests) = 0;
/**
* Updates allocation by applying offer operations.
*
* This call is mainly intended to support persistence-related features
* (dynamic reservation and persistent volumes). The allocator may react
* differently for certain offer operations. The allocator should use this
* call to update bookkeeping information related to the framework.
*/
virtual void updateAllocation(
const FrameworkID& frameworkId,
const SlaveID& slaveId,
const std::vector<Offer::Operation>& operations) = 0;
/**
* TODO (gyliu513): Add more comments after dynamic reservation finished
*
* @param slaveId ID of the agent.
* @param operations TODO(gyliu513)
*/
virtual process::Future<Nothing> updateAvailable(
const SlaveID& slaveId,
const std::vector<Offer::Operation>& operations) = 0;
/**
* Updates unavailability for an agent.
*
* We currently support storing the next unavailability, if there is one,
* per agent. If `unavailability` is not set then there is no known upcoming
* unavailability. This might require the implementation of the function to
* remove any inverse offers that are outstanding.
*/
virtual void updateUnavailability(
const SlaveID& slaveId,
const Option<Unavailability>& unavailability) = 0;
/**
* Updates inverse offer.
*
* Informs the allocator that the inverse offer has been responded to or
* revoked.
*
* @param unavailableResources The `unavailableResources` can be used by the
* allocator to distinguish between different inverse offers sent to the
* same framework for the same slave.
* @param status If `status` is not set then the inverse offer was not
* responded to, possibly because the offer timed out or was rescinded.
* This might require the implementation of the function to remove any
* inverse offers that are outstanding.
* @param filters A filter attached to the inverse offer can be used by the
* framework to control when it wants to be contacted again with the
* inverse offer. The "filters" for InverseOffers are identical to the
* existing mechanism for re-offering Offers to frameworks.
*/
virtual void updateInverseOffer(
const SlaveID& slaveId,
const FrameworkID& frameworkId,
const Option<UnavailableResources>& unavailableResources,
const Option<InverseOfferStatus>& status,
const Option<Filters>& filters = None()) = 0;
/**
* Retrieves the status of all inverse offers maintained by the allocator.
*/
virtual process::Future<
hashmap<SlaveID, hashmap<FrameworkID, mesos::master::InverseOfferStatus>>>
getInverseOfferStatuses() = 0;
/**
* Recovers resources.
*
* Used to update the set of available resources for a specific agent. This
* method is invoked to inform the allocator about allocated resources that
* have been refused or are no longer in use.
*/
virtual void recoverResources(
const FrameworkID& frameworkId,
const SlaveID& slaveId,
const Resources& resources,
const Option<Filters>& filters) = 0;
/**
* Suppresses offers.
*
* Informs the allocator to stop sending offers to the framework.
*/
virtual void suppressOffers(
const FrameworkID& frameworkId) = 0;
/**
* Revives offers.
*
* Revives offers for a framework. This is invoked by a framework when
* it wishes to receive filtered resources or offers immediately.
*/
virtual void reviveOffers(
const FrameworkID& frameworkId) = 0;
/**
* Informs the allocator to set quota for the given role.
*
* It is up to the allocator implementation how to satisfy quota. An
* implementation may employ different strategies for roles with or
* without quota. Hence an empty (or zero) quota is not necessarily the
* same as an absence of quota. Logically, this method implies that the
* given role should be transitioned to the group of roles with quota
* set. An allocator implementation may assert quota for the given role
* is not set prior to the call and react accordingly if this assumption
* is violated (i.e. fail).
*
* TODO(alexr): Consider returning a future which an allocator can fail
* in order to report failure.
*
* TODO(alexr): Consider adding an `updateQuota()` method which allows
* updating existing quota.
*/
virtual void setQuota(
const std::string& role,
const mesos::quota::QuotaInfo& quota) = 0;
/**
* Informs the allocator to remove quota for the given role.
*
* An allocator implementation may employ different strategies for roles
* with or without quota. Hence an empty (or zero) quota is not necessarily
* the same as an absence of quota. Logically, this method implies that the
* given role should be transitioned to the group of roles without quota
* set (absence of quota). An allocator implementation may assert quota
* for the given role is set prior to the call and react accordingly if
* this assumption is violated (i.e. fail).
*
* TODO(alexr): Consider returning a future which an allocator can fail in
* order to report failure.
*/
virtual void removeQuota(
const std::string& role) = 0;
};
} // namespace allocator {
} // namespace master {
} // namespace mesos {
#endif // __MESOS_MASTER_ALLOCATOR_HPP__