def term_barcode_mx_date(barcode): "Возвращает дату/время генерации ШК типа mx.DateTime.DateTime" d0 = DateTime(2010, 1, 1, 0, 0, 0) minutes = numeral_systems.any_to_dec(barcode[7:12], 36) return d0 + TimeDelta(minutes=minutes)
def StrTomxTime(_timeStr, fmt={'hour':'%H', 'min':'%M'}, delim=":"): format = fmt['hour']+delim+fmt['min'] #_time = Time(*time.strptime(_timeStr,format)[3:5]) h,m=time.strptime(_timeStr,format)[3:5] _time = TimeDelta(hours=h,minutes=m) #strptime(abs,'%H:%M',today(second=0)) #_time = Time() return _time
def get_worktime(self, daytype): """ return a TimeDelta representing the amount of work time on datetime. """ res = TimeDelta(0) intervals = self._get_intervals(daytype) for from_time, to_time in intervals: res += to_time - from_time return res
def wakeup_interval_changed_callback(self, *args): h, m, s = ( self.builder.get_object('wakeup-interval-hours').get_text(), self.builder.get_object('wakeup-interval-minutes').get_text(), self.builder.get_object('wakeup-interval-seconds').get_text()) if not h: h = 0 if not s: s = 0 if not m: m = 0 try: self.config._options['wakeup-interval'] = TimeDelta(seconds=int(s), minutes=int(m), hours=int(h)) except: print "Invalid Wakeup interval value" self.config._options['wakeup-interval'] = TimeDelta(seconds=10)
def __init__(self, manager, quantum, non_sched, fastforward = False): """Initializes the real clock. Arguments: manager -- the resource manager quantum -- interval between clock wakeups fastforward -- if True, the clock won't actually sleep for the duration of the quantum.""" Clock.__init__(self, manager) self.fastforward = fastforward if not self.fastforward: self.lastwakeup = None else: self.lastwakeup = round_datetime(now()) self.logger = logging.getLogger("CLOCK") self.starttime = self.get_time() self.nextschedulable = None self.nextperiodicwakeup = None self.quantum = TimeDelta(seconds=quantum) self.non_sched = TimeDelta(seconds=non_sched)
def estimate_migration_time(self, lease): migration = get_config().get("migration") if migration == constants.MIGRATE_YES: vmrr = lease.get_last_vmrr() images_in_pnode = dict([(pnode, 0) for pnode in set(vmrr.nodes.values())]) for (vnode, pnode) in vmrr.nodes.items(): images_in_pnode[pnode] += lease.software.image_size max_to_transfer = max(images_in_pnode.values()) bandwidth = self.resourcepool.info.get_migration_bandwidth() return estimate_transfer_time(max_to_transfer, bandwidth) elif migration == constants.MIGRATE_YES_NOTRANSFER: return TimeDelta(seconds=0)
def __load_option(self, sec, opt): # Load a single option secname = sec.name optname = opt.name has_option = self.config.has_option(secname, optname) if not has_option: if opt.required: raise ConfigException, "Required option '%s.%s' not found" % ( secname, optname) if opt.required_if != None: for req in opt.required_if: (condsec, condopt) = req[0] condvalue = req[1] if self.config.has_option( condsec, condopt) and self.config.get( condsec, condopt) == condvalue: raise ConfigException, "Option '%s.%s' is required when %s.%s==%s" % ( secname, optname, condsec, condopt, condvalue) value = opt.default else: if opt.type == OPTTYPE_INT: value = self.config.getint(secname, optname) elif opt.type == OPTTYPE_FLOAT: value = self.config.getfloat(secname, optname) elif opt.type == OPTTYPE_STRING: value = self.config.get(secname, optname) elif opt.type == OPTTYPE_BOOLEAN: value = self.config.getboolean(secname, optname) elif opt.type == OPTTYPE_DATETIME: value = self.config.get(secname, optname) value = ISO.ParseDateTime(value) elif opt.type == OPTTYPE_TIMEDELTA: value = self.config.getint(secname, optname) value = TimeDelta(seconds=value) if opt.valid != None: if not value in opt.valid: raise ConfigException, "Invalid value specified for '%s.%s'. Valid values are %s" % ( secname, optname, opt.valid) self._options[opt.getter] = value
def enactment_overhead_changed_callback(self, *args): h, m, s = ( self.builder.get_object('enactment-overhead-hours').get_text(), self.builder.get_object('enactment-overhead-minutes').get_text(), self.builder.get_object('enactment-overhead-seconds').get_text()) if not h: h = 0 if not s: s = 0 if not m: m = 0 try: self.config._options['enactment-overhead'] = TimeDelta( seconds=int(s), minutes=int(m), hours=int(h)) except: print "Invalid enactment-overhead value" self.config._options['enactment-overhead'] = None
def shutdown_time_changed_callback(self, *args): h, m, s = (self.builder.get_object('shutdown-time-hours').get_text(), self.builder.get_object('shutdown-time-minutes').get_text(), self.builder.get_object('shutdown-time-seconds').get_text()) if not h: h = 0 if not s: s = 0 if not m: m = 0 try: self.config._options['shutdown-time'] = TimeDelta(seconds=int(s), minutes=int(m), hours=int(h)) except: print "Invalid shutdown-time value" self.config._options['shutdown-time'] = None
def force_scheduling_threshold_changed_callback(self, *args): h, m, s = (self.builder.get_object( 'force-scheduling-threshold-hours').get_text(), self.builder.get_object( 'force-scheduling-threshold-minutes').get_text(), self.builder.get_object( 'force-scheduling-threshold-seconds').get_text()) if not h: h = 0 if not s: s = 0 if not m: m = 0 try: self.config._options['force-scheduling-threshold'] = TimeDelta( seconds=int(s), minutes=int(m), hours=int(h)) except: print "Invalid Wakeup interval value" self.config._options['force-scheduling-threshold'] = None
def adjustDateTime(adjustDelta, dateTime): """ sometimes a DateTime object has to be adjusted, when illegal components were specified adjustDateTime corrects DateTime object with specifications obtained from fixTimeComponents() input: adjustFlags is tuple/list of flags for adjusting ( increaseDay, increaseHour, increaseMin ) output: corrected DateTime object """ # Increase day dateTime += DateTimeDelta(adjustDelta[0]) # Increase hour dateTime += TimeDelta(adjustDelta[1]) # Increase minute dateTime += DateTimeDeltaFromSeconds(60.0 * adjustDelta[2]) return dateTime
def run(self): self.parse_options() infile = self.opt.inf outfile = self.opt.outf root = ET.Element("lease-workload") root.set("name", infile) description = ET.SubElement(root, "description") time = TimeDelta(seconds=0) lease_id = 1 requests = ET.SubElement(root, "lease-requests") infile = open(infile, "r") for line in infile: if line[0] != '#' and len(line.strip()) != 0: fields = line.split() submit_time = int(fields[0]) start_time = int(fields[1]) duration = int(fields[2]) real_duration = int(fields[3]) num_nodes = int(fields[4]) cpu = int(fields[5]) mem = int(fields[6]) disk = int(fields[7]) vm_image = fields[8] vm_imagesize = int(fields[9]) lease_request = ET.SubElement(requests, "lease-request") lease_request.set("arrival", str(TimeDelta(seconds=submit_time))) if real_duration != duration: realduration = ET.SubElement(lease_request, "realduration") realduration.set("time", str(TimeDelta(seconds=real_duration))) lease = ET.SubElement(lease_request, "lease") lease.set("id", ` lease_id `) nodes = ET.SubElement(lease, "nodes") node_set = ET.SubElement(nodes, "node-set") node_set.set("numnodes", ` num_nodes `) res = ET.SubElement(node_set, "res") res.set("type", "CPU") if cpu == 1: res.set("amount", "100") else: pass res = ET.SubElement(node_set, "res") res.set("type", "Memory") res.set("amount", ` mem `) start = ET.SubElement(lease, "start") if start_time == -1: lease.set("preemptible", "true") else: lease.set("preemptible", "false") exact = ET.SubElement(start, "exact") exact.set("time", str(TimeDelta(seconds=start_time))) duration_elem = ET.SubElement(lease, "duration") duration_elem.set("time", str(TimeDelta(seconds=duration))) software = ET.SubElement(lease, "software") diskimage = ET.SubElement(software, "disk-image") diskimage.set("id", vm_image) diskimage.set("size", ` vm_imagesize `) lease_id += 1 tree = ET.ElementTree(root) print ET.tostring(root)
def __init__(self, parent, bd=4, relief=RAISED): Frame.__init__(self, parent) ################################################################################## # Some variables for our use in the program snooze_min = 15 armed = False go_time = now() + TimeDelta(8,0,0) dt = TimeDelta(8,0,0) Update_per_sec = 2 ################################################################################## # Define some functions that may be handy to make the functions of an alarm clock def run_alarm(): update_fields() if self.armed: if self.go_time < now(): sound_alarm() self.after(1000 / Update_per_sec, run_alarm) # run N times per second # Runs the command in the "Halt Command" field when we snooze or halt the alarm def halt_alarm(): self.armed = False dt = TimeDelta(0,0,0) update_fields() os.system(halt_field.get() + '&') def snooze_alarm(): self.go_time = now() + TimeDelta(0,snooze_min,1) self.dt = TimeDelta(0,snooze_min) halt_alarm() self.armed = True run_alarm() # Runs the command in the "Alarm Command" field when the alarm is to go off def sound_alarm(): self.armed = False dt = TimeDelta(0,0,0) update_fields() os.system(run_field.get() + '&') # Refreshes the display fields to we can see the time count down def update_fields(): # find the new dt self.dt = self.go_time - now() # Clear the fields and then... time_field_hour.delete(0,END) time_field_min.delete(0,END) time_field_sec.delete(0,END) dt_field_hour.delete(0,END) dt_field_min.delete(0,END) dt_field_sec.delete(0,END) # fill them in again time_field_hour.insert(0,self.go_time.hour) time_field_min.insert(0,self.go_time.minute) time_field_sec.insert(0,int(self.go_time.second)) dt_field_hour.insert(0,self.dt.hour) dt_field_min.insert(0,self.dt.minute) dt_field_sec.insert(0,int(self.dt.second)) # Sets the time the alarm will go off def set_time(): h = int(time_field_hour.get()) m = int(time_field_min.get()) s = int(time_field_sec.get()) self.go_time = DateTime(now().year,now().month,now().day,h,m,s) if self.go_time < now(): self.go_time = DateTime(now().year, now().month, now().day + 1, h, m, s) self.dt = self.go_time - now() self.armed = True run_alarm() # Sets the alarm to go off after so long def set_dt(): self.dt = TimeDelta(int(dt_field_hour.get()),int(dt_field_min.get()),int(dt_field_sec.get())) self.go_time = now() + self.dt self.armed = True run_alarm() ################################################################################## # Here we build the GUI and make the button point to functions that do stuff for us. # This field takes the time we want the alarm to go off tmp_time = now() + TimeDelta(8,0,0) #Find sugested 8 hours from now time_field_hour = Entry(self, width=2) #Make the entry field time_field_hour.insert(0, tmp_time.hour) #Put the reccomended hour in time_field_min = Entry(self, width=2) time_field_min.insert(0, tmp_time.minute) time_field_sec = Entry(self, width=2) time_field_sec.insert(0, tmp_time.minute) time_field_label = Label(self, text="Alarm Time:") set_time_button = Button(self, text="Set Time", command=set_time) # This takes the amount of time we want to elapse before the alarm goes off dt_field_hour = Entry(self, width=2) dt_field_hour.insert(0, 8) dt_field_min = Entry(self, width=2) dt_field_min.insert(0, 0) dt_field_sec = Entry(self, width=2) dt_field_sec.insert(0, 0) dt_field_label = Label(self, text="Countdown:") set_dt_button = Button(self, text="Set Countdown", command=set_dt) # This field runs a command inserted into this field run_field = Entry(self) run_field.insert(0,'totem --play') run_field_label = Label(self, text="Alarm Command:") halt_field = Entry(self) halt_field.insert(0,'totem --pause') halt_field_label = Label(self, text="Stop Command:") # The quit button. Closes the window and exits the program quit_button = Button(self, text="Quit", command=root.quit) # The stop alarm button. Stops the alarm clock stop_button = Button(self, text="Stop Alarm", fg="red", command=halt_alarm) # This button starts the snooze sequence snooze_button = Button(self, text="Snooze " + str(snooze_min) + " min.", fg="red", command=snooze_alarm) #Set everything's location time_field_label.grid(row=0, column=0, sticky=W) time_field_hour.grid(row=0, column=1, sticky=W) Label(self, text=":").grid(row=0, column=2, sticky=W) time_field_min.grid(row=0, column=3, sticky=W) Label(self, text=":").grid(row=0, column=4, sticky=W) time_field_sec.grid(row=0, column=5, sticky=W) set_time_button.grid(row=0, column=6, sticky=EW) dt_field_label.grid(row=1, column=0, sticky=W) dt_field_hour.grid(row=1, column=1, sticky=W) Label(self, text=":").grid(row=1, column=2, sticky=W) dt_field_min.grid(row=1, column=3, sticky=W) Label(self, text=":").grid(row=1, column=4, sticky=W) dt_field_sec.grid(row=1, column=5, sticky=W) set_dt_button.grid(row=1, column=6, sticky=EW) rows = 7 columns = 7 run_field_label.grid(row=2, column=0, sticky=W) run_field.grid(row=2, column=1, columnspan=columns-1, sticky=EW) halt_field_label.grid(row=3, column=0, sticky=W) halt_field.grid(row=3, column=1, columnspan=columns-1, sticky=EW) snooze_button.grid(row=4, columnspan=columns, sticky=NSEW) stop_button.grid(row=5, columnspan=columns, sticky=NSEW) quit_button.grid(row=6, columnspan=columns, sticky=NSEW)
def LastTodayTime(): return today() + TimeDelta(hours=23, minutes=59, seconds=59)
def halt_alarm(): self.armed = False dt = TimeDelta(0,0,0) update_fields() os.system(halt_field.get() + '&')
def estimate_migration_time(self, lease): return TimeDelta(seconds=0)
from mx.DateTime import now, TimeDelta if 0: # Force import of the datetime module d = now() d.pydate() td = TimeDelta(3) print td td1 = td.rebuild() print td1 pytime = td.pytime() print pytime pydelta = td.pytimedelta() print pydelta
def snooze_alarm(): self.go_time = now() + TimeDelta(0,snooze_min,1) self.dt = TimeDelta(0,snooze_min) halt_alarm() self.armed = True run_alarm()
def set_dt(): self.dt = TimeDelta(int(dt_field_hour.get()),int(dt_field_min.get()),int(dt_field_sec.get())) self.go_time = now() + self.dt self.armed = True run_alarm()
def sound_alarm(): self.armed = False dt = TimeDelta(0,0,0) update_fields() os.system(run_field.get() + '&')
def Time(hour, minute, second): return TimeDelta(hour, minute, second)
class HaizeaConfig(Config): sections = [] # ============================= # # # # GENERAL OPTIONS # # # # ============================= # general = Section( "general", required=True, doc= "This section is used for general options affecting Haizea as a whole." ) general.options = \ [ Option(name = "loglevel", getter = "loglevel", type = OPTTYPE_STRING, required = False, default = "INFO", valid = ["STATUS","INFO","DEBUG","VDEBUG"], doc = """ Controls the level (and amount) of log messages. Valid values are: - STATUS: Only print status messages - INFO: Slightly more verbose that STATUS - DEBUG: Prints information useful for debugging the scheduler. - VDEBUG: Prints very verbose information on the scheduler's internal data structures. Use only for short runs. """), Option(name = "logfile", getter = "logfile", type = OPTTYPE_STRING, required = False, default = "/var/tmp/haizea.log", doc = """ When running Haizea as a daemon, this option specifies the file that log messages should be written to. """), Option(name = "mode", getter = "mode", type = OPTTYPE_STRING, required = True, valid = ["simulated","opennebula"], doc = """ Sets the mode the scheduler will run in. Currently the only valid values are "simulated" and "opennebula". The "simulated" mode expects lease requests to be provided through a trace file, and all enactment is simulated. The "opennebula" mode interacts with the OpenNebula virtual infrastructure manager (http://www.opennebula.org/) to obtain lease requests and to do enactment on physical resources. """), Option(name = "lease-preparation", getter = "lease-preparation", type = OPTTYPE_STRING, required = False, default = constants.PREPARATION_UNMANAGED, valid = [constants.PREPARATION_UNMANAGED, constants.PREPARATION_TRANSFER], doc = """ Sets how the scheduler will handle the preparation overhead of leases. Valid values are: - unmanaged: The scheduler can assume that there is no deployment overhead, or that some other entity is taking care of it (e.g., one of the enactment backends) - imagetransfer: A disk image has to be transferred from a repository node before the lease can start. """), Option(name = "lease-failure-handling", getter = "lease-failure-handling", type = OPTTYPE_STRING, required = False, default = constants.ONFAILURE_CANCEL, valid = [constants.ONFAILURE_CANCEL, constants.ONFAILURE_EXIT, constants.ONFAILURE_EXIT_RAISE], doc = """ Sets how the scheduler will handle a failure in a lease. Valid values are: - cancel: The lease is cancelled and marked as "FAILED" - exit: Haizea will exit cleanly, printing relevant debugging information to its log. - exit-raise: Haizea will exit by raising an exception. This is useful for debugging, as IDEs will recognize this as an exception and will facilitate debugging it. """), Option(name = "persistence-file", getter = "persistence-file", type = OPTTYPE_STRING, required = False, default = defaults.PERSISTENCE_LOCATION, doc = """ This is the file where lease information, along with some additional scheduling information, is persisted to. If set to "none", no information will be persisted to disk, and Haizea will run entirely in-memory (this is advisable when running in simulation, as persisting to disk adds considerable overhead, compared to running in-memory). """) ] sections.append(general) # ============================= # # # # SCHEDULING OPTIONS # # # # ============================= # scheduling = Section( "scheduling", required=True, doc="The options in this section control how Haizea schedules leases.") scheduling.options = \ [ Option(name = "mapper", getter = "mapper", type = OPTTYPE_STRING, required = False, default = "greedy", doc = """ VM-to-physical node mapping algorithm used by Haizea. There is currently only one mapper available (the greedy mapper). """), Option(name = "policy-admission", getter = "policy.admission", type = OPTTYPE_STRING, required = False, default = "accept-all", doc = """ Lease admission policy. This controls what leases are accepted by Haizea. Take into account that this decision takes place before Haizea even attempts to schedule the lease (so, you can think of lease admission as "eligibility to be scheduled"). There are two built-in policies: - accept-all: Accept all leases. - no-ARs: Accept all leases except advance reservations. See the Haizea documentation for details on how to write your own policies. """), Option(name = "policy-preemption", getter = "policy.preemption", type = OPTTYPE_STRING, required = False, default = "no-preemption", doc = """ Lease preemption policy. Determines what leases can be preempted. There are two built-in policies: - no-preemption: Do not allow any preemptions - ar-preempts-everything: Allow all ARs to preempt other leases. See the Haizea documentation for details on how to write your own policies. """), Option(name = "policy-matchmaking", getter = "policy.matchmaking", type = OPTTYPE_STRING, required = False, default = "condor", doc = ""), Option(name = "policy-host-selection", getter = "policy.host-selection", type = OPTTYPE_STRING, required = False, default = "greedy", doc = """ Physical host selection policy. controls how Haizea chooses what physical hosts to map VMs to. This option is closely related to the mapper options (if the greedy mapper is used, then the greedy host selection policy should be used, or unexpected results will happen). The two built-in policies are: - no-policy: Choose nodes arbitrarily - greedy: Apply a greedy policy that tries to minimize the number of preemptions. See the Haizea documentation for details on how to write your own policies. """), Option(name = "wakeup-interval", getter = "wakeup-interval", type = OPTTYPE_TIMEDELTA, required = False, default = TimeDelta(seconds=60), doc = """ Interval at which Haizea will wake up to manage resources and process pending requests. This option is not used when using a simulated clock, since the clock will skip directly to the time where an event is happening. """), Option(name = "backfilling", getter = "backfilling", type = OPTTYPE_STRING, required = False, default = None, valid = [constants.BACKFILLING_OFF, constants.BACKFILLING_AGGRESSIVE, constants.BACKFILLING_CONSERVATIVE, constants.BACKFILLING_INTERMEDIATE], doc = """ Backfilling algorithm to use. Valid values are: - off: don't do backfilling - aggressive: at most 1 reservation in the future - conservative: unlimited reservations in the future - intermediate: N reservations in the future (N is specified in the backfilling-reservations option) """), Option(name = "backfilling-reservations", getter = "backfilling-reservations", type = OPTTYPE_INT, required = False, required_if = [(("scheduling","backfilling"),constants.BACKFILLING_INTERMEDIATE)], doc = """ Number of future reservations to allow when using the "intermediate" backfilling option. """), Option(name = "suspension", getter = "suspension", type = OPTTYPE_STRING, required = True, valid = [constants.SUSPENSION_NONE, constants.SUSPENSION_SERIAL, constants.SUSPENSION_ALL], doc = """ Specifies what can be suspended. Valid values are: - none: suspension is never allowed - serial-only: only 1-node leases can be suspended - all: any lease can be suspended """), Option(name = "suspend-rate", getter = "suspend-rate", type = OPTTYPE_FLOAT, required = True, doc = """ Rate at which VMs are assumed to suspend (in MB of memory per second) """), Option(name = "resume-rate", getter = "resume-rate", type = OPTTYPE_FLOAT, required = True, doc = """ Rate at which VMs are assumed to resume (in MB of memory per second) """), Option(name = "suspendresume-exclusion", getter = "suspendresume-exclusion", type = OPTTYPE_STRING, required = False, default = constants.SUSPRES_EXCLUSION_LOCAL, valid = [constants.SUSPRES_EXCLUSION_LOCAL, constants.SUSPRES_EXCLUSION_GLOBAL], doc = """ When suspending or resuming a VM, the VM's memory is dumped to a file on disk. To correctly estimate the time required to suspend a lease with multiple VMs, Haizea makes sure that no two suspensions/resumptions happen at the same time (e.g., if eight memory files were being saved at the same time to disk, the disk's performance would be reduced in a way that is not as easy to estimate as if only one file were being saved at a time). Depending on whether the files are being saved to/read from a global or local filesystem, this exclusion can be either global or local. """), Option(name = "scheduling-threshold-factor", getter = "scheduling-threshold-factor", type = OPTTYPE_INT, required = False, default = 1, doc = """ To avoid thrashing, Haizea will not schedule a lease unless all overheads can be correctly scheduled (which includes image transfers, suspensions, etc.). However, this can still result in situations where a lease is prepared, and then immediately suspended because of a blocking lease in the future. The scheduling threshold factor can be used to specify that a lease must not be scheduled unless it is guaranteed to run for a minimum amount of time (the rationale behind this is that you ideally don't want leases to be scheduled if they're not going to be active for at least as much time as was spent in overheads). The default value is 1, meaning that the lease will be active for at least as much time T as was spent on overheads (e.g., if preparing the lease requires 60 seconds, and we know that it will have to be suspended, requiring 30 seconds, Haizea won't schedule the lease unless it can run for at least 90 minutes). In other words, a scheduling factor of F required a minimum duration of F*T. A value of 0 could lead to thrashing, since Haizea could end up with situations where a lease starts and immediately gets suspended. """), Option(name = "override-suspend-time", getter = "override-suspend-time", type = OPTTYPE_INT, required = False, default = None, doc = """ Overrides the time it takes to suspend a VM to a fixed value (i.e., not computed based on amount of memory, enactment overhead, etc.) """), Option(name = "override-resume-time", getter = "override-resume-time", type = OPTTYPE_INT, required = False, default = None, doc = """ Overrides the time it takes to suspend a VM to a fixed value (i.e., not computed based on amount of memory, enactment overhead, etc.) """), Option(name = "force-scheduling-threshold", getter = "force-scheduling-threshold", type = OPTTYPE_TIMEDELTA, required = False, doc = """ This option can be used to force a specific scheduling threshold time to be used, instead of calculating one based on overheads. """), Option(name = "migration", getter = "migration", type = OPTTYPE_STRING, required = False, default = constants.MIGRATE_NO, valid = [constants.MIGRATE_NO, constants.MIGRATE_YES, constants.MIGRATE_YES_NOTRANSFER], doc = """ Specifies whether leases can be migrated from one physical node to another. Valid values are: - no - yes - yes-notransfer: migration is performed without transferring any files. """), Option(name = "non-schedulable-interval", getter = "non-schedulable-interval", type = OPTTYPE_TIMEDELTA, required = False, default = TimeDelta(seconds=10), doc = """ The minimum amount of time that must pass between when a request is scheduled to when it can actually start. The default should be good for most configurations, but may need to be increased if you're dealing with exceptionally high loads. """), Option(name = "shutdown-time", getter = "shutdown-time", type = OPTTYPE_TIMEDELTA, required = False, default = TimeDelta(seconds=0), doc = """ The amount of time that will be allocated for a VM to shutdown. When running in OpenNebula mode, it is advisable to set this to a few seconds, so no operation gets scheduled right when a VM is shutting down. The most common scenario is that a VM will start resuming right when another VM shuts down. However, since both these activities involve I/O, it can delay the resume operation and affect Haizea's estimation of how long the resume will take. """), Option(name = "enactment-overhead", getter = "enactment-overhead", type = OPTTYPE_TIMEDELTA, required = False, default = TimeDelta(seconds=0), doc = """ The amount of time that is required to send an enactment command. This value will affect suspend/resume estimations and, in OpenNebula mode, will force a pause of this much time between suspend/resume enactment commands. When suspending/resuming many VMs at the same time (which is likely to happen if suspendresume-exclusion is set to "local"), it will take OpenNebula 1-2 seconds to process each command (this is a small amount of time, but if 32 VMs are being suspended at the same time, on in each physical node, this time can compound up to 32-64 seconds, which has to be taken into account when estimating when to start a suspend operation that must be completed before another lease starts). """) ] sections.append(scheduling) # ============================= # # # # SIMULATION OPTIONS # # # # ============================= # simulation = Section( "simulation", required=False, required_if=[(("general", "mode"), "simulated")], doc= "This section is used to specify options when Haizea runs in simulation" ) simulation.options = \ [ Option(name = "clock", getter = "clock", type = OPTTYPE_STRING, required = False, default = constants.CLOCK_REAL, valid = [constants.CLOCK_REAL, constants.CLOCK_SIMULATED], doc = """ Type of clock to use in simulation: - simulated: A simulated clock that fastforwards through time. Can only use the tracefile request frontend - real: A real clock is used, but simulated resources and enactment actions are used. Can only use the RPC request frontend. """), Option(name = "starttime", getter = "starttime", type = OPTTYPE_DATETIME, required = False, required_if = [(("simulation","clock"),constants.CLOCK_SIMULATED)], doc = """ Time at which simulated clock will start. """), Option(name = "resources", getter = "simul.resources", type = OPTTYPE_STRING, required = True, doc = """ Simulated resources. This option can take two values, "in-tracefile" (which means that the description of the simulated site is in the tracefile) or a string specifying a site with homogeneous resources. The format is: <numnodes> [ <resource_type>:<resource_quantity>]+ For example, "4 CPU:100 Memory:1024" describes a site with four nodes, each with one CPU and 1024 MB of memory. """), Option(name = "imagetransfer-bandwidth", getter = "imagetransfer-bandwidth", type = OPTTYPE_INT, required = True, doc = """ Bandwidth (in Mbps) available for image transfers. This would correspond to the outbound network bandwidth of the node where the images are stored. """), Option(name = "stop-when", getter = "stop-when", type = OPTTYPE_STRING, required = False, default = constants.STOPWHEN_ALLDONE, valid = [constants.STOPWHEN_ALLDONE, constants.STOPWHEN_BESUBMITTED, constants.STOPWHEN_BEDONE], doc = """ When using the simulated clock, this specifies when the simulation must end. Valid options are: - all-leases-done: All requested leases have been completed and there are no queued/pending requests. - besteffort-submitted: When all best-effort leases have been submitted. - besteffort-done: When all best-effort leases have been completed. """), Option(name = "status-message-interval", getter = "status-message-interval", type = OPTTYPE_INT, required = False, default = None, doc = """ If specified, the simulated clock will print a status message with some basic statistics. This is useful to keep track of long simulations. The interval is specified in minutes. """) ] sections.append(simulation) # ============================= # # # # ACCOUNTING OPTIONS # # # # ============================= # accounting = Section( "accounting", required=True, doc= "Haizea can collect information while running, and save that information to a file for off-line processing. This section includes options controlling this feature." ) accounting.options = \ [ Option(name = "datafile", getter = "datafile", type = OPTTYPE_STRING, required = False, default = None, doc = """ This is the file where statistics on the scheduler's run will be saved to (waiting time of leases, utilization data, etc.). If omitted, no data will be saved. """), Option(name = "probes", getter = "accounting-probes", type = OPTTYPE_STRING, required = False, doc = """ Accounting probes. There are four built-in probes: - AR: Collects information on AR leases. - best-effort: Collects information on best effort leases. - immediate: Collects information immediate leases. - utilization: Collects information on resource utilization. See the Haizea documentation for details on how to write your own accounting probes. """), Option(name = "attributes", getter = "attributes", type = OPTTYPE_STRING, required = False, doc = """ This option is used internally by Haizea when using multiconfiguration files. See the multiconfiguration documentation for more details. """) ] sections.append(accounting) # ============================= # # # # DEPLOYMENT OPTIONS # # (w/ image transfers) # # # # ============================= # imgtransfer = Section("deploy-imagetransfer", required=False, required_if=[(("general", "lease-deployment"), "imagetransfer")], doc=""" When lease deployment with disk image transfers is selected, this section is used to control image deployment parameters.""" ) imgtransfer.options = \ [ Option(name = "transfer-mechanism", getter = "transfer-mechanism", type = OPTTYPE_STRING, required = True, valid = [constants.TRANSFER_UNICAST, constants.TRANSFER_MULTICAST], doc = """ Specifies how disk images are transferred. Valid values are: - unicast: A disk image can be transferred to just one node at a time - multicast: A disk image can be multicast to multiple nodes at the same time. """), Option(name = "avoid-redundant-transfers", getter = "avoid-redundant-transfers", type = OPTTYPE_BOOLEAN, required = False, default = True, doc = """ Specifies whether the scheduler should take steps to detect and avoid redundant transfers (e.g., if two leases are scheduled on the same node, and they both require the same disk image, don't transfer the image twice; allow one to "piggyback" on the other). There is generally no reason to set this option to False. """), Option(name = "force-imagetransfer-time", getter = "force-imagetransfer-time", type = OPTTYPE_TIMEDELTA, required = False, doc = """ Forces the image transfer time to a specific amount. This options is intended for testing purposes. """), Option(name = "diskimage-reuse", getter = "diskimage-reuse", type = OPTTYPE_STRING, required = False, required_if = None, default = constants.REUSE_NONE, valid = [constants.REUSE_NONE, constants.REUSE_IMAGECACHES], doc = """ Specifies whether disk image caches should be created on the nodes, so the scheduler can reduce the number of transfers by reusing images. Valid values are: - none: No image reuse - image-caches: Use image caching algorithm described in Haizea publications """), Option(name = "diskimage-cache-size", getter = "diskimage-cache-size", type = OPTTYPE_INT, required = False, required_if = [(("deploy-imagetransfer","diskimage-reuse"),True)], doc = """ Specifies the size (in MB) of the disk image cache on each physical node. """) ] sections.append(imgtransfer) # ============================= # # # # TRACEFILE OPTIONS # # # # ============================= # tracefile = Section("tracefile", required=False, doc=""" When reading in requests from a tracefile, this section is used to specify the tracefile and other parameters.""") tracefile.options = \ [ Option(name = "tracefile", getter = "tracefile", type = OPTTYPE_STRING, required = True, doc = """ Path to tracefile to use. """), Option(name = "imagefile", getter = "imagefile", type = OPTTYPE_STRING, required = False, doc = """ Path to list of images to append to lease requests. If omitted, the images in the tracefile are used. """), Option(name = "injectionfile", getter = "injectionfile", type = OPTTYPE_STRING, required = False, doc = """ Path to file with leases to "inject" into the tracefile. """), Option(name = "runtime-slowdown-overhead", getter = "runtime-slowdown-overhead", type = OPTTYPE_FLOAT, required = False, default = 0, doc = """ Adds a runtime overhead (in %) to the lease duration. """), Option(name = "add-overhead", getter = "add-overhead", type = OPTTYPE_STRING, required = False, default = constants.RUNTIMEOVERHEAD_NONE, valid = [constants.RUNTIMEOVERHEAD_NONE, constants.RUNTIMEOVERHEAD_ALL, constants.RUNTIMEOVERHEAD_BE], doc = """ Specifies what leases will have a runtime overhead added: - none: No runtime overhead must be added. - besteffort: Add only to best-effort leases - all: Add runtime overhead to all leases """), Option(name = "bootshutdown-overhead", getter = "bootshutdown-overhead", type = OPTTYPE_TIMEDELTA, required = False, default = TimeDelta(seconds=0), doc = """ Specifies how many seconds will be alloted to boot and shutdown of the lease. """), Option(name = "override-memory", getter = "override-memory", type = OPTTYPE_INT, required = False, default = constants.NO_MEMORY_OVERRIDE, doc = """ Overrides memory requirements specified in tracefile. """), ] sections.append(tracefile) # ============================= # # # # OPENNEBULA OPTIONS # # # # ============================= # opennebula = Section("opennebula", required=False, required_if=[(("general", "mode"), "opennebula")], doc=""" This section is used to specify OpenNebula parameters, necessary when using Haizea as an OpenNebula scheduling backend.""" ) opennebula.options = \ [ Option(name = "host", getter = "one.host", type = OPTTYPE_STRING, required = True, doc = """ Host where OpenNebula is running. Typically, OpenNebula and Haizea will be installed on the same host, so the following option should be set to 'localhost'. If they're on different hosts, make sure you modify this option accordingly. """), Option(name = "port", getter = "one.port", type = OPTTYPE_INT, required = False, default = defaults.OPENNEBULA_RPC_PORT, doc = """ TCP port of OpenNebula's XML RPC server """), Option(name = "stop-when-no-more-leases", getter = "stop-when-no-more-leases", type = OPTTYPE_BOOLEAN, required = False, default = False, doc = """ This option is useful for testing and running experiments. If set to True, Haizea will stop when there are no more leases to process (which allows you to tun Haizea and OpenNebula unattended, and count on it stopping when there are no more leases to process). For now, this only makes sense if you're seeding Haizea with requests from the start (otherwise, it will start and immediately stop). """), Option(name = "dry-run", getter = "dry-run", type = OPTTYPE_BOOLEAN, required = False, default = False, doc = """ This option is useful for testing. If set to True, Haizea will fast-forward through time (note that this is different that using the simulated clock, which has to be used with a tracefile; with an Haizea/OpenNebula dry run, you will have to seed OpenNebula with requests before starting Haizea). You will generally want to set stop-when-no-more-leases when doing a dry-run. IMPORTANT: Haizea will still send out enactment commands to OpenNebula. Make sure you replace onevm with a dummy command that does nothing (or that reacts in some way you want to test; e.g., by emulating a deployment failure, etc.) """), ] sections.append(opennebula) def __init__(self, config): Config.__init__(self, config, self.sections) self.attrs = {} if self._options["attributes"] != None: attrs = self._options["attributes"].split(",") for attr in attrs: (k, v) = attr.split("=") self.attrs[k] = v def get_attr(self, attr): return self.attrs[attr] def get_attrs(self): return self.attrs.keys()