blob: 70e6f025d89383084ab8b2cda23ab1cd55d959b2 [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.
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/stringify.hpp>
#include "common/resources_utils.hpp"
namespace mesos {
bool needCheckpointing(const Resource& resource)
{
return Resources::isDynamicallyReserved(resource) ||
Resources::isPersistentVolume(resource);
}
// NOTE: We effectively duplicate the logic in 'Resources::apply'
// which is less than ideal. But we can not simply create
// 'Offer::Operation' and invoke 'Resources::apply' here.
// 'RESERVE' operation requires that the specified resources are
// dynamically reserved only, and 'CREATE' requires that the
// specified resources are already dynamically reserved.
// These requirements are violated when we try to infer dynamically
// reserved persistent volumes.
// TODO(mpark): Consider introducing an atomic 'RESERVE_AND_CREATE'
// operation to solve this problem.
Try<Resources> applyCheckpointedResources(
const Resources& resources,
const Resources& checkpointedResources)
{
Resources totalResources = resources;
foreach (const Resource& resource, checkpointedResources) {
if (!needCheckpointing(resource)) {
return Error("Unexpected checkpointed resources " + stringify(resource));
}
Resource stripped = resource;
if (Resources::isDynamicallyReserved(resource)) {
stripped.set_role("*");
stripped.clear_reservation();
}
// Strip persistence and volume from the disk info so that we can
// check whether it is contained in the `totalResources`.
if (Resources::isPersistentVolume(resource)) {
if (stripped.disk().has_source()) {
stripped.mutable_disk()->clear_persistence();
stripped.mutable_disk()->clear_volume();
} else {
stripped.clear_disk();
}
}
if (!totalResources.contains(stripped)) {
return Error(
"Incompatible slave resources: " + stringify(totalResources) +
" does not contain " + stringify(stripped));
}
totalResources -= stripped;
totalResources += resource;
}
return totalResources;
}
} // namespace mesos {