[[PageOutline]] = GENI Aggregate Manager API Draft Revisions = This page documents DRAFT revisions to the GENI Aggregate Manager API, proposed for the next version of the API. As indicated below, some of the revisions documented here have been discussed on the GENI developer mailing list, and during at least one GEC. Other revisions are in early discussions and subject to change or abandonment. The GENI Aggregate Manager API allows aggregates to advertise resources and to allocate resources to Slices in the form of Slivers. A Sliver is a set of resources allocated by one Aggregate to one Slice. See below for a proposed complete definition. The current officially adopted version of the API is '''2''' and is documented on [wiki:GAPI_AM_API the main API page]. API Version 2 was adopted based on changes previously listed on this page. Those changes have been removed from this page, and are now documented [wiki:GAPI_AM_API_V2_DELTAS on a separate page]. They include: A. RSpec related changes, specifying that RSpecs are XML following GENI standard schemas. * Since June 2011, the latest software from ProtoGENI and SFA (as of code tag 1.0-24) has complied with these changes. * Omni version 1.3 (released June 2011) added client software support for these changes. B. Supporting flexible arguments and returns. Specifically, adding a property list to all calls, and making all returns be a property list. This page documents proposed changes for AM API version '''3'''. These changes are grouped into sets. API Version 3 will be the collection of changes from the change sets below which we next agree on. Change sets still under discussion will then be targeted at a future release. == Proposing Additional Changes == GENI community members are encouraged to propose changes to the GENI Aggregate Manager API. Technical discussions are generally held on the [mailto:dev@geni.net Developers mailing list] Specific questions may be directed to the software team at the GPO (Tom Mitchell, Aaron Helsinger, and Sarah Edwards) at {tmitchel, ahelsing, sedwards} at geni.net = Proposed changes for GENI Aggregate Manager API version 3 = This page documents a long list of proposed changes for AM API version 3. These changes provide ways for aggregates to expand GENI functionality, without requiring further API modifications. There are many changes here. As such, aggregates may implement these to varying degrees. - Clients are reminded that these methods are requests - based on the AM type and resource types, these requests may fail or not make sense. Clients should watch for {{{UNSUPPORTED}}} returns. - AMs are encouraged to implement as much of this API as reasonable to provide a common front for clients. When a function is not possible, return {{{UNSUPPORTED}}}, document publicly what functions do work, and suggest alternative ways to get the result the client desired. = Summary = == Proposed Changes == At the top level, the proposed changes for AM API v3 include: - [#ChangeSetC:UpdateSlivers Change Set C]: Add the ability to !UpdateSlivers to immediately modify your reservation - [#ChangeSetD:Sliver-specificoperations Change Set D: Slivers]: Change methods to clarify that there may be multiple slivers per slice at an AM, and to allow operating on individual slivers - [#ChangeSetE:Tickets Change Set E: Tickets]: Add methods using tickets to do negotiated reservations - [#ChangeSetF1:DefineSliverStates Change Set F1]: Superseded by F3 and F4: Define sliver states, and the state changes that various methods cause - [#ChangeSetF2:ActOnSlivers Change Set F2]: Superseded by F3 and F4: Add a new general !ActOnSlivers method allowing AMs to support AM and resource-type specific operations - [#ChangeSetF3:SliverAllocationStatesandmethods Change Set F3]: Sliver Allocation States and methods - [#ChangeSetF4:SliverOperationsMethod Change Set F4]: Method to perform Sliver Operational actions - [#ChangeSetF5:SliverOperationalStates Change Set F5]: Sliver Operational States - ADOPTED: [#Adopted:ChangeSetG:Credentialsaregeneralauthorizationtokens. Change Set G]: Generalize the credentials argument, allowing ABAC support - Change Set H: Clarify: A second call to !CreateSlivers without an intervening !DeleteSlivers is an error. - ADOPTED: Change Set I1: !SliversStatus return structure includes sliver expiration - ADOPTED with changes: Change Set I2: !SliversStatus return includes SSH logins/key for nodes that support SSH access - ADOPTED: Change Set I3: !CreateSlivers return becomes a struct, adds sliver expiration - Change Set I4: !CreateSlivers optionally does not start resources. - Withdrawn: [#Withdrawn:ChangeSetJ Change Set J]: Support proxy aggregates with 1 new option and 1 new !GetVersion entry - ADOPTED: [#Adopted:ChangeSetK:Standardizecertificatesandcredentials Change Set K]: Standardize certificate contents, etc - Include a real serial number, holder email, holder uuid, and optionally authority URL in certificates - Define slice ID as the UUID plus URN in slice certificates - Define slice name, sliver name, and user name restrictions, and similar for URNs - Publish schemas for credentials and certificates - Postponed: [#ChangeSetL:ChangeSFAcredentialsprivileges Change Set L]: Standardize slice credential privileges - [#ChangeSetM:NewMethodSignatures Change Set M]: New method signatures, incorporating all previous adopted change sets For a full listing of the proposed API methods after all these changes, see [#Changesummary-methodsignatures below]. == Unspecified items == - Semantics of adding or removing slivers from the full set of slivers in a slice at an aggregate - An acceptable Update proposal - RSpec for advertising operational states for a sliver type - Publish credential schema - Define error codes returned by new methods, conditions ----- = Change Set C: !UpdateSlivers = Add an ability for experimenters to modify their allocated resources at an aggregate without deleting (and possibly losing) existing resource allocations. This change was briefly discussed at GEC13, and is a topic for ongoing discussion. == Motivation == A common complaint among experimenters about the current AM API is that there is no way to add or remove resources from a slice at an aggregate, without completely deleting the slice at that aggregate and recreating it, possibly losing resources to another experimenter and certainly losing state. This proposal aims to address that, by introducing a method to update the slice at an aggregate. The [http://svn.planet-lab.org/attachment/wiki/WikiStart/sfa.pdf SFA] calls for an !UpdateSlice method, "to request that additional resources—as specified in the RSpec—be allocated to the slice". In the !PlanetLab implementation of the SFA, !UpdateSliver is in fact a synonym for !CreateSliver - the server will ensure that your allocated resources match your request RSpec, adding, removing and modifying resources as needed. It immediately allocates and boots nodes to match the request RSpec. The ProtoGENI CMV2 API has [http://www.protogeni.net/trac/protogeni/wiki/ComponentManagerAPIV2#UpdateSliver UpdateSliver], which is described as the way to "Request a change of resuorces for an existing sliver. The new set of resources that are desired are specified in the rspec." At ProtoGENI as at !PlanetLab, this method takes the full RSpec description of resources the experimenter wants, and the server computes the difference with what the experimenter already has. At ProtoGENI though, this method returns a ticket. The experimenter must then redeem the ticket to actually acquire the resources. This topic was discussed at the [http://groups.geni.net/geni/wiki/GEC12GeniAmAPI GEC12 AM API session] and on the GENI dev mailing list (in [http://lists.geni.net/pipermail/dev/2011-October/000433.html October] and [http://lists.geni.net/pipermail/dev/2011-November/000531.html November]). This topic was also discussed on the geni-dev mailing list here: http://lists.geni.net/pipermail/dev/2012-March/000588.html and here: http://lists.geni.net/pipermail/dev/2012-March/000643.html and elsewhere in March 2012. A competing related proposal from Gary Wong is here: http://www.protogeni.net/trac/protogeni/wiki/AM_API_proposals A further revised proposal is expected from Jon Duerig. == !UpdateSlivers == This change would add a new method !UpdateSlivers, which takes a full request RSpec of the desired final state of the slice at this aggregate. This proposal calls for adding this functionality in the context of tickets: the !UpdateSlivers method returns a ticket. See [#ChangeSetE:Tickets Change Set E: Tickets] for details. Some points about this change: - The method takes a full request RSpec - not a diff. - Note that we want the manifest to be readily modifiable to be a request (include component_ids and sliver_ids), but it is not yet. - AMs may, as always, return {{{UNSUPPORTED}}} - EG if they are incapable of determining what changes to apply (computing a diff). - The request is either fully satisfied, or fails (returns an error code). - AMs must document the level of service they provide: will any state be lost on existing resources? - Options includes {{{geni_end_time}}}, a RFC3339 requested end time for the reservation. See below for details. - If omitted, the AM may reserve the resources for the default sliver duration. - AMs should follow the logic of !RenewSlivers to determine if the requested duration of the sliver is acceptable. - The request should Fail (return an error code) if the resources cannot be reserved until the requested time. Aggregates and experimenters should use an RSpec extension for specifying a guarantee on state loss per-resource: EG: {{{ ... }}} This uses the RNC schema: {{{ default namespace = "http://www.protogeni.net/resources/rspec/ext/preserve/1" # This is meant to extend a node or link Preserved = element preserve { attribute guarantee { "none" | "persistent-state" | "dynamic-state" | "no-disruption" } } start = Preserved }}} In the above schema, the states represent increasing levels of state preservation guarantee. {{{ struct UpdateSlivers(string slice_urn, string credentials[], string rspec, struct options) }}} Returns a struct: {{{ { ticket: geni_status: , } }}} See [#ChangeSetE:Tickets Change Set E: Tickets] for details on the ticket returned and ticket semantics. = Change Set D: Sliver-specific operations = A slice may have multiple slivers at a single AM. Experimenters can operate on slivers independently, if the AM supports it. AMs define slivers as groups of resources, and give them locally unique sliver_urns for identifying that group of resources. This change was briefly discussed at GEC13, and remains open for discussion. Concerns include whether aggregates can support individually operating on slivers, and whether we should make this change without that functionality. See http://lists.geni.net/pipermail/dev/2012-March/000593.html as well. == Motivation == This change set was discussed at the [http://groups.geni.net/geni/wiki/GEC12GeniAmAPI GEC12 AM API session]. The current AM API calls take a Slice URN, and operate on all resources under that label at the given aggregate - all the resources for that slice at the aggregate are allocated, renewed, and deleted together. There is no provision for releasing some of the resources allocated to the slice at that aggregate, or for adding new resources to the reservation for that slice at a given aggregate. This ties closely to the precise definition of a Slice vs a Sliver. The current AM API methods imply that a sliver represents all resources at an aggregate for a given slice. However, this does not match the definition that previous GENI documents have used, nor the functionality that experimenters desire. Previous GENI documents have used this definition: ''A sliver is the smallest set of resources at an aggregate that can be independently reserved and allocated. A given slice may contain multiple slivers at a single aggregate. A sliver may contain multiple components.'' Given this definition, the current AM API methods in fact operate on a group of slivers. This change set would provide a means for experimenters to operate on individual slivers within their slice at a given aggregate. == Define sliver == A Sliver is an aggregate defined grouping of resources within a slice at this aggregate, whose URN identifies the sliver, and can be used as an argument to methods such as !DeleteSlivers or !RenewSlivers, and whose status can be independently reported in the return from !SliversStatus. The AM defines 1 or more of these groupings to satisfy a given resource request for a slice. All reserved resources are directly contained by exactly 1 such sliver container, which is in precisely 1 slice. Slivers are identified by an aggregate selected URN. See other change proposals for details on standardizing such URNs. == Addressable Slivers == Considering the clarified sliver definition, several API names are misleading. This change proposal modifies those method names to clarify that they may work with multiple slivers. Additionally, some methods can logically operate on individual slivers: this change modifies those methods' arguments to allow specifying a particular sliver. '''This proposal is missing a supplementary proposal of the semantics involved in operating on individual slivers, part of the slice at an AM.''' In particular, defining whether !CreateSlivers can be called multiple times, and the semantics of doing !DeleteSlivers or !RenewSlivers on only some of the slivers in a slice at an aggregate. '''The specific method signature changes of this proposal are superseded by proposal F3 and the proposed summary methods at the bottom of this page.''' 1. Rename some existing methods to clarify that they act on 1+ slivers: - !CreateSliver -> !CreateSlivers - !RenewSliver -> !RenewSlivers - !DeleteSliver -> !DeleteSlivers - !SliverStatus -> !SliversStatus 2. Some methods that take {{{slice_urn}}} now take a {{{urn}}} that may be a slice or sliver: - !RenewSlivers, !DeleteSlivers, !SliversStatus - AMs are responsible for distinguishing whether the request operates on a slice or a sliver (see [#ChangeSetK:Standardizecertificatesandcredentials Change Set K] which defines how slice and sliver URNs differ). - AMs are free to refuse to Renew, Delete, or provide status on an individual sliver, if the local AM or that resource type does not support it. - AMs should return an error message. Clients may often use !UpdateSlivers instead to similar effect. Open Question: Should the methods take a list of urns, 1 of which may be a slice_urn? = Change Set E: Tickets = AM APIv3 adds support for negotiated reservations or two-phase commit, by '''add'''ing methods that allow an experimenter to reserve resources for a slice without committing to using them, or forcing the AM to incur the cost of instantiating them. This change is actively under discussion. See for example http://lists.geni.net/pipermail/dev/2012-March/000616.html and http://lists.geni.net/pipermail/dev/2012-March/000648.html For an alternative proposal, see: http://www.protogeni.net/trac/protogeni/wiki/AM_API_proposals The later proposal for allocation states (below) supersedes this. See [#ChangeSetF3:SliverAllocationStatesandmethods Change Set F3]. == Motivation == This possible change was discussed at the [http://groups.geni.net/geni/wiki/GEC12GeniAmAPI GEC12 AM API session]. The [http://svn.planet-lab.org/attachment/wiki/WikiStart/sfa.pdf SFA] defines the concept of a ticket. SFA1.0 section 5.3 says "A component signs an RSpec to produce a ticket, indicating a promise by the component to bind resources to the ticket-holder at some point in time." Tickets are promises to allocate resources. Tickets are used in the [http://www.protogeni.net/trac/protogeni/wiki/ComponentManagerAPIV2 ProtoGENI CMV2 interface], and are discussed on [http://www.protogeni.net/trac/protogeni/wiki/Tickets the PG wiki]. Tickets with a slightly different semantics (and leases) are also used extensively in Orca. For details on the use of leases and tickets in Orca, see [https://geni-orca.renci.org/trac/attachment/wiki/WikiStart/ORCA%20Book.pdf 'the Orca Book']. However, each of these uses of the notion of tickets differs. Tickets would potentially enable a number of useful and possibly critical features: - Coordinated or negotiated reservations: reserving resources from aggregate B only if aggregate A can give you a complementary resource. For example, a VLAN tag. This is related to stitching, both network stitching and the more general form. - Two phase commit reservations (similar to the above). - Scheduled reservations in the future. - Brokers: 3rd parties consolidating, scheduling and allocating resources on behalf of a number of other aggregates - Lending resources to other experimenters - Giving experimenters explicit control over when resources are started, stopped, and restarted (see the discussion on !UpdateSliver). == Tickets semantics == This proposal would add tickets to the existing AM API, allowing experimenters to reserve (hold) resources temporarily and cheaply. Tickets represent a promise to the named slice to allocate the specified resources, if the ticket is 'redeemed' while the ticket is still valid. Tickets describe a complete specification of the resources that will be allocated to the slice at this aggregate, if the ticket is redeemed. Some key properties of the tickets proposed here: - Tickets are IOUs from an AM to a slice (not to an experimenter - no delegation is necessary or possible). - Experimenters do not need to use tickets to reserve resources: existing methods without tickets still work. - A ticket is a promise by the AM to give the specified resources to the slice if an authorized slice member requests them. - The aggregate is saying they will not give away these resources to other slices, but only to this slice. - AMs must document how firm their promises are. See the attribute {{{geni_ticket_service_class}}}. - Some aggregates may only offer soft promises, as in PlanetLab. - Tickets are signed by the AM: non repudiatable. - Tickets are bound to a slice: they contain the slice certificate. - Tickets may be passed from 1 researcher on a slice to another freely - no explicit delegation is required. - Indeed, any experimenter with appropriate slice credentials can retrieve the ticket from the aggregate. - Tickets may not be delegated to another slice or other entity; these tickets do not support brokers. - Tickets promise a particular set of resources: they include an RSpec. Note that this may be an unbound RSpec. - Note that we do not currently have unbound manifest RSpecs. For now we specify only that this is an RSpec. - Tickets are good for a limited time. - They must be redeemed by a specified time, {{{redeem_before}}}, after which the aggregate is free to assign the resources elsewhere. - Aggregates determine {{{redeem_before}}}, which is some epsilon in the near future. - Aggregates may accept a new option {{{geni_reserve_until}}} which is a request for a particular {{{redeem_before}}}, but are not required to support this (they may ignore the option). - Tickets specify when the resources will be available from ({{{starts}}}, typically essentially now), and when they will be available until (typically now plus the aggregate-local default sliver expiration time). - The resources may be available even longer, but that would require a separate !RenewSlivers call. - Tickets specify the full final state of the slice after applying this ticket. - Tickets are not incremental changes, and are not additive. - The implication is that there may be only 1 ticket outstanding for a slice per aggregate (except for scheduled reservations, see below). - This also implies that these tickets are not suitable for use by brokers. - Aggregates must attempt to honor their promises. As a result, aggregates must remember all outstanding tickets until they are redeemed or expire. - All ticket related timestamps must be in the format of RFC3339 (http://www.ietf.org/rfc/rfc3339.txt) - Full date and time with explicit timezone: offset from UTC or in UTC. - eg: {{{1985-04-12T23:20:50.52Z}}} or {{{1996-12-19T16:39:57-08:00}}} {{{ #!comment == Ticket contents == Tickets have an ID, the certificate of the slice to whom the resources are promised, an RSpec representing the promised resources, several timestamps, other attributes, and a signature by the aggregate (including the aggregate's certificate). Tickets are externally represented as signed XML documents following the [http://www.w3.org/TR/xmldsig-core/ XML Digital Signatures specification]. Tickets contain: - {{{owner_gid}}} = the certificate of the experimenter who requested the ticket - {{{target_gid}}} = slice certificate - {{{uuid}}} - Unique ID for the ticket, in the hexadecimal digit string format given in [http://www.ietf.org/rfc/rfc4122.txt RFC 4122] - {{{expires}}} - RFC3339 compliant Date/Time when the resources will no longer be yours per this reservation (eg sliver duration+now) - {{{redeem_before}}}: RFC3339 compliant Date/Time when you must redeem this reservation, or your resources will be returned to the available pool (eg now+epsilon) - {{{starts}}} - RFC3339 compliant Date/Time when the resources will be yours, per this reservation (eg now) - RSpec (not specified as request or manifest) - Attributes (AM/resource-type specific name/value pairs) - Including {{{geni_ticket_service_class}}} as defined below, to indicate the firmness of the promise this ticket represents - signature including issuing AM's certificate More formally: {{{ { owner_gid = , target_gid = , uuid = , expires = , redeem_before = , starts = , rspec = , attributes = { geni_ticket_service_class = , }, signature } }}} Tickets should include the {{{geni_ticket_service_class}}} attribute for advertising the firmness of the promise that a ticket represents (case insensitive string or integer). - FIXME: Provide definitions for these service classes. - 1=WEAK_EFFORT - 2=BEST_EFFORT - 3=ELASTIC_RESERVATION - 4=HARD_RESERVATION Tickets will follow a defined schema, to be published on geni.net. Tickets logically have a URN (not included in the ticket): {{{urn:publicid:IDN++ticket+}}} For a similar structure in ProtoGENI, see https://www.protogeni.net/trac/protogeni/attachment/wiki/Authentication/credential.rnc == Methods == 1. !GetTicket {{{ struct GetTicket (string slice_urn, string credentials[], string requestRSpec, struct options) }}} - Get a ticket promising resources requested in the rspec. - If there is already an outstanding ticket for the slice, an error is returned. - Return: ticket - Result State: {{{ticketed}}} - Options may include {{{geni_start_time}}} and {{{geni_end_time}}} (see below) 2. !RedeemTicket {{{ struct RedeemTicket(string slice_urn, string credentials[], string ticket, struct users[] (as in CreateSlivers), struct options) }}} - Return: {{{ { string rspec=, string geni_start_time=, string geni_expires=, string geni_status=, } }}} - Begin allocating the resources promised in the ticket. - Option {{{geni_auto_start}}}: - If supplied and true (boolean: 0 or 1 in XML-RPC), the aggregate automatically start/restarts resources as necessary, as though the experimenter called !ActOnSlivers(start). - State will be {{{changing}}} and then {{{ready}}} - If omitted the aggregate does not start resources (default behavior). The final state is {{{allocated}}}, and the experimenter must explicitly start or restart resources using !ActOnSlivers - Note that resources which do not require a 'start' may already be {{{ready}}} on normal return from !RedeemTicket. - Omitting the ticket causes the aggregate to redeem the outstanding ticket for this slice if any. If none, return an error code. - The ticket must be valid: not expired or previously redeemed or replaced. If so, an error is returned. 3. !ReleaseTicket {{{ struct ReleaseTicket(string slice_urn, string credentials[], string ticket, struct options) }}} - Give up the reservation for resources. - Return: true (1 in XMLRPC) or error - Omitting the ticket causes the aggregate to release the 0 or 1 outstanding tickets for this slice. - If this ticket was from !UpdateSlivers, then the sliver returns to the {{{allocated}}} state and existing resources are not modified. 4. !UpdateTicket (atomic release/get) {{{ struct UpdateTicket(string slice_urn, string credentials[], string requestRSpec, string ticket, struct options) }}} - For updating a reservation in place, replacing one ticket with a new one. On success, the old ticket is invalid. - Return: Ticket - Result State: {{{ticketed}}} - Options may include {{{geni_start_time}}} and {{{geni_end_time}}} (see below) - The ticket must be valid: not expired or previously redeemed or replaced. If so, an error is returned. 5. !UpdateSlivers {{{ struct UpdateSlivers(string slice_urn, string credentials[], string requestRSpec, struct options) }}} - Returns a struct: {{{ { string ticket= string geni_status=, } }}} - Get a promise for resources that would replace currently allocated resources, as defined in [#ChangeSetC:UpdateSlivers Change Set C]. - Result State: {{{ticketed}}} - On completion, the slice has both a ticket and a set of slivers at this aggregate. Overall it is both {{{allocated}}} and {{{ticketed}}}, which is called {{{ticketed}}}. - Options may include {{{geni_start_time}}} and {{{geni_end_time}}}, a RFC3339 requested start and end time for the reservation (option not required). - The request should Fail (return an error code) if the resources cannot be reserved from or until the requested time. - The method takes a full request RSpec - not a diff. - AMs may, as always, return {{{UNSUPPORTED}}} - EG if they are incapable of determining what changes to apply (computing a diff). - The request is either fully satisfied, or fails (returns an error code). - For further details on the !UpdateSlivers semantics, see [#ChangeSetC:UpdateSlivers Change Set C]. For a similar set of functions in ProtoGENI, see: https://www.protogeni.net/trac/protogeni/wiki/ComponentManagerAPIV2 == Other changes to support tickets == - !CreateSlivers remains the first call: do not use it to add resources to the slice. - !ListResources return value changes to be: {{{ { string rspec (ad or Manifest - may be empty though) string tickets[] (required but may be an empty list) } }}} - For !ListResources with no {{{slice_urn}}}, {{{tickets}}} shall be an empty list, and rspec shall be an ad RSpec. - For !ListResources with a {{{slice_urn}}}, {{{rspec}}} is the manifest RSpec for everything belonging to that slice at this AM, if anything is currently allocated (not just a ticket). {{{tickets}}} is then any outstanding ticket(s) for this slice. == Scheduling support using Tickets == This ticket structure and methods, with small additions, supports using tickets for scheduling. This proposal does not require support for scheduling at aggregates. - We are not explicitly supporting scheduling, but the timestamps here should be sufficient. - !GetTicket, !CreateSlivers, !ListResources, !UpdateTicket, !UpdateSlivers all accept new RFC3339 compliant {{{geni_start_time}}} and {{{geni_end_time}}} options to support scheduling in the future. - For !GetTicket and !CreateSlivers, if left out then the reservation start is 'now or really soon' and the end is start plus the default sliver duration. - AMs that do not support scheduling return {{{UNSUPPORTED}}} when passed {{{geni_start_time}}}. - AMs should still support {{{geni_end_time}}}, following the logic of !RenewSlivers to determine if the requested duration of the sliver is acceptable. - IE at !CreateSlivers and !GetTicket and !UpdateSlivers in particular - The request should Fail (return an error code) if the resources cannot be reserved until the requested time. - {{{redeem_before}}} in tickets should be {{{starts}}}+epsilon. That epsilon is AM specific, but typically a small number of minutes. - Multiple tickets may be outstanding for a single slice at a single AM only for non overlapping time intervals. - IE you could request 2 tickets: 1 for machines 1-3 on Tuesday and simultaneously request 1 for machines 4-6 on Thursday. - These options are accepted in !ListResources as well. - Specifying {{{geni_start_time}}} means tell me what will be available at that time. Default is now. - Specifying both {{{geni_end_time}}} and {{{geni_start_time}}} means show me only things available for that entire duration. }}} ----- = Change Set F: Support AM and resource-type specific methods. = Define the control API (the AM API) as about moving slivers through various states at an AM. The proposal here elicited concerns (the method !ActOnSlivers is an ioctl, and the states mix allocation and operational states). A later alternative proposal, see http://lists.geni.net/pipermail/dev/2012-March/000721.html At the GEC13 coding sprint, a variant on the above was approved. It is documented here as [#ChangeSetF3:SliverAllocationStatesandmethods Change Set F3]. A variant on the operational states proposal is defines as Change Set F4 and documented here: https://openflow.stanford.edu/display/FOAM/GENI+-+PerformOperationalAction == Motivation == AM API methods logically change the state of the slivers at this AM. But the API is not clear what experimenters should expect, and does not provide easy ways for experimenters to control when and how states change. There is in particular no way to move slivers through states and change them in ways otherwise undefined by the API. == Change Set F1: Define Sliver States == '''This change is superseded by Change Sets F3 and F4.''' Currently the AM API defines several possible states as valid returns in !SliversStatus: {{{configuring}}}, {{{ready}}}, {{{unknown}}}, and {{{failed}}}. This change changes and expands that list of valid states, and explicitly defines the expected states after each AM API method call. Additionally, this change provides a mechanism for aggregates to supply their own states. The GENI AM API can be thought of as manipulating slivers. As such, each method potentially changes the state of 1 or more slivers. With the changes proposed here, several of the methods return a new {{{geni_status}}} field, whose value is one of the standard GENI sliver status values. Aggregates must use one of the standard GENI values for that return. == Change Set F2: !ActOnSlivers == '''This change is superseded by Change Sets F3 and F4.''' This change introduces a new method, providing a generic way to act on slivers in an AM or resource type specific way. This method shall be used to 'start' or 'stop' or 'restart' resources that have been allocated but not started by !CreateSlivers or !RedeemTicket. It may also be used to change the state of slivers (or their contained resources) in an aggregate or resource specific way. Some aggregates may use this method to change configuration details of allocated resources. This might include changing acceptable login keys. == Change Set F3: Sliver Allocation States and methods == '''This change was discussed and adopted at the GEC13 Coding Sprint.''' For meeting minutes, see: [wiki:GEC13Agenda/CodingSprint the GEC13 Coding Sprint agenda page]. - We agreed to use two kinds of states: allocation states, and operational states. We put off discussion of operational states (ie is the node booted), noting however that this is critical. See Change Set F4. - We debated whether the API should specify a limited number of states, or allow for aggregate or resource specific states. We agreed that for allocation states, the API should define a limited set of states, while operational states might be more permissive. - We discussed the pros and cons of including a single all-in-one method to change allocation states, or a single method per desired transition. There is at least 1 case where there are 2 paths between the same 2 allocation states with very different meaning. As a result, we agreed to use a separate method per allocation state change. We agreed on 3 allocation states for slivers and an enumeration of methods for transitioning between those states. [[Image(sliver-alloc-states3.jpg)]] Allocation states: 1. `geni_unallocated` (alternatively called 'null'). The sliver does not exist. This is the small black circle in typical state diagrams. 2. `geni_allocated` (alternatively called 'offered' or 'promised'). The sliver exists, defines particular resources, and is in a sliver. The aggregate has not (if possible) done any time consuming or expensive work to instantiate the resources, provision them, or make it difficult to revert the slice to the state prior to allocating this sliver. This state is what the aggregate is offering the experimenter. 3. `geni_provisioned`. The aggregate has started instantiating resources, and otherwise making changes to resources and the slice to make the resources available to the experimenter. At this point, operational states are valid to specify further when the resources are available for experimenter use. The key change is the addition of state 2, representing resources that have been allocated to a slice without provisioning the resources. This represents a cheap and un-doable resource allocation, such as we previously discussed in the context of tickets. This compares reasonably well to the 'transaction' proposal written up by Gary Wong (http://www.protogeni.net/trac/protogeni/wiki/AM_API_proposals). When a sliver is created and moved into state 2 (`geni_allocated`), the aggregate produces a manifest RSpec identifying which resources are included in the sliver. This is something like the current !CreateSlivers, except that it does not provision nor start the resources. These resources are exclusively available to the containing sliver, but are not ready for use. In particular, allocating a sliver should be a cheap and quick operation, which the aggregate can readily un-do without impacting the state of slivers which are fully provisioned. For some aggregates, transitioning to this state may be a no-op. States 2 and 3 (`geni_allocated` and `geni_provisioned`) have aggregate and possibly resource specific timeouts. By convention the `geni_allocated` state timeout is typically short, like the {{{redeem_before}}} in ProtoGENI tickets, or the {{{commit_by}}} in Gary's transactions proposal. The `geni_provisioned` state timeout is the existing sliver expiration. If the client does not transition the sliver from `geni_allocated` to `geni_provisioned` before the end of the `geni_allocated` state timeout, the sliver reverts to `geni_unallocated`. If the experimenter needs more time, the experimenter should be allowed to request a renewal of either timeout. Note that typically the sliver expiration time (timeout for state 3, `geni_provisioned`) will be notably longer than the timeout for state 2, `geni_allocated`. State 3, `geni_provisioned`, is the state of the sliver allocation after the aggregate begins to instantiate the sliver. Note that fully provisioning a sliver may take noticeable time. This state also includes a timeout - the sliver expiration time (which is not necessarily related to the time it takes to provision a resource). !RenewSlivers extends this timeout. For some aggregates and resource types, moving to this state from state 2 (`geni_allocated`) may be a no-op. If the transition from one state to another fails, the sliver shall remain in its original state. These are the only allocation states supported by this API. Since the state transitions are finite, but include potentially multiple transitions between the same two states, this API uses separate methods to perform each state transition, rather than a single method for requesting a new state for the sliver. 1. !CreateSlivers moves 1+ slivers from `geni_unallocated` (state 1) to `geni_allocated` (state 2). This method can be described as creating an instance of the state machine for each sliver. If the aggregate cannot fully satisfy the request, the whole request fails. This is a change from the version 2 !CreateSliver, which also provisioned the resources, and 'started' them. That is !CreateSlivers does 1 of the 3 things that it did previously. Note the method name change, consistent with change set D. 2. !DeleteSlivers moves 1+ slivers from either state 2 or 3 (`geni_allocated` or `geni_provisioned`), back to state 1 (`geni_unallocated`). This is similar to the AM API version 2 !DeleteSliver. Note the method name change, consistent with change set D. 3. !RenewAllocations requests an extended timeout for slivers in state 2 (`geni_allocated`). 4. !RenewSlivers requests an extended timeout for slivers in state 3 - the `geni_provisioned` state. That is, this method's semantics does not change. Note the method name change, consistent with change set D. 5. !ProvisionSlivers moves 1+ slivers from state 2 (`geni_allocated`) to state 3 (`geni_provisioned`). This is some of what version 2 !CreateSliver did. Note however that this does not 'start' the resources, or otherwise change their operational state. This method only fully instantiates the resources in the slice. This may be a no-op for some aggregates or resources. '''Update''': Combine the 2 !RenewFoo methods into a single Renew() method which does different things for different sliver types. These states apply to each sliver individually. Logically, the state transition methods then take a single sliver URN. For convenience, these methods accept a list of sliver URNs, or a slice URN as a simple alias for all slivers in this slice at this aggregate. Since each method may operate on multiple slivers, each of these methods returns a list of structs as the value: {{{ value = [ { geni_sliver_urn: , geni_allocation_status: , geni_expires: