Project

General

Profile

root / branches / 1.1 / src / haizea / common / utils.py @ 846

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
from mx import DateTime
20
from math import ceil, floor
21
from cPickle import dump, load, HIGHEST_PROTOCOL
22
from datetime import datetime
23
from mx.DateTime import TimeDelta
24
import re
25
import textwrap
26

    
27
def generate_config_name(profile, tracefile, annotationfile, injectedfile):
28
    tracename=tracefile.split("/")[-1].split(".")[0]
29
    
30
    if injectedfile != None and injectedfile != "None":
31
        injectname=injectedfile.split("/")[-1].split(".")[0]
32
        name = tracename + "+" + injectname
33
    else:
34
        name = tracename
35
        
36
    if annotationfile != None and annotationfile != "None":
37
        annotname=annotationfile.split("/")[-1].split(".")[0]
38
        name += "+" + annotname        
39
            
40
    name = profile + "_" + name
41
    return name
42
    
43
def round_datetime_delta(d):
44
    return DateTime.DateTimeDelta(d.day, d.hour, d.minute, int(ceil(d.second)))
45

    
46
def round_datetime(d):
47
    d += DateTime.TimeDelta(seconds=0.5)
48
    return DateTime.DateTime(d.year, d.month, d.day, d.hour, d.minute, int(floor(d.second)))
49

    
50
def UNIX2DateTime(t):
51
    return DateTime.TimestampFromTicks(t)
52

    
53
    
54
def vnodemapstr(vnodes):
55
    if len(vnodes) == 0:
56
        return "UNUSED"
57
    else:
58
        return ",".join(["L"+`l`+"V"+`v` for (l, v) in vnodes])
59
    
60
# Based on http://norvig.com/python-iaq.html
61
def abstract():
62
    import inspect
63
    caller = inspect.stack()[1][3]
64
    raise NotImplementedError(caller + ' must be implemented in subclass')
65

    
66
def pickle(data, filename):
67
    f = open (filename, "w")
68
    dump(data, f, protocol = HIGHEST_PROTOCOL)
69
    f.close()
70

    
71
def unpickle(filename):
72
    f = open (filename, "r")
73
    data = load(f)
74
    f.close()
75
    return data
76

    
77

    
78
LEASE_ID = 1
79

    
80
def get_lease_id():
81
    global LEASE_ID
82
    l = LEASE_ID
83
    LEASE_ID += 1
84
    return l
85

    
86
def reset_lease_id_counter():
87
    global LEASE_ID
88
    LEASE_ID = 1
89

    
90
def pretty_nodemap(nodes):
91
    pnodes = list(set(nodes.values()))
92
    normmap = [([y[0] for y in nodes.items() if y[1]==x], x) for x in pnodes]
93
    for m in normmap: m[0].sort()
94
    s = "   ".join([", ".join(["V"+`y` for y in x[0]])+" -> P" + `x[1]` for x in normmap])
95
    return s  
96

    
97
def estimate_transfer_time(size, bandwidth):
98
    bandwidthMBs = float(bandwidth) / 8
99
    seconds = size / bandwidthMBs
100
    return round_datetime_delta(DateTime.TimeDelta(seconds = seconds)) 
101
 
102
def xmlrpc_marshall_singlevalue(value):
103
    if isinstance(value, DateTime.DateTimeType):
104
        return datetime.fromtimestamp(value)
105
    elif isinstance(value, DateTime.DateTimeDeltaType):
106
        return value.seconds
107
    else:
108
        return value
109
    
110
def import_class(fq_name):
111
    fq_name = fq_name.split(".")
112
    package_name = ".".join(fq_name[:-1])
113
    class_name = fq_name[-1]
114
    module = __import__(package_name, globals(), locals(), [class_name])
115
    exec("cls = module.%s" % class_name)
116
    return cls
117
    
118
def rst2latex(text):
119
    from docutils.core import publish_string
120
    latex = textwrap.dedent(text).strip()
121
    latex = publish_string(latex,  writer_name="latex")
122
    latex = re.compile("\\\\begin{document}\n\n\\\\setlength{\\\\locallinewidth}{\\\\linewidth}\n\n(.*)\\\\end{document}", flags=re.DOTALL).search(latex)
123
    latex = latex.group(1)
124
    return latex
125

    
126
def compute_suspend_resume_time(mem, rate):
127
    """ Compute the time to suspend/resume a single VM
128
                        
129
    Arguments:
130
    mem -- Amount of memory used by the VM
131
    rate -- The rate at which an individual VM is suspended/resumed
132
    
133
    """            
134
    time = float(mem) / rate
135
    time = round_datetime_delta(TimeDelta(seconds = time))
136
    return time
137
    
138
class Singleton(type):
139
    """ 
140
    A singleton metaclass. 
141
    From: http://en.wikipedia.org/wiki/Singleton_pattern#Python
142
    """
143
    def __init__(self, name, bases, dict):
144
        super(Singleton, self).__init__(name, bases, dict)
145
        self.instance = None
146
 
147
    def __call__(self, *args, **kw):
148
        if self.instance is None:
149
            self.instance = super(Singleton, self).__call__(*args, **kw)
150
 
151
        return self.instance
152
    
153
    def reset_singleton(self):
154
        self.instance = None
155
 
156
def get_config():
157
    from haizea.core.manager import Manager
158
    return Manager().config
159

    
160
def get_clock():
161
    from haizea.core.manager import Manager
162
    return Manager().clock
163

    
164
def get_policy():
165
    from haizea.core.manager import Manager
166
    return Manager().policy
167

    
168
def get_persistence():
169
    from haizea.core.manager import Manager
170
    return Manager().persistence
171

    
172
class InvalidStateMachineTransition(Exception):
173
    pass
174

    
175
class StateMachine(object):
176
    def __init__(self, initial_state, transitions, state_str = None):
177
        self.state = initial_state
178
        self.transitions = transitions
179
        self.state_str = state_str
180

    
181
    def change_state(self, new_state):
182
        valid_next_states = [x[0] for x in self.transitions[self.state]]
183
        if new_state in valid_next_states:
184
            self.state = new_state
185
        else:
186
            raise InvalidStateMachineTransition, "Invalid transition. State is %s, wanted to change to %s, can only change to %s" % (self.get_state_str(self.state), self.get_state_str(new_state), [self.get_state_str(x) for x in valid_next_states])
187
        
188
    def get_state(self):
189
        return self.state
190
    
191
    def get_state_str(self, state):
192
        if self.state_str == None:
193
            return "%s" % state
194
        else:
195
            return self.state_str[state]
196
        
197
class OpenNebulaXMLRPCClientSingleton(object):
198
    
199
    __metaclass__ = Singleton
200
    
201
    def __init__(self, *args, **kwargs):
202
        from haizea.common.opennebula_xmlrpc import OpenNebulaXMLRPCClient
203
        self.client = OpenNebulaXMLRPCClient(*args, **kwargs)
204
        
205