source: fedd/federation/emulab_segment.py @ 22a1a77

compt_changesinfo-ops
Last change on this file since 22a1a77 was 6e33086, checked in by Ted Faber <faber@…>, 12 years ago

InfoSegment? to emulab access controllers

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