source: fedd/federation/emulab_segment.py @ 3f5e375

compt_changesinfo-ops
Last change on this file since 3f5e375 was 3f5e375, checked in by Ted Faber <faber@…>, 13 years ago

Error handling

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[181aeb4]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, 
[3f5e375]47                    "Cannot connect" % e)
[181aeb4]48            raise e
49        except BIOError, e:
50            if self.log:
[3f5e375]51                self.log.warn("BIO error: %s" % e)
[181aeb4]52            raise e
53        except sslerror, e:
54            if self.log:
[3f5e375]55                self.log.warn("SSL (socket) error: %s" %  e)
[181aeb4]56            raise e
57        except SSLError, e:
58            if self.log:
[3f5e375]59                self.log.warn("SSL error: %s" % e)
[181aeb4]60            raise e
61        except httplib.HTTPException, e:
62            if self.log:
[3f5e375]63                self.log.warn("HTTP error: %s" % e)
[181aeb4]64            raise e
65        except Fault, f:
[3f5e375]66            raise service_error(service_error.protocol, 
67                    "Remote XMLRPC Fault: %s" % f)
[181aeb4]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):
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:
[c53ca69]104                self.log.debug("[make_null_experiment]: (debug) Creating experiment")
[181aeb4]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 self.log:
[c53ca69]118                self.log.info("[make_null_experiment]: Creating experiment")
[725c55d]119            print params
[181aeb4]120            code, value = self.emulab_call('experiment.startexp', params)
121
122            if self.log:
123                if code == 0: 
124                    self.log.info('[make_null_experiment]: Create succeeded')
125                else: 
126                    self.log.error('[make_null_experiment]: Create failed: %s' \
127                            % value)
128
129            return code == 0
130
131    def swap_exp(self, pid, eid, direction='out', wait=True):
132        """
133        Swap experiment in.
134        """
135        if self.debug:
136            if self.log:
137                self.log.info("[swap_exp]: (debug) Swapping %s %s" % \
138                        (eid, direction))
139            return True
140        else:
141            if self.log:
142                self.log.info("[swap_exp]: Swapping %s %s" % (eid, direction))
143            params = {
144                    'proj': pid,
145                    'exp': eid,
146                    'direction': direction,
147                    'wait': wait,
148                    }
149            code, value = self.emulab_call('experiment.swapexp', params)
150
151            if self.log:
152                if code == 0: self.log.info('[swap_exp]: Swap succeeded')
153                else: self.log.error('[swap_exp]: Swap failed: %s' % value)
154
155        return code == 0
156
157    def modify_exp(self, pid, eid, tcl, wait=True):
158        if self.debug:
159            self.log.info("[modify_exp]: (debug) Modifying %s" % eid)
160            return True
161        else:
162            self.log.info("[modify_exp]: Modifying %s" % eid)
163            params = {
164                    'proj': pid,
165                    'exp': eid,
166                    'nsfilestr': tcl,
167                    'wait': wait,
168                    'reboot': True,
169                    'restart_eventsys': True,
170                    }
171            code, value = self.emulab_call('experiment.modify', params)
172            if self.log:
173                if code == 0: 
174                    self.log.info('[modify_exp]: Modify succeeded')
175                else: 
176                    self.log.error('[modify_exp]: Modify failed: %s' \
177                            % value)
178            return code == 0
179
180
181    def get_mapping(self, pid, eid):
182        """
183        Get the physical to virtual mapping from the expinfo command and save
184        it in the self.map member.
185        """
186
187        if self.debug:
188            if self.log:
189                self.log.info("[get_mapping] (debug) Generating mapping")
190                return True
191        else:
192            if self.log:
193                self.log.info("[get_mapping] Generating mapping")
194
195            params = {
196                    'proj': pid,
197                    'exp': eid,
198                    'aspect': 'mapping'
199                    }
200            code, nodes = self.emulab_call('experiment.info', params)
201            if code ==0:
202                for k, v in nodes.items():
203                    if v.get('erole', False) and 'pnode' in v:
204                        self.node[k] = v['pnode']
205                if self.log:
206                    self.log.info("Mapping complete")
207                return True
208            else:
209                raise service_error(service_error.internal,
210                        "Cannot get node mapping of segment:%s/%s" % (pid, eid))
211
Note: See TracBrowser for help on using the repository browser.