Project

General

Profile

root / trunk / src / haizea / common / utils.py @ 675

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 docutils.core import publish_string
24
import re
25
import textwrap
26

    
27
def generate_config_name(profile, tracefile, 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
    name = profile + "_" + name
37
    return name
38
    
39
def round_datetime_delta(d):
40
    return DateTime.DateTimeDelta(d.day, d.hour, d.minute, int(ceil(d.second)))
41

    
42
def round_datetime(d):
43
    d += DateTime.TimeDelta(seconds=0.5)
44
    return DateTime.DateTime(d.year, d.month, d.day, d.hour, d.minute, int(floor(d.second)))
45

    
46
def UNIX2DateTime(t):
47
    return DateTime.TimestampFromTicks(t)
48

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

    
62
def pickle(data, filename):
63
    f = open (filename, "w")
64
    dump(data, f, protocol = HIGHEST_PROTOCOL)
65
    f.close()
66

    
67
def unpickle(filename):
68
    f = open (filename, "r")
69
    data = load(f)
70
    f.close()
71
    return data
72

    
73

    
74
LEASE_ID = 1
75

    
76
def get_lease_id():
77
    global LEASE_ID
78
    l = LEASE_ID
79
    LEASE_ID += 1
80
    return l
81

    
82
def reset_lease_id_counter():
83
    global LEASE_ID
84
    LEASE_ID = 1
85

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

    
93
def estimate_transfer_time(size, bandwidth):
94
    bandwidthMBs = float(bandwidth) / 8
95
    seconds = size / bandwidthMBs
96
    return round_datetime_delta(DateTime.TimeDelta(seconds = seconds)) 
97
 
98
def xmlrpc_marshall_singlevalue(value):
99
    if isinstance(value, DateTime.DateTimeType):
100
        return datetime.fromtimestamp(value)
101
    elif isinstance(value, DateTime.DateTimeDeltaType):
102
        return value.seconds
103
    else:
104
        return value
105
    
106
def import_class(fq_name):
107
    fq_name = fq_name.split(".")
108
    package_name = ".".join(fq_name[:-1])
109
    class_name = fq_name[-1]
110
    module = __import__(package_name, globals(), locals(), [class_name])
111
    exec("cls = module.%s" % class_name)
112
    return cls
113
    
114
def rst2latex(text):
115
    latex = textwrap.dedent(text).strip()
116
    latex = publish_string(latex,  writer_name="latex")
117
    latex = re.compile("\\\\begin{document}\n\n\\\\setlength{\\\\locallinewidth}{\\\\linewidth}\n\n(.*)\\\\end{document}", flags=re.DOTALL).search(latex)
118
    latex = latex.group(1)
119
    return latex
120
    
121
class Singleton(type):
122
    """ 
123
    A singleton metaclass. 
124
    From: http://en.wikipedia.org/wiki/Singleton_pattern#Python
125
    """
126
    def __init__(self, name, bases, dict):
127
        super(Singleton, self).__init__(name, bases, dict)
128
        self.instance = None
129
 
130
    def __call__(self, *args, **kw):
131
        if self.instance is None:
132
            self.instance = super(Singleton, self).__call__(*args, **kw)
133
 
134
        return self.instance
135
    
136
    def reset_singleton(self):
137
        self.instance = None
138
 
139
def get_config():
140
    from haizea.core.manager import Manager
141
    return Manager().config
142

    
143
def get_clock():
144
    from haizea.core.manager import Manager
145
    return Manager().clock
146

    
147
def get_policy():
148
    from haizea.core.manager import Manager
149
    return Manager().policy
150

    
151
def get_persistence():
152
    from haizea.core.manager import Manager
153
    return Manager().persistence
154

    
155
class InvalidStateMachineTransition(Exception):
156
    pass
157

    
158
class StateMachine(object):
159
    def __init__(self, initial_state, transitions, state_str = None):
160
        self.state = initial_state
161
        self.transitions = transitions
162
        self.state_str = state_str
163

    
164
    def change_state(self, new_state):
165
        valid_next_states = [x[0] for x in self.transitions[self.state]]
166
        if new_state in valid_next_states:
167
            self.state = new_state
168
        else:
169
            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])
170
        
171
    def get_state(self):
172
        return self.state
173
    
174
    def get_state_str(self, state):
175
        if self.state_str == None:
176
            return "%s" % state
177
        else:
178
            return self.state_str[state]
179
        
180
class OpenNebulaXMLRPCClientSingleton(object):
181
    
182
    __metaclass__ = Singleton
183
    
184
    def __init__(self, *args, **kwargs):
185
        from haizea.common.opennebula_xmlrpc import OpenNebulaXMLRPCClient
186
        self.client = OpenNebulaXMLRPCClient(*args, **kwargs)
187
        
188