[haizea-commit] r610 - branches/TP2.0/src/haizea/core
haizea-commit at mailman.cs.uchicago.edu
haizea-commit at mailman.cs.uchicago.edu
Mon Jul 20 11:04:28 CDT 2009
Author: borja
Date: 2009-07-20 11:04:22 -0500 (Mon, 20 Jul 2009)
New Revision: 610
Modified:
branches/TP2.0/src/haizea/core/leases.py
branches/TP2.0/src/haizea/core/manager.py
Log:
- Polished up documentation on manager.py
- Documented most of leases.py
Modified: branches/TP2.0/src/haizea/core/leases.py
===================================================================
--- branches/TP2.0/src/haizea/core/leases.py 2009-07-17 15:04:33 UTC (rev 609)
+++ branches/TP2.0/src/haizea/core/leases.py 2009-07-20 16:04:22 UTC (rev 610)
@@ -16,9 +16,21 @@
# limitations under the License. #
# -------------------------------------------------------------------------- #
-"""This module provides the lease data structures, and a couple of auxiliary
-data structures.
+"""This module provides the lease data structures:
+* Lease: Represents a lease
+* LeaseStateMachine: A state machine to keep track of a lease's state
+* Capacity: Used to represent a quantity of resources
+* Timestamp: An exact moment in time
+* Duration: A duration
+* SoftwareEnvironment, UnmanagedSoftwareEnvironment, DiskImageSoftwareEnvironment:
+ Used to represent a lease's required software environment.
+* LeaseWorkload: Represents a collection of lease requests submitted
+ in a specific order.
+* Site: Represents the site with leasable resources.
+* Nodes: Represents a collection of machines ("nodes"). This is used
+ both when specifying a site and when specifying the machines
+ needed by a leases.
"""
from haizea.common.constants import LOGLEVEL_VDEBUG
@@ -30,14 +42,25 @@
import logging
import xml.etree.ElementTree as ET
-#-------------------------------------------------------------------#
-# #
-# LEASE DATA STRUCTURES #
-# #
-#-------------------------------------------------------------------#
+
class Lease(object):
+ """A resource lease
+
+ This is one of the main data structures used in Haizea. A lease
+ is "a negotiated and renegotiable agreement between a resource
+ provider and a resource consumer, where the former agrees to make
+ a set of resources available to the latter, based on a set of
+ lease terms presented by the resource consumer". All the gory
+ details on what this means can be found on the Haizea website
+ and on the Haizea publications.
+
+ See the __init__ method for a description of the information that
+ is contained in a lease.
+
+ """
+
# Lease states
STATE_NEW = 0
STATE_PENDING = 1
@@ -58,6 +81,7 @@
STATE_DONE = 16
STATE_FAIL = 17
+ # String representation of lease states
state_str = {STATE_NEW : "New",
STATE_PENDING : "Pending",
STATE_REJECTED : "Rejected",
@@ -83,6 +107,7 @@
IMMEDIATE = 3
UNKNOWN = -1
+ # String representation of lease types
type_str = {BEST_EFFORT: "Best-effort",
ADVANCE_RESERVATION: "AR",
IMMEDIATE: "Immediate",
@@ -90,44 +115,174 @@
def __init__(self, submit_time, requested_resources, start, duration,
deadline, preemptible, software):
+ """Constructs a lease.
+
+ The arguments are the fundamental attributes of a lease.
+ The attributes that are not specified by the arguments are
+ the lease ID (which is an autoincremented integer), the
+ lease state (a lease always starts out in state "NEW").
+ A lease also has several bookkeeping attributes that are
+ only meant to be consumed by other Haizea objects.
+
+ Arguments:
+ submit_time -- The time at which the lease was submitted
+ requested_resources -- A dictionary (int -> Capacity) mapping
+ each requested node to a capacity (i.e., the amount of
+ resources requested for that node)
+ start -- A Timestamp object containing the requested time.
+ duration -- A Duration object containing the requested duration.
+ deadline -- A Timestamp object containing the deadline by which
+ this lease must be completed.
+ preemptible -- A boolean indicating whether this lease can be
+ preempted or not.
+ software -- A SoftwareEnvironment object specifying the
+ software environment required by the lease.
+ """
# Lease ID (read only)
self.id = get_lease_id()
- # Request attributes (read only)
+ # Lease attributes
self.submit_time = submit_time
+ self.requested_resources = requested_resources
self.start = start
self.duration = duration
- self.end = None
+ self.deadline = deadline
+ self.preemptible = preemptible
self.software = software
- self.requested_resources = requested_resources
- self.preemptible = preemptible
- # Bookkeeping attributes
- # (keep track of the lease's state, resource reservations, etc.)
+ # Bookkeeping attributes:
+
+ # Lease state
self.state = LeaseStateMachine()
+
+ # End of lease (recorded when the lease ends)
+ self.end = None
+
+ # Number of nodes requested in the lease
self.numnodes = len(requested_resources)
+
+ # The following two lists contain all the resource reservations
+ # (or RRs) associated to this lease. These two lists are
+ # basically the link between the lease and Haizea's slot table.
+
+ # The preparation RRs are reservations that have to be
+ # completed before a lease can first transition into a
+ # READY state (e.g., image transfers)
self.preparation_rrs = []
+ # The VM RRs are reservations for the VMs that implement
+ # the lease.
self.vm_rrs = []
# Enactment information. Should only be manipulated by enactment module
self.enactment_info = None
- self.vnode_enactment_info = dict([(n+1, None) for n in range(self.numnodes)])
+ self.vnode_enactment_info = dict([(n, None) for n in self.requested_resources.keys()])
self.logger = logging.getLogger("LEASES")
+ @classmethod
+ def from_xml_file(cls, xml_file):
+ """Constructs a lease from an XML file.
+
+ See the Haizea documentation for details on the
+ lease XML format.
+
+ Argument:
+ xml_file -- XML file containing the lease in XML format.
+ """
+ cls.from_xml_element(ET.parse(xml_file).getroot())
+
+ @classmethod
+ def from_xml_string(cls, xml_str):
+ """Constructs a lease from an XML string.
+
+ See the Haizea documentation for details on the
+ lease XML format.
+
+ Argument:
+ xml_str -- String containing the lease in XML format.
+ """
+ cls.from_xml_element(ET.parsestring(xml_str))
+
+ @classmethod
+ def from_xml_element(cls, element):
+ """Constructs a lease from an ElementTree element.
+
+ See the Haizea documentation for details on the
+ lease XML format.
+
+ Argument:
+ element -- Element object containing a "<lease>" element.
+ """
+ submit_time = Parser.DateTimeFromString(element.get("submit-time"))
+
+ nodes = Nodes.from_xml_element(element.find("nodes"))
+
+ requested_resources = nodes.get_all_nodes()
+
+ start = element.find("start")
+ if len(start.getchildren()) == 0:
+ start = Timestamp(None)
+ else:
+ exact = start.find("exact")
+ if exact != None:
+ start = Timestamp(Parser.DateTimeFromString(exact.get("time")))
+ # TODO: Other starting times
+
+ duration = Duration(Parser.DateTimeDeltaFromString(element.find("duration").get("time")))
+
+ deadline = None
+
+ preemptible = bool(element.get("preemptible"))
+
+ software = element.find("software")
+
+ if software.find("none") != None:
+ software = UnmanagedSoftwareEnvironment()
+ elif software.find("disk-image") != None:
+ disk_image = software.find("disk-image")
+ image_id = disk_image.get("id")
+ image_size = int(disk_image.get("size"))
+ software = DiskImageSoftwareEnvironment(image_id, image_size)
+
+ return Lease(submit_time, requested_resources, start, duration,
+ deadline, preemptible, software)
+
def get_type(self):
+ """Determines the type of lease
+
+ Based on the lease's attributes, determines the lease's type.
+ Can return Lease.BEST_EFFORT, Lease.ADVANCE_RESERVATION, or
+ Lease.IMMEDIATE
+
+ """
if self.start.requested == None:
return Lease.BEST_EFFORT
else:
return Lease.ADVANCE_RESERVATION
def get_state(self):
+ """Returns the lease's state.
+
+ """
return self.state.get_state()
def set_state(self, state):
+ """Changes the lease's state.
+
+ The state machine will throw an exception if the
+ requested transition is illegal.
+
+ Argument:
+ state -- The new state
+ """
self.state.change_state(state)
def print_contents(self, loglevel=LOGLEVEL_VDEBUG):
+ """Prints the lease's attributes to the log.
+
+ Argument:
+ loglevel -- The loglevel at which to print the information
+ """
self.logger.log(loglevel, "__________________________________________________")
self.logger.log(loglevel, "Lease ID : %i" % self.id)
self.logger.log(loglevel, "Type : %s" % Lease.type_str[self.get_type()])
@@ -141,6 +296,11 @@
self.logger.log(loglevel, "--------------------------------------------------")
def print_rrs(self, loglevel=LOGLEVEL_VDEBUG):
+ """Prints the lease's resource reservations to the log.
+
+ Argument:
+ loglevel -- The loglevel at which to print the information
+ """
if len(self.preparation_rrs) > 0:
self.logger.log(loglevel, "DEPLOYMENT RESOURCE RESERVATIONS")
self.logger.log(loglevel, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
@@ -154,47 +314,121 @@
self.logger.log(loglevel, "##")
def get_active_vmrrs(self, time):
+ """Returns the active VM resource reservations at a given time
+
+ Argument:
+ time -- Time to look for active reservations
+ """
return [r for r in self.vm_rrs if r.start <= time and time <= r.end and r.state == ResourceReservation.STATE_ACTIVE]
def get_scheduled_reservations(self):
+ """Returns all scheduled reservations
+
+ """
return [r for r in self.preparation_rrs + self.vm_rrs if r.state == ResourceReservation.STATE_SCHEDULED]
+ def get_last_vmrr(self):
+ """Returns the last VM reservation for this lease.
+
+ """
+ return self.vm_rrs[-1]
+
def get_endtime(self):
+ """Returns the time at which the last VM reservation
+ for this lease ends.
+
+ Note that this is not necessarily the time at which the lease
+ will end, just the time at which the last currently scheduled
+ VM will end.
+
+ """
vmrr = self.get_last_vmrr()
return vmrr.end
-
+
def append_vmrr(self, vmrr):
+ """Adds a VM resource reservation to the lease.
+
+ Argument:
+ vmrr -- The VM RR to add.
+ """
self.vm_rrs.append(vmrr)
- def append_preparationrr(self, vmrr):
- self.preparation_rrs.append(vmrr)
+ def remove_vmrr(self, vmrr):
+ """Removes a VM resource reservation from the lease.
+ Argument:
+ vmrr -- The VM RR to remove.
+ """
+ if not vmrr in self.vm_rrs:
+ raise Exception, "Tried to remove an VM RR not contained in this lease"
+ else:
+ self.vm_rrs.remove(vmrr)
+
+ def append_preparationrr(self, preparation_rr):
+ """Adds a preparation resource reservation to the lease.
+
+ Argument:
+ preparation_rr -- The preparation RR to add.
+ """
+ self.preparation_rrs.append(preparation_rr)
+
def remove_preparationrr(self, preparation_rr):
+ """Removes a preparation resource reservation from the lease.
+
+ Argument:
+ preparation_rr -- The preparation RR to remove.
+ """
if not preparation_rr in self.preparation_rrs:
raise Exception, "Tried to remove a preparation RR not contained in this lease"
else:
self.preparation_rrs.remove(preparation_rr)
- def get_last_vmrr(self):
- return self.vm_rrs[-1]
-
- def update_vmrr(self, rrold, rrnew):
- self.vm_rrs[self.vm_rrs.index(rrold)] = rrnew
-
- def remove_vmrr(self, vmrr):
- if not vmrr in self.vm_rrs:
- raise Exception, "Tried to remove an VM RR not contained in this lease"
- else:
- self.vm_rrs.remove(vmrr)
-
def clear_rrs(self):
+ """Removes all resource reservations for this lease
+ (both preparation and VM)
+
+ """
self.preparation_rrs = []
self.vm_rrs = []
def get_waiting_time(self):
+ """Gets the waiting time for this lease.
+
+ The waiting time is the difference between the submission
+ time and the time at which the lease start. This method
+ mostly makes sense for best-effort leases, where the
+ starting time is determined by Haizea.
+
+ """
return self.start.actual - self.submit_time
def get_slowdown(self, bound=10):
+ """Determines the bounded slowdown for this lease.
+
+ Slowdown is a normalized measure of how much time a
+ request takes to make it through a queue (thus, like
+ get_waiting_time, the slowdown makes sense mostly for
+ best-effort leases). Slowdown is equal to the time the
+ lease took to run on a loaded system (i.e., a system where
+ it had to compete with other leases for resources)
+ divided by the time it would take if it just had the
+ system all to itself (i.e., starts running immediately
+ without having to wait in a queue and without the
+ possibility of being preempted).
+
+ "Bounded" slowdown is one where leases with very short
+ durations are rounded up to a bound, to prevent the
+ metric to be affected by reasonable but disproportionate
+ waiting times (e.g., a 5-second lease with a 15 second
+ waiting time -an arguably reasonable waiting time- has a
+ slowdown of 4, the same as 10 hour lease having to wait
+ 30 hours for resources).
+
+ Argument:
+ bound -- The bound, specified in seconds.
+ All leases with a duration less than this
+ parameter are rounded up to the bound.
+ """
time_on_dedicated = self.duration.original
time_on_loaded = self.end - self.submit_time
bound = TimeDelta(seconds=bound)
@@ -203,82 +437,53 @@
return time_on_loaded / time_on_dedicated
def add_boot_overhead(self, t):
+ """Adds a boot overhead to the lease.
+
+ Increments the requested duration to account for the fact
+ that some time will be spent booting up the resources.
+
+ Argument:
+ t -- Time to add
+ """
self.duration.incr(t)
def add_runtime_overhead(self, percent):
- self.duration.incr_by_percent(percent)
+ """Adds a runtime overhead to the lease.
- def from_xml_file(self, xml_file):
- self.__from_xml(ET.parse(xml_file).getroot())
-
- def from_xml_string(self, xml):
- self.__from_xml(ET.parsestring(xml))
+ This method is mostly meant for simulations. Since VMs
+ run slower than physical hardware, this increments the
+ duration of a lease by a percent to observe the effect
+ of having all the leases run slower on account of
+ running on a VM.
- @classmethod
- def from_xml_element(cls, element):
- submit_time = Parser.DateTimeFromString(element.get("submit-time"))
+ Note: the whole "runtime overhead" problem is becoming
+ increasingly moot as people have lost their aversion to
+ VMs thanks to the cloud computing craze. Anecdotal evidence
+ suggests that most people don't care that VMs will run
+ X % slower (compared to a physical machine) because they
+ know full well that what they're getting is a virtual
+ machine (the same way a user of an HPC system would know
+ that he/she's getting processors with speed X as opposed to
+ those on some other site, with speed X*0.10)
- nodes = Nodes.from_xml_element(element.find("nodes"))
+ Argument:
+ percent -- Runtime overhead (in percent of requested
+ duration) to add to the lease.
+ """
+ self.duration.incr_by_percent(percent)
+
- requested_resources = nodes.get_all_nodes()
-
- start = element.find("start")
- if len(start.getchildren()) == 0:
- start = Timestamp(None)
- else:
- exact = start.find("exact")
- if exact != None:
- start = Timestamp(Parser.DateTimeFromString(exact.get("time")))
- # TODO: Other starting times
-
- duration = Duration(Parser.DateTimeDeltaFromString(element.find("duration").get("time")))
-
- deadline = None
-
- preemptible = bool(element.get("preemptible"))
-
- software = element.find("software")
-
- if software.find("none") != None:
- software = UnmanagedSoftwareEnvironment()
- elif software.find("disk-image") != None:
- disk_image = software.find("disk-image")
- image_id = disk_image.get("id")
- image_size = int(disk_image.get("size"))
- software = DiskImageSoftwareEnvironment(image_id, image_size)
-
- return Lease(submit_time, requested_resources, start, duration,
- deadline, preemptible, software)
-
- def get_leases(self):
- return self.entries
-
- def xmlrpc_marshall(self):
- # Convert to something we can send through XMLRPC
- l = {}
- l["id"] = self.id
- l["submit_time"] = xmlrpc_marshall_singlevalue(self.submit_time)
- l["start_req"] = xmlrpc_marshall_singlevalue(self.start.requested)
- l["start_sched"] = xmlrpc_marshall_singlevalue(self.start.scheduled)
- l["start_actual"] = xmlrpc_marshall_singlevalue(self.start.actual)
- l["duration_req"] = xmlrpc_marshall_singlevalue(self.duration.requested)
- l["duration_acc"] = xmlrpc_marshall_singlevalue(self.duration.accumulated)
- l["duration_actual"] = xmlrpc_marshall_singlevalue(self.duration.actual)
- l["end"] = xmlrpc_marshall_singlevalue(self.end)
- l["diskimage_id"] = self.diskimage_id
- l["diskimage_size"] = self.diskimage_size
- l["numnodes"] = self.numnodes
- l["resources"] = `self.requested_resources`
- l["preemptible"] = self.preemptible
- l["state"] = self.get_state()
- l["vm_rrs"] = [vmrr.xmlrpc_marshall() for vmrr in self.vm_rrs]
-
- return l
+class LeaseStateMachine(StateMachine):
+ """A lease state machine
- def __from_xml(self, leaseworkload_element):
- pass
-
-class LeaseStateMachine(StateMachine):
+ A child of StateMachine, this class simply specifies the valid
+ states and transitions for a lease (the actual state machine code
+ is in StateMachine).
+
+ See the Haizea documentation for a description of states and
+ valid transitions.
+
+ """
initial_state = Lease.STATE_NEW
transitions = {Lease.STATE_NEW: [(Lease.STATE_PENDING, "")],
@@ -351,41 +556,161 @@
def __init__(self):
StateMachine.__init__(self, LeaseStateMachine.initial_state, LeaseStateMachine.transitions, Lease.state_str)
+
class Capacity(object):
+ """A quantity of resources
+
+ This class is used to represent a quantity of resources, such
+ as those required by a lease. For example, if a lease needs a
+ single node with 1 CPU and 1024 MB of memory, a single Capacity
+ object would be used containing that information.
+
+ Resources in a Capacity object can be multi-instance, meaning
+ that several instances of the same type of resources can be
+ specified. For example, if a node requires 2 CPUs, then this is
+ represented as two instances of the same type of resource. Most
+ resources, however, will be "single instance" (e.g., a physical
+ node only has "one" memory).
+
+ Note: This class is similar, but distinct from, the ResourceTuple
+ class in the slottable module. The ResourceTuple class can contain
+ the same information, but uses a different internal representation
+ (which is optimized for long-running simulations) and is tightly
+ coupled to the SlotTable class. The Quantity and ResourceTuple
+ classes are kept separate so that the slottable module remains
+ independent from the rest of Haizea (in case we want to switch
+ to a different slottable implementation in the future).
+
+ """
def __init__(self, types):
+ """Constructs an empty Capacity object.
+
+ All resource types are initially set to be single-instance,
+ with a quantity of 0 for each resource.
+
+ Argument:
+ types -- List of resource types. e.g., ["CPU", "Memory"]
+ """
self.ninstances = dict([(type, 1) for type in types])
self.quantity = dict([(type, [0]) for type in types])
def get_quantity(self, type):
+ """Gets the quantity of a single-instance resource
+
+ Argument:
+ type -- The type of resource (using the same name passed
+ when constructing the Capacity object)
+ """
return self.get_quantity_instance(type, 1)
def get_quantity_instance(self, type, instance):
+ """Gets the quantity of a specific instance of a
+ multi-instance resource.
+
+ Argument:
+ type -- The type of resource (using the same name passed
+ when constructing the Capacity object)
+ instance -- The instance. Note that instances are numbered
+ from 1.
+ """
return self.quantity[type][instance-1]
def set_quantity(self, type, amount):
+ """Sets the quantity of a single-instance resource
+
+ Argument:
+ type -- The type of resource (using the same name passed
+ when constructing the Capacity object)
+ amount -- The amount to set the resource to.
+ """
self.set_quantity_instance(type, 1, amount)
def set_quantity_instance(self, type, instance, amount):
+ """Sets the quantity of a specific instance of a
+ multi-instance resource.
+
+ Argument:
+ type -- The type of resource (using the same name passed
+ when constructing the Capacity object)
+ instance -- The instance. Note that instances are numbered
+ from 1.
+ amount -- The amount to set the instance of the resource to.
+ """
self.quantity[type][instance-1] = amount
def set_ninstances(self, type, ninstances):
+ """Changes the number of instances of a resource type.
+
+ Note that changing the number of instances will initialize
+ all the instances' amounts to zero. This method should
+ only be called right after constructing a Capacity object.
+
+ Argument:
+ type -- The type of resource (using the same name passed
+ when constructing the Capacity object)
+ ninstance -- The number of instances
+ """
self.ninstances[type] = ninstances
self.quantity[type] = [0 for i in range(ninstances)]
-
+
def get_resource_types(self):
+ """Returns the types of resources in this capacity..
+
+ """
return self.quantity.keys()
class Timestamp(object):
+ """An exact point in time.
+
+ This class is just a wrapper around three DateTimes. When
+ dealing with timestamps in Haizea (such as the requested
+ starting time for a lease), we want to keep track not just
+ of the requested timestamp, but also the scheduled timestamp
+ (which could differ from the requested one) and the
+ actual timestamp (which could differ from the scheduled one).
+ """
def __init__(self, requested):
+ """Constructor
+
+ Argument:
+ requested -- The requested timestamp
+ """
self.requested = requested
self.scheduled = None
self.actual = None
def __repr__(self):
+ """Returns a string representation of the Duration"""
return "REQ: %s | SCH: %s | ACT: %s" % (self.requested, self.scheduled, self.actual)
class Duration(object):
+ """A duration
+
+ This class is just a wrapper around five DateTimes. When
+ dealing with durations in Haizea (such as the requested
+ duration for a lease), we want to keep track of the following:
+
+ - The requested duration
+ - The accumulated duration (when the entire duration of
+ the lease can't be scheduled without interrumption, this
+ keeps track of how much duration has been fulfilled so far)
+ - The actual duration (which might not be the same as the
+ requested duration)
+
+ For the purposes of simulation, we also want to keep track
+ of the "original" duration (since the requested duration
+ can be modified to simulate certain overheads) and the
+ "known" duration (when simulating lease workloads, this is
+ the actual duration of the lease, which is known a posteriori).
+ """
+
def __init__(self, requested, known=None):
+ """Constructor
+
+ Argument:
+ requested -- The requested duration
+ known -- The known duration (ONLY in simulation)
+ """
self.original = requested
self.requested = requested
self.accumulated = TimeDelta()
@@ -394,39 +719,96 @@
self.known = known
def incr(self, t):
+ """Increments the requested duration by an amount.
+
+ Argument:
+ t -- The time to add to the requested duration.
+ """
self.requested += t
if self.known != None:
self.known += t
def incr_by_percent(self, pct):
+ """Increments the requested duration by a percentage.
+
+ Argument:
+ pct -- The percentage of the requested duration to add.
+ """
factor = 1 + float(pct)/100
self.requested = round_datetime_delta(self.requested * factor)
if self.known != None:
self.requested = round_datetime_delta(self.known * factor)
def accumulate_duration(self, t):
+ """Increments the accumulated duration by an amount.
+
+ Argument:
+ t -- The time to add to the accumulated duration.
+ """
self.accumulated += t
def get_remaining_duration(self):
+ """Returns the amount of time required to fulfil the entire
+ requested duration of the lease.
+
+ """
return self.requested - self.accumulated
- # ONLY in simulation
def get_remaining_known_duration(self):
+ """Returns the amount of time required to fulfil the entire
+ known duration of the lease.
+
+ ONLY for simulations.
+ """
return self.known - self.accumulated
def __repr__(self):
+ """Returns a string representation of the Duration"""
return "REQ: %s | ACC: %s | ACT: %s | KNW: %s" % (self.requested, self.accumulated, self.actual, self.known)
class SoftwareEnvironment(object):
+ """The base class for a lease's software environment"""
+
def __init__(self):
+ """Constructor.
+
+ Does nothing."""
pass
class UnmanagedSoftwareEnvironment(SoftwareEnvironment):
+ """Represents an "unmanaged" software environment.
+
+ When a lease has an unmanaged software environment,
+ Haizea does not need to perform any actions to prepare
+ a lease's software environment (it assumes that this
+ task is carried out by an external entity, and that
+ software environments can be assumed to be ready
+ when a lease has to start; e.g., if VM disk images are
+ predeployed on all physical nodes)."""
+
def __init__(self):
+ """Constructor.
+
+ Does nothing."""
pass
class DiskImageSoftwareEnvironment(SoftwareEnvironment):
+ """Reprents a software environment encapsulated in a disk image.
+
+ When a lease's software environment is contained in a disk image,
+ this disk image must be deployed to the physical nodes the lease
+ is mapped to before the lease can start. This means that the
+ preparation for this lease must be handled by a preparation
+ scheduler (see documentation in lease_scheduler) capable of
+ handling a DiskImageSoftwareEnvironment.
+ """
def __init__(self, image_id, image_size):
+ """Constructor.
+
+ Arguments:
+ image_id -- A unique identifier for the disk image required
+ by the lease.
+ image_size -- The size, in MB, of the disk image. """
self.image_id = image_id
self.image_size = image_size
@@ -482,7 +864,7 @@
def create_empty_resource_quantity(self):
return Capacity(self.resource_types)
- def get_resource_types_with_max_instances(self):
+ def get_resource_types(self):
max_ninstances = dict((rt, 1) for rt in self.resource_types)
for node_set in self.nodes.node_sets:
capacity = node_set[1]
Modified: branches/TP2.0/src/haizea/core/manager.py
===================================================================
--- branches/TP2.0/src/haizea/core/manager.py 2009-07-17 15:04:33 UTC (rev 609)
+++ branches/TP2.0/src/haizea/core/manager.py 2009-07-20 16:04:22 UTC (rev 610)
@@ -24,9 +24,9 @@
This module provides the following classes:
-* Manager: The resource manager itself. Pretty much everything else
+* Manager: Haizea itself. Pretty much everything else
is contained in this class.
-* Clock: A base class for the resource manager's clock.
+* Clock: A base class for Haizea's clock.
* SimulatedClock: A clock for simulations.
* RealClock: A clock that advances in realtime.
"""
@@ -150,7 +150,7 @@
resourcepool = ResourcePool(info_enact, vm_enact, deploy_enact)
# Slot table
- slottable = SlotTable(site.get_resource_types_with_max_instances())
+ slottable = SlotTable(site.get_resource_types())
for n in resourcepool.get_nodes() + resourcepool.get_aux_nodes():
rt = slottable.create_resource_tuple_from_capacity(n.capacity)
slottable.add_node(n.id, rt)
@@ -179,11 +179,10 @@
elif preparation_type == constants.PREPARATION_TRANSFER:
preparation_scheduler = ImageTransferPreparationScheduler(slottable, resourcepool, deploy_enact)
- # VM Scheduler
+ # VM mapper and scheduler
mapper = self.config.get("mapper")
mapper = mapper_mappings.get(mapper, mapper)
mapper = import_class(mapper)
-
mapper = mapper(slottable, self.policy)
vm_scheduler = VMScheduler(slottable, resourcepool, mapper)
@@ -408,7 +407,7 @@
def process_starting_reservations(self, time):
"""Process reservations starting/stopping at specified time"""
- # The scheduler takes care of this.
+ # The lease scheduler takes care of this.
try:
self.scheduler.process_starting_reservations(time)
except UnrecoverableError, exc:
@@ -419,7 +418,7 @@
def process_ending_reservations(self, time):
"""Process reservations starting/stopping at specified time"""
- # The scheduler takes care of this.
+ # The lease scheduler takes care of this.
try:
self.scheduler.process_ending_reservations(time)
except UnrecoverableError, exc:
@@ -460,7 +459,7 @@
"""Return next changepoint in the slot table"""
return self.scheduler.slottable.get_next_changepoint(self.clock.get_time())
- def exists_leases_in_rm(self):
+ def exists_more_leases(self):
"""Return True if there are any leases still "in the system" """
return self.scheduler.exists_scheduled_leases() or not self.scheduler.is_queue_empty()
@@ -703,7 +702,7 @@
# If there's no more leases in the system, and no more pending requests,
# then we're done.
- if not self.manager.exists_leases_in_rm() and not tracefrontend.exists_more_requests():
+ if not self.manager.exists_more_leases() and not tracefrontend.exists_more_requests():
self.done = True
# We can also be done if we've specified that we want to stop when
@@ -857,7 +856,7 @@
# fixed.
if self.manager.config._options.has_key("stop-when-no-more-leases"):
stop_when_no_more_leases = self.manager.config.get("stop-when-no-more-leases")
- if stop_when_no_more_leases and not self.manager.exists_leases_in_rm():
+ if stop_when_no_more_leases and not self.manager.exists_more_leases():
self.done = True
# Sleep
More information about the Haizea-commit
mailing list