Adding CCN RMs for Linux backend
[nepi.git] / src / nepi / resources / linux / ccn / ccnr.py
1 #
2 #    NEPI, a framework to manage network experiments
3 #    Copyright (C) 2013 INRIA
4 #
5 #    This program is free software: you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License as published by
7 #    the Free Software Foundation, either version 3 of the License, or
8 #    (at your option) any later version.
9 #
10 #    This program is distributed in the hope that it will be useful,
11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #    GNU General Public License for more details.
14 #
15 #    You should have received a copy of the GNU General Public License
16 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19
20 from nepi.execution.attribute import Attribute, Flags, Types
21 from nepi.execution.trace import Trace, TraceAttr
22 from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
23     ResourceAction
24 from nepi.resources.linux.application import LinuxApplication
25 from nepi.resources.linux.ccn.ccnd import LinuxCCND
26 from nepi.resources.linux.node import OSType
27
28 from nepi.util.sshfuncs import ProcStatus
29 from nepi.util.timefuncs import strfnow, strfdiff
30 import os
31
32 reschedule_delay = "0.5s"
33
34 @clsinit_copy
35 class LinuxCCNR(LinuxApplication):
36     _rtype = "LinuxCCNR"
37
38     @classmethod
39     def _register_attributes(cls):
40         max_fanout = Attribute("maxFanout",
41             "Sets the CCNR_BTREE_MAX_FANOUT environmental variable. ",
42             flags = Flags.ExecReadOnly)
43
44         max_leaf_entries = Attribute("maxLeafEntries",
45             "Sets the CCNR_BTREE_MAX_LEAF_ENTRIES environmental variable. ",
46             flags = Flags.ExecReadOnly)
47
48         max_node_bytes = Attribute("maxNodeBytes",
49             "Sets the CCNR_BTREE_MAX_NODE_BYTES environmental variable. ",
50             flags = Flags.ExecReadOnly)
51
52         max_node_pool = Attribute("maxNodePool",
53             "Sets the CCNR_BTREE_MAX_NODE_POOL environmental variable. ",
54             flags = Flags.ExecReadOnly)
55
56         content_cache = Attribute("contentCache",
57             "Sets the CCNR_CONTENT_CACHE environmental variable. ",
58             flags = Flags.ExecReadOnly)
59
60         debug = Attribute("debug",
61             "Sets the CCNR_DEBUG environmental variable. "
62             "Logging level for ccnr. Defaults to WARNING.",
63             type = Types.Enumerate,
64             allowed = [
65                     "NONE",
66                     "SEVERE",
67                     "ERROR",
68                     "WARNING",
69                     "INFO",
70                     "FINE, FINER, FINEST"],
71             flags = Flags.ExecReadOnly)
72
73         directory = Attribute("directory",
74             "Sets the CCNR_DIRECTORY environmental variable. ",
75             flags = Flags.ExecReadOnly)
76
77         global_prefix = Attribute("globalPrefix",
78             "Sets the CCNR_GLOBAL_PREFIX environmental variable. ",
79             flags = Flags.ExecReadOnly)
80
81         listen_on = Attribute("listenOn",
82             "Sets the CCNR_LISTEN_ON environmental variable. ",
83             flags = Flags.ExecReadOnly)
84
85         min_send_bufsize = Attribute("minSendBufsize",
86             "Sets the CCNR_MIN_SEND_BUFSIZE environmental variable. ",
87             flags = Flags.ExecReadOnly)
88
89         proto = Attribute("proto",
90             "Sets the CCNR_PROTO environmental variable. ",
91             flags = Flags.ExecReadOnly)
92
93         status_port = Attribute("statusPort",
94             "Sets the CCNR_STATUS_PORT environmental variable. ",
95             flags = Flags.ExecReadOnly)
96
97         start_write_scope_limit = Attribute("startWriteScopeLimit",
98             "Sets the CCNR_START_WRITE_SCOPE_LIMIT environmental variable. ",
99             flags = Flags.ExecReadOnly)
100
101         ccns_debug = Attribute("ccnsDebug",
102             "Sets the CCNS_DEBUG environmental variable. ",
103             flags = Flags.ExecReadOnly)
104
105         ccns_enable = Attribute("ccnsEnable",
106             "Sets the CCNS_ENABLE environmental variable. ",
107             flags = Flags.ExecReadOnly)
108
109         ccns_faux_error = Attribute("ccnsFauxError",
110             "Sets the CCNS_FAUX_ERROR environmental variable. ",
111             flags = Flags.ExecReadOnly)
112
113         ccns_heartbeat_micros = Attribute("ccnsHeartBeatMicros",
114             "Sets the CCNS_HEART_BEAT_MICROS environmental variable. ",
115             flags = Flags.ExecReadOnly)
116
117         ccns_max_compares_busy = Attribute("ccnsMaxComparesBusy",
118             "Sets the CCNS_MAX_COMPARES_BUSY environmental variable. ",
119             flags = Flags.ExecReadOnly)
120
121         ccns_max_fetch_busy = Attribute("ccnsMaxFetchBusy",
122             "Sets the CCNS_MAX_FETCH_BUSY environmental variable. ",
123             flags = Flags.ExecReadOnly)
124
125         ccns_node_fetch_lifetime = Attribute("ccnsNodeFetchLifetime",
126             "Sets the CCNS_NODE_FETCH_LIFETIME environmental variable. ",
127             flags = Flags.ExecReadOnly)
128
129         ccns_note_err = Attribute("ccnsNoteErr",
130             "Sets the CCNS_NOTE_ERR environmental variable. ",
131             flags = Flags.ExecReadOnly)
132
133         ccns_repo_store = Attribute("ccnsRepoStore",
134             "Sets the CCNS_REPO_STORE environmental variable. ",
135             flags = Flags.ExecReadOnly)
136
137         ccns_root_advise_fresh = Attribute("ccnsRootAdviseFresh",
138             "Sets the CCNS_ROOT_ADVISE_FRESH environmental variable. ",
139             flags = Flags.ExecReadOnly)
140
141         ccns_root_advise_lifetime = Attribute("ccnsRootAdviseLifetime",
142             "Sets the CCNS_ROOT_ADVISE_LIFETIME environmental variable. ",
143             flags = Flags.ExecReadOnly)
144
145         ccns_stable_enabled = Attribute("ccnsStableEnabled",
146             "Sets the CCNS_STABLE_ENABLED environmental variable. ",
147             flags = Flags.ExecReadOnly)
148
149         ccns_sync_scope = Attribute("ccnsSyncScope",
150             "Sets the CCNS_SYNC_SCOPE environmental variable. ",
151             flags = Flags.ExecReadOnly)
152
153         cls._register_attribute(max_fanout)
154         cls._register_attribute(max_leaf_entries)
155         cls._register_attribute(max_node_bytes)
156         cls._register_attribute(max_node_pool)
157         cls._register_attribute(content_cache)
158         cls._register_attribute(debug)
159         cls._register_attribute(directory)
160         cls._register_attribute(global_prefix)
161         cls._register_attribute(listen_on)
162         cls._register_attribute(min_send_bufsize)
163         cls._register_attribute(proto)
164         cls._register_attribute(status_port)
165         cls._register_attribute(start_write_scope_limit)
166         cls._register_attribute(ccns_debug)
167         cls._register_attribute(ccns_enable)
168         cls._register_attribute(ccns_faux_error)
169         cls._register_attribute(ccns_heartbeat_micros)
170         cls._register_attribute(ccns_max_compares_busy)
171         cls._register_attribute(ccns_max_fetch_busy)
172         cls._register_attribute(ccns_node_fetch_lifetime)
173         cls._register_attribute(ccns_note_err)
174         cls._register_attribute(ccns_repo_store)
175         cls._register_attribute(ccns_root_advise_fresh)
176         cls._register_attribute(ccns_root_advise_lifetime)
177         cls._register_attribute(ccns_stable_enabled)
178         cls._register_attribute(ccns_sync_scope)
179
180     @classmethod
181     def _register_traces(cls):
182         log = Trace("log", "CCND log output")
183
184         cls._register_trace(log)
185
186     def __init__(self, ec, guid):
187         super(LinuxCCNR, self).__init__(ec, guid)
188         # Marks whether ccnr is running
189         self._running = False
190
191     @property
192     def ccnd(self):
193         ccnd = self.get_connected(LinuxCCND.rtype())
194         if ccnd: return ccnd[0]
195         return None
196
197     def deploy(self):
198         if not self.get("command"):
199             self.set("command", self._default_command)
200         
201         if not self.get("env"):
202             self.set("env", self._default_environment)
203
204         # Wait until associated ccnd is provisioned
205         ccnd = self.ccnd
206
207         if not ccnd or ccnd.state < ResourceState.READY:
208             # ccnr needs to wait until ccnd is deployed and running
209             self.ec.schedule(reschedule_delay, self.deploy)
210         else:
211             # Invoke the actual deployment
212             super(LinuxCCNR, self).deploy()
213
214             # As soon as the ccnd sources are deployed, we launch the
215             # daemon ( we don't want to lose time launching the ccn 
216             # daemon later on )
217             if self._state == ResourceState.READY:
218                 self._start_in_background()
219                 self._running = True
220
221     def start(self):
222         # CCND should already be started by now.
223         # Nothing to do but to set the state to STARTED
224         if self._running:
225             self._start_time = strfnow()
226             self._state = ResourceState.STARTED
227         else:
228             msg = " Failed to execute command '%s'" % command
229             self.error(msg, out, err)
230             self._state = ResourceState.FAILED
231             raise RuntimeError, msg
232
233     @property
234     def state(self):
235         state = super(LinuxCCNR, self).state()
236         if self._state in [ResourceState.TERMINATED, ResourceState.FAILED]:
237             self._running = False
238
239         if self._state == ResourceState.READY:
240             # CCND is really deployed only when ccn daemon is running 
241             if not self._running:
242                 return ResourceState.PROVISIONED
243  
244         return self._state
245
246     @property
247     def _default_command(self):
248         return "ccnr"
249
250     @property
251     def _default_environment(self):
252         envs = dict({
253             "maxFanout": "CCNR_BTREE_MAX_FANOUT",
254             "maxLeafEntries": "CCNR_BTREE_MAX_LEAF_ENTRIES",
255             "maxNodeBytes": "CCNR_BTREE_MAX_NODE_BYTES",
256             "maxNodePool": "CCNR_BTREE_MAX_NODE_POOL",
257             "contentCache": "CCNR_CONTENT_CACHE",
258             "debug": "CCNR_DEBUG",
259             "directory": "CCNR_DIRECTORY",
260             "globalPrefix": "CCNR_GLOBAL_PREFIX",
261             "listenOn": "CCNR_LISTEN_ON",
262             "minSendBufsize": "CCNR_MIN_SEND_BUFSIZE",
263             "proto": "CCNR_PROTO",
264             "statusPort": "CCNR_STATUS_PORT",
265             "startWriteScopeLimit": "CCNR_START_WRITE_SCOPE_LIMIT",
266             "ccnsDebug": "CCNS_DEBUG",
267             "ccnsEnable": "CCNS_ENABLE",
268             "ccnsFauxError": "CCNS_FAUX_ERROR",
269             "ccnsHeartBeatMicros": "CCNS_HEART_BEAT_MICROS",
270             "ccnsMaxComparesBusy": "CCNS_MAX_COMPARES_BUSY",
271             "ccnsMaxFetchBusy": "CCNS_MAX_FETCH_BUSY",
272             "ccnsNodeFetchLifetime": "CCNS_NODE_FETCH_LIFETIME",
273             "ccnsNoteErr": "CCNS_NOTE_ERR",
274             "ccnsRepoStore": "CCNS_REPO_STORE",
275             "ccnsRootAdviseFresh": "CCNS_ROOT_ADVISE_FRESH",
276             "ccnsRootAdviseLifetime": "CCNS_ROOT_ADVISE_LIFETIME",
277             "ccnsStableEnabled": "CCNS_STABLE_ENABLED",
278             "ccnsSyncScope": "CCNS_SYNC_SCOPE",
279             })
280
281         env = "PATH=$PATH:${EXP_HOME}/ccnx/bin "
282         env += " ".join(map(lambda k: "%s=%s" % (envs.get(k), self.get(k)) \
283             if self.get(k) else "", envs.keys()))
284         
285         return env            
286         
287     def valid_connection(self, guid):
288         # TODO: Validate!
289         return True
290