Package haizea :: Package core :: Package frontends :: Module opennebula
[hide private]
[frames] | no frames]

Source Code for Module haizea.core.frontends.opennebula

  1  # -------------------------------------------------------------------------- # 
  2  # Copyright 2006-2009, University of Chicago                                 # 
  3  # Copyright 2008-2009, Distributed Systems Architecture Group, Universidad   # 
  4  # Complutense de Madrid (dsa-research.org)                                   # 
  5  #                                                                            # 
  6  # Licensed under the Apache License, Version 2.0 (the "License"); you may    # 
  7  # not use this file except in compliance with the License. You may obtain    # 
  8  # a copy of the License at                                                   # 
  9  #                                                                            # 
 10  # http://www.apache.org/licenses/LICENSE-2.0                                 # 
 11  #                                                                            # 
 12  # Unless required by applicable law or agreed to in writing, software        # 
 13  # distributed under the License is distributed on an "AS IS" BASIS,          # 
 14  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   # 
 15  # See the License for the specific language governing permissions and        # 
 16  # limitations under the License.                                             # 
 17  # -------------------------------------------------------------------------- # 
 18   
 19  import haizea.common.constants as constants 
 20  from haizea.core.leases import Lease, Capacity, Timestamp, Duration, UnmanagedSoftwareEnvironment 
 21  from haizea.core.frontends import RequestFrontend 
 22  from haizea.common.utils import UNIX2DateTime, round_datetime, get_config, OpenNebulaXMLRPCClientSingleton 
 23  from haizea.common.opennebula_xmlrpc import OpenNebulaVM 
 24  from mx.DateTime import DateTimeDelta, ISO 
 25   
 26  import operator 
 27  import logging 
 28   
29 -class OpenNebulaHaizeaVM(object):
30 HAIZEA_PARAM = "HAIZEA" 31 HAIZEA_START = "START" 32 HAIZEA_START_NOW = "now" 33 HAIZEA_START_BESTEFFORT = "best_effort" 34 HAIZEA_DURATION = "DURATION" 35 HAIZEA_DURATION_UNLIMITED = "unlimited" 36 HAIZEA_PREEMPTIBLE = "PREEMPTIBLE" 37 HAIZEA_PREEMPTIBLE_YES = "yes" 38 HAIZEA_PREEMPTIBLE_NO = "no" 39 HAIZEA_GROUP = "GROUP" 40 41
42 - def __init__(self, opennebula_vm):
43 # If there is no HAIZEA parameter, the default is to treat the 44 # request as an immediate request with unlimited duration 45 if not opennebula_vm.template.has_key(OpenNebulaHaizeaVM.HAIZEA_PARAM): 46 self.start = OpenNebulaHaizeaVM.HAIZEA_START_NOW 47 self.duration = OpenNebulaHaizeaVM.HAIZEA_DURATION_UNLIMITED 48 self.preemptible = OpenNebulaHaizeaVM.HAIZEA_PREEMPTIBLE_NO 49 self.group = None 50 else: 51 self.start = opennebula_vm.template[OpenNebulaHaizeaVM.HAIZEA_PARAM][OpenNebulaHaizeaVM.HAIZEA_START] 52 self.duration = opennebula_vm.template[OpenNebulaHaizeaVM.HAIZEA_PARAM][OpenNebulaHaizeaVM.HAIZEA_DURATION] 53 self.preemptible = opennebula_vm.template[OpenNebulaHaizeaVM.HAIZEA_PARAM][OpenNebulaHaizeaVM.HAIZEA_PREEMPTIBLE] 54 if opennebula_vm.template[OpenNebulaHaizeaVM.HAIZEA_PARAM].has_key(OpenNebulaHaizeaVM.HAIZEA_GROUP): 55 self.group = opennebula_vm.template[OpenNebulaHaizeaVM.HAIZEA_PARAM][OpenNebulaHaizeaVM.HAIZEA_GROUP] 56 else: 57 self.group = None 58 59 self.submit_time = UNIX2DateTime(opennebula_vm.stime) 60 61 # Create Timestamp object 62 if self.start == OpenNebulaHaizeaVM.HAIZEA_START_NOW: 63 self.start = Timestamp(Timestamp.NOW) 64 elif self.start == OpenNebulaHaizeaVM.HAIZEA_START_BESTEFFORT: 65 self.start = Timestamp(Timestamp.UNSPECIFIED) 66 elif self.start[0] == "+": 67 # Relative time 68 self.start = Timestamp(round_datetime(self.submit_time + ISO.ParseTime(self.start[1:]))) 69 else: 70 self.start = Timestamp(ISO.ParseDateTime(self.start)) 71 72 # Create Duration object 73 if self.duration == OpenNebulaHaizeaVM.HAIZEA_DURATION_UNLIMITED: 74 # This is an interim solution (make it run for a century). 75 # TODO: Integrate concept of unlimited duration in the lease datastruct 76 self.duration = Duration(DateTimeDelta(36500)) 77 else: 78 self.duration = Duration(ISO.ParseTimeDelta(self.duration)) 79 80 81 self.preemptible = (self.preemptible == OpenNebulaHaizeaVM.HAIZEA_PREEMPTIBLE_YES) 82 83 84 self.capacity = Capacity([constants.RES_CPU, constants.RES_MEM, constants.RES_DISK]) 85 86 # CPU 87 # CPUs in VMs are not reported the same as in hosts. 88 # THere are two template values: CPU and VCPU. 89 # CPU reports the percentage of the CPU needed by the VM. 90 # VCPU, which is optional, reports how many CPUs are needed. 91 cpu = int(float(opennebula_vm.template["CPU"]) * 100) 92 if opennebula_vm.template.has_key("VCPU"): 93 ncpu = int(opennebula_vm.template["VCPU"]) 94 else: 95 ncpu = 1 96 self.capacity.set_ninstances(constants.RES_CPU, ncpu) 97 for i in range(ncpu): 98 self.capacity.set_quantity_instance(constants.RES_CPU, i+1, cpu) 99 100 # Memory. Unlike hosts, memory is reported directly in MBs 101 self.capacity.set_quantity(constants.RES_MEM, int(opennebula_vm.template["MEMORY"])) 102 103 self.one_id = opennebula_vm.id
104 105
106 -class OpenNebulaFrontend(RequestFrontend):
107
108 - def __init__(self):
109 self.processed = [] 110 self.logger = logging.getLogger("ONEREQ") 111 self.rpc = OpenNebulaXMLRPCClientSingleton().client
112
113 - def load(self, manager):
114 pass
115
116 - def get_accumulated_requests(self):
117 vms = self.rpc.vmpool_info() 118 119 # Extract the pending OpenNebula VMs 120 pending_vms = [] 121 for vm in vms: 122 if not vm.id in self.processed and vm.state == OpenNebulaVM.STATE_PENDING: 123 vm_detailed = self.rpc.vm_info(vm.id) 124 pending_vms.append(OpenNebulaHaizeaVM(vm_detailed)) 125 self.processed.append(vm.id) 126 127 grouped = [vm for vm in pending_vms if vm.group != None] 128 not_grouped = [vm for vm in pending_vms if vm.group == None] 129 130 # Extract VM groups 131 group_ids = set([vm.group for vm in grouped]) 132 groups = {} 133 for group_id in group_ids: 134 groups[group_id] = [vm for vm in grouped if vm.group == group_id] 135 136 lease_requests = [] 137 for group_id, opennebula_vms in groups.items(): 138 lease_requests.append(self.__ONEreqs_to_lease(opennebula_vms, group_id)) 139 140 for opennebula_vm in not_grouped: 141 lease_requests.append(self.__ONEreqs_to_lease([opennebula_vm])) 142 143 lease_requests.sort(key=operator.attrgetter("submit_time")) 144 return lease_requests
145
146 - def exists_more_requests(self):
147 return True
148 149
150 - def __ONEreqs_to_lease(self, opennebula_vms, group_id=None):
151 # The vm_with_params is used to extract the HAIZEA parameters. 152 # (i.e., lease-wide attributes) 153 vm_with_params = opennebula_vms[0] 154 155 # Per-lease attributes 156 start = vm_with_params.start 157 duration = vm_with_params.duration 158 preemptible = vm_with_params.preemptible 159 submit_time = vm_with_params.submit_time 160 161 # Per-vnode attributes 162 requested_resources = dict([(i+1,vm.capacity) for i, vm in enumerate(opennebula_vms)]) 163 164 lease = Lease.create_new(submit_time = submit_time, 165 requested_resources = requested_resources, 166 start = start, 167 duration = duration, 168 deadline = None, 169 preemptible = preemptible, 170 software = UnmanagedSoftwareEnvironment()) 171 172 lease.enactment_info = group_id 173 lease.vnode_enactment_info = dict([(i+1,vm.one_id) for i, vm in enumerate(opennebula_vms)]) 174 return lease
175