Skip to content

Commit

Permalink
Merge pull request #393 from fabric-testbed/392-extendrenew-slice-to-…
Browse files Browse the repository at this point in the history
…take-into-account-advance-reservations

392 extendrenew slice to take into account advance reservations
  • Loading branch information
kthare10 authored Jul 15, 2024
2 parents 062e627 + 7e41359 commit b5371c1
Show file tree
Hide file tree
Showing 31 changed files with 907 additions and 461 deletions.
2 changes: 1 addition & 1 deletion fabric_cf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = "1.7.0b1"
__version__ = "1.7.0rc0"
__VERSION__ = __version__
6 changes: 5 additions & 1 deletion fabric_cf/actor/core/apis/abc_actor_management_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ def get_sites(self, *, caller: AuthToken, site: str) -> ResultSitesAvro:
def get_reservations(self, *, caller: AuthToken, states: List[int] = None,
slice_id: ID = None, rid: ID = None, oidc_claim_sub: str = None,
email: str = None, rid_list: List[str] = None, type: str = None,
site: str = None, node_id: str = None) -> ResultReservationAvro:
site: str = None, node_id: str = None,
host: str = None, ip_subnet: str = None) -> ResultReservationAvro:
"""
Get Reservations
@param states states
Expand All @@ -252,6 +253,9 @@ def get_reservations(self, *, caller: AuthToken, states: List[int] = None,
@param node_id node id
Obtains all reservations with error information in case of failure
@param caller caller
@param host host
@param ip_subnet ip subnet
@return returns list of the reservations
"""

Expand Down
4 changes: 3 additions & 1 deletion fabric_cf/actor/core/apis/abc_actor_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from fabric_cf.actor.core.apis.abc_tick import ABCTick

if TYPE_CHECKING:
from fabric_cf.actor.core.kernel.slice_state_machine import SliceState
from fabric_cf.actor.core.apis.abc_actor_event import ABCActorEvent
from fabric_cf.actor.core.apis.abc_actor_proxy import ABCActorProxy
from fabric_cf.actor.core.apis.abc_base_plugin import ABCBasePlugin
Expand Down Expand Up @@ -431,12 +432,13 @@ def register_slice(self, *, slice_object: ABCSlice):
"""

@abstractmethod
def modify_slice(self, *, slice_object: ABCSlice):
def modify_slice(self, *, slice_object: ABCSlice, new_state: SliceState):
"""
Modify the slice registered with the actor. Moves the slice into Modifying State
Args:
slice_object: slice_object
new_state: new_state
Raises:
Exception in case of error
"""
Expand Down
6 changes: 4 additions & 2 deletions fabric_cf/actor/core/apis/abc_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def update_slice(self, *, slice_object: ABCSlice):
def get_reservations(self, *, slice_id: ID = None, graph_node_id: str = None, project_id: str = None,
email: str = None, oidc_sub: str = None, rid: ID = None, states: list[int] = None,
site: str = None, rsv_type: list[str] = None, start: datetime = None,
end: datetime = None) -> List[ABCReservationMixin]:
end: datetime = None, ip_subnet: str = None, host: str = None) -> List[ABCReservationMixin]:
"""
Retrieves the reservations.
Expand All @@ -172,7 +172,8 @@ def get_reservations(self, *, slice_id: ID = None, graph_node_id: str = None, pr

@abstractmethod
def get_components(self, *, node_id: str, states: list[int], rsv_type: list[str], component: str = None,
bdf: str = None, start: datetime = None, end: datetime = None) -> Dict[str, List[str]]:
bdf: str = None, start: datetime = None, end: datetime = None,
excludes: List[str] = None) -> Dict[str, List[str]]:
"""
Returns components matching the search criteria
@param node_id: Worker Node ID to which components belong
Expand All @@ -182,6 +183,7 @@ def get_components(self, *, node_id: str, states: list[int], rsv_type: list[str]
@param bdf: Component's PCI address
@param start: start time
@param end: end time
@param excludes: Excludes the list of reservations
NOTE# For P4 switches; node_id=node+renc-p4-sw component=ip+192.168.11.8 bdf=p1
Expand Down
6 changes: 4 additions & 2 deletions fabric_cf/actor/core/apis/abc_mgmt_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from typing import TYPE_CHECKING, List, Tuple, Dict

from fabric_mb.message_bus.messages.delegation_avro import DelegationAvro
from fabric_mb.message_bus.messages.poa_avro import PoaAvro
from fabric_mb.message_bus.messages.poa_info_avro import PoaInfoAvro
from fabric_mb.message_bus.messages.site_avro import SiteAvro

Expand Down Expand Up @@ -151,7 +150,8 @@ def accept_update_slice(self, *, slice_id: ID) -> bool:
@abstractmethod
def get_reservations(self, *, states: List[int] = None, slice_id: ID = None,
rid: ID = None, oidc_claim_sub: str = None, email: str = None, rid_list: List[str] = None,
type: str = None, site: str = None, node_id: str = None) -> List[ReservationMng]:
type: str = None, site: str = None, node_id: str = None,
host: str = None, ip_subnet: str = None) -> List[ReservationMng]:
"""
Get Reservations
@param states states
Expand All @@ -163,6 +163,8 @@ def get_reservations(self, *, states: List[int] = None, slice_id: ID = None,
@param type type of reservations like NodeSliver/NetworkServiceSliver
@param site site
@param node_id node id
@param ip_subnet ip subnet
@param host host
Obtains all reservations
@return returns list of the reservations
"""
Expand Down
10 changes: 10 additions & 0 deletions fabric_cf/actor/core/apis/abc_reservation_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from enum import Enum
from typing import TYPE_CHECKING

from fabric_cf.actor.core.time.term import Term

from fabric_cf.actor.core.apis.abc_reservation_resources import ABCReservationResources
from fabric_cf.actor.core.apis.abc_reservation_status import ABCReservationStatus

Expand Down Expand Up @@ -541,5 +543,13 @@ def poa_info(self, *, incoming: Poa):
"""
Process POA response
@throws Exception in case of error
"""

@abstractmethod
def get_term(self) -> Term:
"""
Return Tem
@throws Exception in case of error
"""
6 changes: 5 additions & 1 deletion fabric_cf/actor/core/common/event_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from fabric_mb.message_bus.messages.slice_avro import SliceAvro
from fim.logging.log_collector import LogCollector
from fim.slivers.base_sliver import BaseSliver
from fim.slivers.network_node import NodeSliver
from fim.user.topology import ExperimentTopology

from fabric_cf.actor.core.common.constants import Constants
Expand Down Expand Up @@ -98,7 +99,7 @@ def log_sliver_event(self, *, slice_object: SliceAvro, sliver: BaseSliver, verb:

owner = slice_object.get_owner()
log_message = f"CFEL Sliver event slc:{slice_object.get_slice_id()} " \
f"slvr:{sliver.get_reservation_info().reservation_id} of " \
f"slvr:{sliver.get_reservation_info().reservation_id}/{sliver.get_name()} of " \
f"type {sliver.get_type()} {verb} " \
f"by prj:{slice_object.get_project_id()} usr:{owner.get_oidc_sub_claim()}" \
f":{owner.get_email()}"
Expand All @@ -112,6 +113,9 @@ def log_sliver_event(self, *, slice_object: SliceAvro, sliver: BaseSliver, verb:

log_message += f" {str(lc)}"

if isinstance(sliver, NodeSliver) and sliver.get_image_ref():
log_message += f" image:{sliver.get_image_ref()}"

self.logger.info(log_message)
except Exception as e:
traceback.print_exc()
Expand Down
4 changes: 2 additions & 2 deletions fabric_cf/actor/core/core/actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,8 @@ def register(self, *, reservation: ABCReservationMixin):
def register_slice(self, *, slice_object: ABCSlice):
self.wrapper.register_slice(slice_object=slice_object)

def modify_slice(self, *, slice_object: ABCSlice):
self.wrapper.modify_slice(slice_object=slice_object)
def modify_slice(self, *, slice_object: ABCSlice, new_state: SliceState):
self.wrapper.modify_slice(slice_object=slice_object, new_state=new_state)

def delete_slice(self, *, slice_id: ID):
self.wrapper.delete_slice(slice_id=slice_id)
Expand Down
4 changes: 4 additions & 0 deletions fabric_cf/actor/core/kernel/broker_reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ def probe_pending(self):
self.transition(prefix="Recover from Extend Failure", state=ReservationStates.Ticketed,
pending=ReservationPendingStates.None_)
self.extend_failure = False
self.update_data.clear(clear_fail=True)
self.error_message = ""
else:
if self.pending_state == ReservationPendingStates.Ticketing:
# Check for a pending ticket operation that may have completed
Expand Down Expand Up @@ -559,7 +561,9 @@ def handle_failed_rpc(self, *, failed: FailedRPC):
super().handle_failed_rpc(failed=failed)

def fail_extend(self, *, message: str, exception: Exception = None):
self.logger.debug(f"Failed Extend: {message}")
self.extend_failure = True
self.notified_failed = False
super().fail(message=message, exception=exception)


Expand Down
9 changes: 7 additions & 2 deletions fabric_cf/actor/core/kernel/kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,10 +872,11 @@ def register_reservation(self, *, reservation: ABCReservationMixin):
finally:
reservation.unlock()

def modify_slice(self, *, slice_object: ABCSlice):
def modify_slice(self, *, slice_object: ABCSlice, new_state: SliceState):
"""
Modify the specified slice with the kernel.
@param slice_object slice_object
@param new_state new_state
@throws Exception in case of failure
"""
if slice_object is None:
Expand All @@ -891,7 +892,11 @@ def modify_slice(self, *, slice_object: ABCSlice):
if not real.is_dead_or_closing():
real.set_config_properties(value=slice_object.get_config_properties())
# Transition slice to Configuring state
real.transition_slice(operation=SliceStateMachine.MODIFY)
if new_state == SliceState.Modifying:
operation = SliceStateMachine.MODIFY
else:
operation = SliceStateMachine.RENEW
real.transition_slice(operation=operation)
real.set_graph_id(graph_id=slice_object.get_graph_id())
real.set_dirty()
self.plugin.get_database().update_slice(slice_object=real)
Expand Down
6 changes: 4 additions & 2 deletions fabric_cf/actor/core/kernel/kernel_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from datetime import datetime
from typing import List, Dict

from fabric_cf.actor.core.kernel.slice_state_machine import SliceState
from fabric_mb.message_bus.messages.poa_info_avro import PoaInfoAvro
from fim.slivers.base_sliver import BaseSliver

Expand Down Expand Up @@ -769,16 +770,17 @@ def register_delegation(self, *, delegation: ABCDelegation):

self.kernel.register_delegation(delegation=delegation)

def modify_slice(self, *, slice_object: ABCSlice):
def modify_slice(self, *, slice_object: ABCSlice, new_state: SliceState):
"""
Modify the slice registered with the kernel
@param slice_object slice_object
@param new_state new_state
@throws Exception in case of error
"""
if slice_object is None or slice_object.get_slice_id() is None or not isinstance(slice_object, ABCSlice):
raise KernelException("Invalid argument {}".format(slice_object))

self.kernel.modify_slice(slice_object=slice_object)
self.kernel.modify_slice(slice_object=slice_object, new_state=new_state)

def delete_slice(self, *, slice_id: ID):
"""
Expand Down
28 changes: 19 additions & 9 deletions fabric_cf/actor/core/kernel/reservation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ def absorb_ticket_update(self, *, incoming: ABCReservationMixin, update_data: Up
self.resources.update(reservation=self, resource_set=incoming.get_resources())
self.logger.debug("absorb_update: {}".format(incoming))

# Clear error message from previous Extend operations
self.error_message = ""

#if self.resources.get_sliver().reservation_info:
# self.resources.get_sliver().reservation_info.error_message = self.error_message

self.policy.update_ticket_complete(reservation=self)

def accept_lease_update(self, *, incoming: ABCReservationMixin, update_data: UpdateData) -> bool:
Expand Down Expand Up @@ -623,9 +629,9 @@ def can_renew(self) -> bool:

return self.last_ticket_update.successful()

def clear_notice(self, clear_fail: bool=False):
self.last_ticket_update.clear()
self.last_lease_update.clear()
def clear_notice(self, clear_fail: bool = False):
self.last_ticket_update.clear(clear_fail=clear_fail)
self.last_lease_update.clear(clear_fail=clear_fail)

def do_relinquish(self):
"""
Expand Down Expand Up @@ -880,9 +886,11 @@ def get_last_ticket_update(self) -> str:
if self.last_ticket_update is not None:
if self.last_ticket_update.get_message() is not None and self.last_ticket_update.get_message() != "":
result += f"{self.last_ticket_update.get_message()}, "
ev = self.last_ticket_update.get_events()
if ev is not None and ev != "":
result += f"events: {ev}, "
# Include events only in case of failure
if self.last_ticket_update.is_failed():
ev = self.last_ticket_update.get_events()
if ev is not None and ev != "":
result += f"events: {ev}, "
result = result[:-2]
return result

Expand All @@ -891,9 +899,11 @@ def get_last_lease_update(self) -> str:
if self.last_lease_update is not None:
if self.last_lease_update.get_message() is not None and self.last_lease_update.get_message() != "":
result += f"{self.last_lease_update.get_message()}, "
ev = self.last_lease_update.get_events()
if ev is not None and ev != "":
result += f"events: {ev}, "
# Include events only in case of failure
if self.last_lease_update.is_failed():
ev = self.last_lease_update.get_events()
if ev is not None and ev != "":
result += f"events: {ev}, "
result = result[:-2]
return result

Expand Down
15 changes: 14 additions & 1 deletion fabric_cf/actor/core/kernel/reservation_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,22 @@
#
#
# Author: Komal Thareja ([email protected])
import enum
from enum import Enum


class ReservationOperation(enum.Enum):
Create = enum.auto(),
Modify = enum.auto(),
Extend = enum.auto()

def __repr__(self):
return self.name

def __str__(self):
return self.name


class ReservationStates(Enum):
"""
Reservation states
Expand Down Expand Up @@ -63,7 +76,7 @@ def translate(state_name: str):
elif state_name.lower() == ReservationStates.Failed.name.lower():
return ReservationStates.Failed
elif state_name.lower() == ReservationStates.CloseFail.name.lower():
return ReservationStates.Failed
return ReservationStates.CloseFail
else:
return ReservationStates.Unknown

Expand Down
13 changes: 12 additions & 1 deletion fabric_cf/actor/core/kernel/slice.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,18 @@ def is_dirty(self) -> bool:
return self.dirty

def transition_slice(self, *, operation: SliceOperation) -> Tuple[bool, SliceState]:
return self.state_machine.transition_slice(operation=operation, reservations=self.reservations)
status, new_state = self.state_machine.transition_slice(operation=operation, reservations=self.reservations)
if status and new_state in [SliceState.StableOK, SliceState.StableError]:
new_end = None
for r in self.reservations.values():
term = r.get_term()
if not new_end or (term and term.get_end_time() > new_end):
new_end = term.get_end_time()

if new_end:
self.lease_end = new_end

return status, new_state

def is_stable_ok(self) -> bool:
state_changed, slice_state = self.transition_slice(operation=SliceStateMachine.REEVALUATE)
Expand Down
7 changes: 7 additions & 0 deletions fabric_cf/actor/core/kernel/slice_state_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def is_modified(*, state) -> bool:
class SliceCommand(Enum):
Create = enum.auto()
Modify = enum.auto()
Renew = enum.auto()
Delete = enum.auto()
Reevaluate = enum.auto()
ModifyAccept = enum.auto()
Expand Down Expand Up @@ -198,6 +199,9 @@ class SliceStateMachine:
MODIFY = SliceOperation(SliceCommand.Modify, SliceState.StableOK, SliceState.StableError, SliceState.Configuring,
SliceState.AllocatedOK, SliceState.AllocatedError)

RENEW = SliceOperation(SliceCommand.Renew, SliceState.StableOK, SliceState.StableError, SliceState.AllocatedOK,
SliceState.ModifyOK, SliceState.ModifyError, SliceState.AllocatedError)

MODIFY_ACCEPT = SliceOperation(SliceCommand.ModifyAccept, SliceState.ModifyOK, SliceState.ModifyError,
SliceState.Modifying, SliceState.AllocatedOK, SliceState.AllocatedError)

Expand Down Expand Up @@ -247,6 +251,9 @@ def transition_slice(self, *, operation: SliceOperation, reservations: Reservati
if operation.command == SliceCommand.Create:
self.state = SliceState.Configuring

elif operation.command == SliceCommand.Renew:
self.state = SliceState.Configuring

elif operation.command == SliceCommand.Modify:
self.state = SliceState.Modifying

Expand Down
Loading

0 comments on commit b5371c1

Please sign in to comment.