source: fedd/Makefile/federation/emulab_segment.py @ 88e7f2f

version-3.01version-3.02
Last change on this file since 88e7f2f was 88e7f2f, checked in by Ted Faber <faber@…>, 14 years ago

version bump

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