-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP vision for builders data model (build capabilities) #9899
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include "build-capability.hh" | ||
#include <algorithm> | ||
|
||
namespace nix { | ||
|
||
bool | ||
BuildCapability::canBuild(const Schedulable & schedulable) const | ||
{ | ||
return schedulable.getSystem() == system | ||
&& std::includes( | ||
supportedFeatures.begin(), supportedFeatures.end(), | ||
schedulable.getRequiredFeatures().begin(), schedulable.getRequiredFeatures().end() | ||
) | ||
&& std::includes( | ||
schedulable.getRequiredFeatures().begin(), schedulable.getRequiredFeatures().end(), | ||
mandatoryFeatures.begin(), mandatoryFeatures.end() | ||
); | ||
} | ||
|
||
} // namespace nix |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#pragma once | ||
///@file | ||
|
||
#include <optional> | ||
#include <set> | ||
#include <string> | ||
|
||
namespace nix { | ||
|
||
class Schedulable { | ||
public: | ||
virtual std::string_view getSystem() const = 0; | ||
virtual const std::set<std::string> & getRequiredFeatures() const = 0; | ||
virtual bool getPreferLocalBuild() const = 0; | ||
}; | ||
|
||
/** | ||
* Parameters that determine which derivations can be built. | ||
* | ||
* *Where* it can be built is determined by context. | ||
*/ | ||
struct BuildCapability { | ||
/** | ||
* For a derivation to be buildable by this capability, `system` must match the derivation `system` by case sensitive string equality. | ||
* | ||
* In a given context, multiple `system`s may be supported. This is represented by having multiple `BuildCapability`s. | ||
*/ | ||
std::string system; | ||
|
||
/** | ||
* For a derivation to be buildable by this capability, `supportedFeatures` must be a superset of the derivation's `requiredFeatures`, or be equal. | ||
*/ | ||
std::set<std::string> supportedFeatures; | ||
|
||
/** | ||
* For a derivation to be buildable by this capability, `mandatoryFeatures` must be a subset of the derivation's `requiredFeatures`, or be equal. | ||
*/ | ||
std::set<std::string> mandatoryFeatures; | ||
|
||
bool canBuild(const Schedulable & schedulable) const; | ||
}; | ||
|
||
/** | ||
* Extends `BuildCapability` to include scheduling information. | ||
*/ | ||
struct SchedulableCapability { | ||
/** | ||
* Which derivations can be built. | ||
*/ | ||
BuildCapability capability; | ||
|
||
/** | ||
* An upper bound on the number of derivations that can be built at once. | ||
* | ||
* If `std::nullopt`, the concurrency is unlimited, or controlled by the remote side. | ||
*/ | ||
std::optional<int> maxJobs; | ||
|
||
/** | ||
* Whether the capability is local to the current machine. | ||
* | ||
* This may include VMs that are running on the same machine. | ||
* It is the user's responsibility to configure their VMs so that there is no unnecessary copying between VMs. | ||
* | ||
* This parameter interacts with the `preferLocalBuild` derivation attribute for builds to indicate that the overhead of copying can be expected to be larger than the actual build. | ||
*/ | ||
bool isLocal; | ||
|
||
/** | ||
* A proportional measure of build performance, typically configured by the user. | ||
* Is divided by load to find the best candidate for a build. | ||
* | ||
* Must be positive. | ||
*/ | ||
float speedFactor; | ||
}; | ||
|
||
} // namespace nix |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,67 @@ | ||
#pragma once | ||
///@file | ||
|
||
#include "build-capability.hh" | ||
#include "types.hh" | ||
|
||
namespace nix { | ||
|
||
class Store; | ||
|
||
struct SchedulableCapability; | ||
|
||
struct Machine { | ||
|
||
const std::string storeUri; | ||
const std::set<std::string> systemTypes; | ||
|
||
const std::string sshKey; | ||
const unsigned int maxJobs; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually removing this is probably wrong, because it can be used to represent a limit on a single resource, such as an x86_64 + i686 build capability, or the resources of VMs (+ non-VM capabilities) such as an aarch64-darwin host with an aarch64-linux build VM. This limit may be crude, but the same idea applies when it's, say, a (cpu, memory) tuple instead of a single number of jobs; that's an orthogonal issue. |
||
const float speedFactor; | ||
const std::set<std::string> supportedFeatures; | ||
const std::set<std::string> mandatoryFeatures; | ||
const std::string sshPublicHostKey; | ||
|
||
/** | ||
* NOTE: The set of capabilities is currently restricted by the constructor | ||
* and the machines format. | ||
*/ | ||
std::vector<SchedulableCapability> capabilities; | ||
|
||
/** Index on `capabilities`. Pointers are references into `capabilities`. */ | ||
std::map<std::string, std::vector<SchedulableCapability *>> capabilitiesBySystem; | ||
|
||
bool enabled = true; | ||
|
||
/** | ||
* @return Whether this host can build the `schedulable`. | ||
*/ | ||
bool canBuild(const Schedulable & schedulable) const; | ||
|
||
/** | ||
* @deprecated Use `canBuild` instead. This method is not accurate. | ||
* | ||
* @return Whether `system` is either `"builtin"` or in | ||
* `systemTypes`. | ||
*/ | ||
bool systemSupported(const std::string & system) const; | ||
|
||
/** | ||
* @deprecated Use `canBuild` instead. This method is not accurate. | ||
* | ||
* @return Whether `features` is a subset of the union of `supportedFeatures` and | ||
* `mandatoryFeatures` | ||
*/ | ||
bool allSupported(const std::set<std::string> & features) const; | ||
|
||
/** | ||
* @deprecated Use `canBuild` instead. This method is not accurate. | ||
* @return @Whether `mandatoryFeatures` is a subset of `features` | ||
*/ | ||
bool mandatoryMet(const std::set<std::string> & features) const; | ||
|
||
Machine(decltype(storeUri) storeUri, | ||
decltype(systemTypes) systemTypes, | ||
std::set<std::string> systemTypes, | ||
decltype(sshKey) sshKey, | ||
decltype(maxJobs) maxJobs, | ||
decltype(speedFactor) speedFactor, | ||
decltype(supportedFeatures) supportedFeatures, | ||
decltype(mandatoryFeatures) mandatoryFeatures, | ||
unsigned int maxJobs, | ||
float speedFactor, | ||
std::set<std::string> supportedFeatures, | ||
std::set<std::string> mandatoryFeatures, | ||
decltype(sshPublicHostKey) sshPublicHostKey); | ||
|
||
ref<Store> openStore() const; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be a list of capabilities, because of shared resources? Alternatively, see https://github.com/NixOS/nix/pull/9899/files#r1478444104
Do we still conflate too many concepts? Maybe we need a build routing tree that's about available resources (and load). Each node may or may not impose restrictions on builds that are routed through it. Each node may or may not have information about how to contact a builder.