source: fedd/federation/emulab_segment.py @ 451fb96

compt_changesinfo-ops
Last change on this file since 451fb96 was 451fb96, checked in by Ted Faber <faber@…>, 9 years ago

typo. Closes #36

  • Property mode set to 100644
File size: 5.9 KB
Line 
1#!/usr/local/bin/python
2
3import logging 
4import util
5
6from M2Crypto import SSL
7from M2Crypto.m2xmlrpclib import SSL_Transport
8from xmlrpclib import ServerProxy, dumps, loads, Fault, Error, Binary
9from M2Crypto.SSL import SSLError
10from M2Crypto.BIO import BIOError
11from socket import error as socket_error
12from socket import sslerror
13import httplib
14from federation.util import fedd_ssl_context
15from federation import service_error
16
17class emulab_segment:
18    def __init__(self, boss, cert):
19        self.ctxt = fedd_ssl_context(my_cert=cert)
20        self.ctxt.set_verify(SSL.verify_none, 10)
21        self.boss = boss
22        self.null = """
23set ns [new Simulator]
24source tb_compat.tcl
25
26set a [$ns node]
27
28$ns rtproto Session
29$ns run
30"""
31        self.log =  getattr(self, 'log', None) 
32        self.debug = getattr(self, 'debug', False)
33
34    def emulab_call(self, method, params):
35        VERSION = 0.1
36        try:
37            transport = SSL_Transport(self.ctxt)
38            port = ServerProxy(self.boss, transport=transport)
39            remote_method = getattr(port, method, None)
40            if remote_method is not None:
41                resp = remote_method(VERSION, params)
42            else:
43                raise service_error(service_error.internal, 
44                        "Bad method: %s" % method)
45        except socket_error, e:
46            raise service_error(service_error.connect, 
47                    "Cannot connect" % e)
48            raise e
49        except BIOError, e:
50            if self.log:
51                self.log.warn("BIO error: %s" % e)
52            raise e
53        except sslerror, e:
54            if self.log:
55                self.log.warn("SSL (socket) error: %s" %  e)
56            raise e
57        except SSLError, e:
58            if self.log:
59                self.log.warn("SSL error: %s" % e)
60            raise e
61        except httplib.HTTPException, e:
62            if self.log:
63                self.log.warn("HTTP error: %s" % e)
64            raise e
65        except Fault, f:
66            raise service_error(service_error.protocol, 
67                    "Remote XMLRPC Fault: %s" % f)
68        except Error, e:
69            raise service_error(service_error.protocol, 
70                    "Remote XMLRPC Fault: %s" % e)
71
72        code = resp.get('code', -1)
73        if code ==0:
74            return (code, resp.get('value', None))
75        else:
76            return (code, resp.get('output', None))
77
78    def get_state(self, pid, eid):
79        """
80        Return the state of the experiment as reported by emulab
81        """
82
83        if self.debug:
84            state = 'swapped'
85        else:
86            params =  { 'proj': pid, 'exp': eid }
87            code, state = self.emulab_call('experiment.state', params)
88            if code != 0:
89                state = 'none'
90
91        if self.log:
92            self.log.debug("State is %s" % state)
93        return state
94
95    def make_null_experiment(self, pid, eid, tmpdir, gid=None):
96        """
97        Create a null copy of the experiment so that we capture any logs there
98        if the modify fails.  Emulab software discards the logs from a failed
99        startexp.
100        """
101
102        if self.debug:
103            if self.log:
104                self.log.debug("[make_null_experiment]: (debug) Creating experiment")
105            return True
106        else:
107            params = {
108                    'proj': pid,
109                    'exp': eid, 
110                    'nsfilestr': self.null,
111                    'batch': False,
112                    'idleswap': 0,
113                    'noidleswap_reason': 'Federated experiment',
114                    'noswapin': True,
115                    'wait': True
116                    }
117            if gid is not None:
118                params['group'] = gid
119            if self.log:
120                self.log.info("[make_null_experiment]: Creating experiment")
121            code, value = self.emulab_call('experiment.startexp', params)
122
123            if self.log:
124                if code == 0: 
125                    self.log.info('[make_null_experiment]: Create succeeded')
126                else: 
127                    self.log.error('[make_null_experiment]: Create failed: %s' \
128                            % value)
129
130            return code == 0
131
132    def swap_exp(self, pid, eid, direction='out', wait=True):
133        """
134        Swap experiment in.
135        """
136        if self.debug:
137            if self.log:
138                self.log.info("[swap_exp]: (debug) Swapping %s %s" % \
139                        (eid, direction))
140            return True
141        else:
142            if self.log:
143                self.log.info("[swap_exp]: Swapping %s %s" % (eid, direction))
144            params = {
145                    'proj': pid,
146                    'exp': eid,
147                    'direction': direction,
148                    'wait': wait,
149                    }
150            code, value = self.emulab_call('experiment.swapexp', params)
151
152            if self.log:
153                if code == 0: self.log.info('[swap_exp]: Swap succeeded')
154                else: self.log.error('[swap_exp]: Swap failed: %s' % value)
155
156        return code == 0
157
158    def terminate_exp(self, pid, eid, wait=True):
159        """
160        Completely terminate experiment
161        """
162        if self.debug:
163            if self.log:
164                self.log.info("[swap_exp]: (debug) terminate %s" %  eid)
165            return True
166        else:
167            if self.log:
168                self.log.info("[swap_exp]: Terminating %s" % eid)
169            params = {
170                    'proj': pid,
171                    'exp': eid,
172                    'wait': wait,
173                    }
174            code, value = self.emulab_call('experiment.endexp', params)
175
176            if self.log:
177                if code == 0: self.log.info('[swap_exp]: Terminate succeeded')
178                else: self.log.error('[swap_exp]: Terminate failed: %s' % value)
179
180        return code == 0
181
182    def modify_exp(self, pid, eid, tcl, wait=True):
183        if self.debug:
184            self.log.info("[modify_exp]: (debug) Modifying %s" % eid)
185            return True
186        else:
187            self.log.info("[modify_exp]: Modifying %s" % eid)
188            params = {
189                    'proj': pid,
190                    'exp': eid,
191                    'nsfilestr': tcl,
192                    'wait': wait,
193                    'reboot': True,
194                    'restart_eventsys': True,
195                    }
196            code, value = self.emulab_call('experiment.modify', params)
197            if self.log:
198                if code == 0: 
199                    self.log.info('[modify_exp]: Modify succeeded')
200                else: 
201                    self.log.error('[modify_exp]: Modify failed: %s' \
202                            % value)
203            return code == 0
204
205
206    def get_mapping(self, pid, eid):
207        """
208        Get the physical to virtual mapping from the expinfo command and save
209        it in the self.map member.
210        """
211
212        if self.debug:
213            if self.log:
214                self.log.info("[get_mapping] (debug) Generating mapping")
215                return True
216        else:
217            if self.log:
218                self.log.info("[get_mapping] Generating mapping")
219
220            params = {
221                    'proj': pid,
222                    'exp': eid,
223                    'aspect': 'mapping'
224                    }
225            code, nodes = self.emulab_call('experiment.info', params)
226            if code ==0:
227                for k, v in nodes.items():
228                    if v.get('erole', False) and 'pnode' in v:
229                        self.node[k] = v['pnode']
230                if self.log:
231                    self.log.info("Mapping complete")
232                return True
233            else:
234                raise service_error(service_error.internal,
235                        "Cannot get node mapping of segment:%s/%s" % (pid, eid))
236
Note: See TracBrowser for help on using the repository browser.