blob: 9569395ea3bf5d972d114fb96004cb9d444d1aed [file] [log] [blame]
Steve McIntyre844bfd42014-11-27 16:58:31 +00001#! /usr/bin/python
2
3# Copyright 2014 Linaro Limited
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 2 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, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18# MA 02110-1301, USA.
19#
20# VLANd admin interface
21#
22
23import os, sys, types
24import time
25import logging
26import optparse
27
28vlandpath = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
29sys.path.insert(0, vlandpath)
30
31import drivers
Steve McIntyre21f02702014-12-16 18:19:47 +000032from errors import CriticalError, InputError, ConfigError, SocketError
Steve McIntyre844bfd42014-11-27 16:58:31 +000033from db.db import VlanDB
Steve McIntyre21f02702014-12-16 18:19:47 +000034from config.config import VlanConfig
35from ipc.ipc import VlanIpc
Steve McIntyre844bfd42014-11-27 16:58:31 +000036
37version = "0.0.0-DEV"
38banner = "Linaro VLANd admin interface, version %s" % version
39
Steve McIntyreae95fd62014-12-05 16:51:41 +000040def is_positive(text):
41 if text in ('1', 'y', 'Y', 't', 'T', 'True'):
42 return True
43 elif text in ('0', 'n', 'N', 'f', 'F', 'False'):
44 return False
45 else:
46 raise InputError("Cannot parse \"%s\" as True or False" % text)
47
Steve McIntyrea132c362014-12-05 15:53:21 +000048def dump_switch(switch):
49 print switch
50
Steve McIntyre11e4cbd2014-12-05 16:03:03 +000051def dump_port(port):
52 print port
53
Steve McIntyree41e3f32014-12-05 18:08:21 +000054def dump_vlan(vlan):
55 print vlan
56
Steve McIntyref1c04f92014-12-16 18:23:15 +000057def call_vland(msgtype, msg):
58 ipc = VlanIpc()
59 ipc.client_connect('localhost', config.vland.port)
60 msg['client_name'] = 'admin.py'
61 msg['type'] = msgtype
62# print 'Sending:'
63# print msg
64 ipc.client_send(msg)
65 ret = ipc.client_recv_and_close()
66 if 'response' not in ret:
67 raise SocketError("Badly-formed response from VLANd server")
68 if ret['response'] == "ERROR":
69 raise InputError("VLANd server said: %s" % ret['error'])
70# print 'VLANd said in reply:'
71# print ret
72 return ret['data']
73
Steve McIntyre844bfd42014-11-27 16:58:31 +000074#print '%s' % banner
75
Steve McIntyrec12f6312014-12-15 15:00:12 +000076config = VlanConfig(filenames=('./vland.cfg',))
Steve McIntyrec12f6312014-12-15 15:00:12 +000077
Steve McIntyre844bfd42014-11-27 16:58:31 +000078#print 'Connecting to DB...'
79db = VlanDB()
80
Steve McIntyrec12f6312014-12-15 15:00:12 +000081# We need to know the vlan_id for the default vlan (tag 1). Make sure
82# we know that before anybody attempts to create things that depend on
83# it.
84default_vlan_id = db.get_vlan_id_by_tag(config.vland.default_vlan_tag)
Steve McIntyrec99e93b2014-12-02 18:21:33 +000085if default_vlan_id is None:
Steve McIntyrec12f6312014-12-15 15:00:12 +000086 raise ConfigError("No vlan ID found for default VLAN tag %d" % config.vland.default_vlan_tag)
Steve McIntyre4b0193d2014-11-28 18:06:12 +000087
Steve McIntyre844bfd42014-11-27 16:58:31 +000088usage = 'Usage: %prog --command [command options]'
Steve McIntyre844bfd42014-11-27 16:58:31 +000089parser = optparse.OptionParser(usage=usage, description=banner)
90
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +000091# System commands
92system_group = optparse.OptionGroup(parser, "System commands")
93system_group.add_option("--status",
94 dest="status",
95 action = "store_true",
96 default = False,
97 help = "Describe current system status")
98parser.add_option_group(system_group)
99# May add shutdown, self-check etc. later
100
Steve McIntyre844bfd42014-11-27 16:58:31 +0000101# Switch commands
102switch_group = optparse.OptionGroup(parser, "Switch commands")
103switch_group.add_option("--list_all_switches",
104 dest = "list_all_switches",
105 action = "store_true",
106 default = False,
107 help = "List all the existing switches in the system")
108switch_group.add_option("--create_switch",
109 dest = "create_switch",
110 action = "store",
111 type = "string",
112 help = "Add a new switch to the system",
113 nargs = 1,
114 metavar = "<name>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000115switch_group.add_option("--delete_switch",
116 dest = "delete_switch",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000117 action = "store",
118 type = "int",
119 help = "Remove an existing switch from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000120 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000121 nargs = 1,
122 metavar = "<switch_id>")
123switch_group.add_option("--show_switch",
124 dest = "show_switch",
125 action = "store",
126 type = "int",
127 help = "Show the details of an existing switch in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000128 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000129 nargs = 1,
130 metavar = "<switch_id>")
131switch_group.add_option("--lookup_switch_by_name",
132 dest = "lookup_switch_by_name",
133 action = "store",
134 type = "string",
135 help = "Lookup a switch ID by name",
136 nargs = 1,
137 metavar = "<name>")
138switch_group.add_option("--list_switch_ports",
139 dest = "list_switch_ports",
140 action = "store",
141 type = "int",
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000142 help = "List the IDs of the ports on an existing switch in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000143 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000144 nargs = 1,
145 metavar = "<switch_id>")
146parser.add_option_group(switch_group)
147
148# Port commands
149port_group = optparse.OptionGroup(parser, "Port commands")
150port_group.add_option("--list_all_ports",
151 dest = "list_all_ports",
152 action = "store_true",
153 default = False,
154 help = "List all the existing ports in the system")
155port_group.add_option("--create_port",
156 dest = "create_port",
157 action = "store",
158 type = "string",
159 help = "Add a new port to the system",
160 nargs = 2,
161 metavar = "<switch_id> <name>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000162port_group.add_option("--delete_port",
163 dest = "delete_port",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000164 action = "store",
165 type = "int",
166 help = "Remove an existing port from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000167 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000168 nargs = 1,
169 metavar = "<port_id>")
170port_group.add_option("--show_port",
171 dest = "show_port",
172 action = "store",
173 type = "int",
174 help = "Show the details of an existing port in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000175 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000176 nargs = 1,
177 metavar = "<port_id>")
178port_group.add_option("--lookup_port_by_switch_and_name",
179 dest = "lookup_port_by_switch_and_name",
180 action = "store",
181 type = "string",
182 help = "Lookup a port ID by switch and port name",
183 nargs = 2,
184 metavar = "<switch_id> <name>")
Steve McIntyre71b41022014-12-05 17:17:44 +0000185port_group.add_option("--set_port_mode",
186 dest = "set_port_mode",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000187 action = "store",
188 type = "string",
189 help = "Set the mode of a port to 'trunk' or 'access'",
190 nargs = 2,
191 metavar = "<port_id> <mode>")
192port_group.add_option("--lock_port",
193 dest = "lock_port",
194 action = "store",
195 type = "string",
196 help = "Lock the settings on a port",
197 nargs = 1,
198 metavar = "<port_id>")
199port_group.add_option("--unlock_port",
200 dest = "unlock_port",
201 action = "store",
202 type = "string",
203 help = "Unock the settings on a port",
204 nargs = 1,
205 metavar = "<port_id>")
206port_group.add_option("--set_port_current_vlan",
207 dest = "set_port_current_vlan",
208 action = "store",
209 type = "int",
210 help = "Set the current VLAN assignment for a port",
211 nargs = 2,
212 metavar = "<port_id> <vlan_id>")
213port_group.add_option("--get_port_current_vlan",
214 dest = "get_port_current_vlan",
215 action = "store",
216 type = "int",
217 help = "Get the current VLAN assignment for a port",
218 nargs = 1,
219 metavar = "<port_id>")
220port_group.add_option("--set_port_base_vlan",
221 dest = "set_port_base_vlan",
222 action = "store",
223 type = "int",
224 help = "Set the base VLAN assignment for a port",
225 nargs = 2,
226 metavar = "<port_id> <vlan_id>")
227port_group.add_option("--get_port_base_vlan",
228 dest = "get_port_base_vlan",
229 action = "store",
230 type = "int",
231 help = "Get the base VLAN assignment for a port",
232 nargs = 1,
233 metavar = "<port_id>")
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000234port_group.add_option("--restore_port_to_base_vlan",
235 dest = "restore_port_to_base_vlan",
236 action = "store",
237 type = "int",
238 help = "Reset the port back to its base VLAN",
239 nargs = 1,
240 metavar = "<port_id>")
Steve McIntyre844bfd42014-11-27 16:58:31 +0000241parser.add_option_group(port_group)
242
243# VLAN commands
244vlan_group = optparse.OptionGroup(parser, "VLAN commands")
245vlan_group.add_option("--list_all_vlans",
246 dest = "list_all_vlans",
247 action = "store_true",
248 default = False,
249 help = "List all the existing vlans in the system")
250vlan_group.add_option("--create_vlan",
251 dest = "create_vlan",
252 action = "store",
253 type = "string",
254 help = "Add a new vlan to the system",
255 nargs = 3,
Steve McIntyre9f0bb602014-11-28 14:36:39 +0000256 metavar = "<name> <tag> <is_base_vlan>")
Steve McIntyre99feaee2014-12-02 18:22:36 +0000257vlan_group.add_option("--delete_vlan",
258 dest = "delete_vlan",
Steve McIntyre844bfd42014-11-27 16:58:31 +0000259 action = "store",
260 type = "int",
261 help = "Remove an existing vlan from the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000262 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000263 nargs = 1,
264 metavar = "<vlan_id>")
265vlan_group.add_option("--show_vlan",
266 dest = "show_vlan",
267 action = "store",
268 type = "int",
269 help = "Show the details of an existing vlan in the system",
Steve McIntyre59e04632014-12-02 18:02:16 +0000270 default = None,
Steve McIntyre844bfd42014-11-27 16:58:31 +0000271 nargs = 1,
272 metavar = "<vlan_id>")
273parser.add_option_group(vlan_group)
274
275(opts, args) = parser.parse_args()
276
Steve McIntyre844bfd42014-11-27 16:58:31 +0000277if opts.list_all_switches:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000278 result = call_vland('query', {'command':'db.all_switches', 'data':None})
Steve McIntyre844bfd42014-11-27 16:58:31 +0000279 count = 0;
280 for line in result:
281 print line
282 count += 1
283 print '%d entries' % count
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000284elif opts.list_all_ports:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000285 result = call_vland('query', {'command':'db.all_ports', 'data':None})
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000286 count = 0;
287 for line in result:
288 print line
289 count += 1
290 print '%d entries' % count
291elif opts.list_all_vlans:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000292 result = call_vland('query', {'command':'db.all_vlans', 'data':None})
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000293 count = 0;
294 for line in result:
295 print line
296 count += 1
297 print '%d entries' % count
Steve McIntyre844bfd42014-11-27 16:58:31 +0000298elif opts.create_switch is not None:
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000299 try:
300 switch_id = db.create_switch(opts.create_switch)
301 print 'Created switch_id %d' % switch_id
302 except InputError as inst:
303 print 'Failed: %s' % inst
Steve McIntyre844bfd42014-11-27 16:58:31 +0000304elif opts.create_port is not None:
Steve McIntyreaf2d5ed2014-12-02 12:42:28 +0000305 try:
306 port_id = db.create_port(opts.create_port[0],
307 opts.create_port[1],
308 default_vlan_id, default_vlan_id)
309 print 'Created port_id %d' % port_id
310 except InputError as inst:
311 print 'Failed: %s' % inst
Steve McIntyrec21d8d12014-11-28 14:42:40 +0000312elif opts.create_vlan is not None:
Steve McIntyrec8aba4c2014-12-02 12:48:51 +0000313 try:
314 vlan_id = db.create_vlan(opts.create_vlan[0],
315 opts.create_vlan[1],
Steve McIntyreae95fd62014-12-05 16:51:41 +0000316 is_positive(opts.create_vlan[2]))
Steve McIntyrec8aba4c2014-12-02 12:48:51 +0000317 print 'Created vlan_id %d' % vlan_id
318 except InputError as inst:
319 print 'Failed: %s' % inst
Steve McIntyre99feaee2014-12-02 18:22:36 +0000320elif opts.delete_switch is not None:
Steve McIntyre64e38862014-12-02 17:19:37 +0000321 try:
Steve McIntyre99feaee2014-12-02 18:22:36 +0000322 switch_id = db.delete_switch(opts.delete_switch)
Steve McIntyre64e38862014-12-02 17:19:37 +0000323 print 'Deleted switch_id %d' % switch_id
324 except InputError as inst:
325 print 'Failed: %s' % inst
Steve McIntyre99feaee2014-12-02 18:22:36 +0000326elif opts.delete_port is not None:
Steve McIntyre6f7ee5c2014-12-02 18:02:50 +0000327 try:
Steve McIntyre99feaee2014-12-02 18:22:36 +0000328 port_id = db.delete_port(opts.delete_port)
Steve McIntyre6f7ee5c2014-12-02 18:02:50 +0000329 print 'Deleted port_id %d' % port_id
330 except InputError as inst:
331 print 'Failed: %s' % inst
Steve McIntyreed5cbea2014-12-02 18:23:00 +0000332elif opts.delete_vlan is not None:
333 try:
334 vlan_id = db.delete_vlan(opts.delete_vlan)
335 print 'Deleted vlan_id %d' % vlan_id
336 except InputError as inst:
337 print 'Failed: %s' % inst
Steve McIntyre8e839a62014-12-05 15:46:05 +0000338elif opts.lookup_switch_by_name is not None:
339 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000340 switch_id = call_vland('query', {'command':'db.get_switch_id_by_name', 'data':{'name':opts.lookup_switch_by_name}})
Steve McIntyre8e839a62014-12-05 15:46:05 +0000341 if switch_id is not None:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000342 print '%d' % switch_id
Steve McIntyre8e839a62014-12-05 15:46:05 +0000343 else:
344 print 'No switch found for name %s' % opts.lookup_switch_by_name
345 except InputError as inst:
346 print 'Failed: %s' % inst
Steve McIntyrea132c362014-12-05 15:53:21 +0000347elif opts.show_switch is not None:
348 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000349 switch = call_vland('query',
350 {'command':'db.get_switch_by_id',
351 'data':{'switch_id': opts.show_switch}})
Steve McIntyrea132c362014-12-05 15:53:21 +0000352 if switch is not None:
353 dump_switch(switch)
354 else:
355 print 'No switch found for switch_id %d' % opts.show_switch
356 except InputError as inst:
357 print 'Failed: %s' % inst
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000358elif opts.list_switch_ports is not None:
359 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000360 ports = call_vland('query',
361 {'command':'db.get_ports_by_switch',
362 'data':{'switch_id': opts.list_switch_ports}})
Steve McIntyre11e4cbd2014-12-05 16:03:03 +0000363 if ports is not None:
364 for port in ports:
365 dump_port(port)
366 else:
367 print 'No ports found for switch_id %d' % opts.list_switch_ports
368 except InputError as inst:
369 print 'Failed: %s' % inst
Steve McIntyre08dd8392014-12-05 16:07:20 +0000370elif opts.show_port is not None:
371 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000372 port = call_vland('query',
373 {'command':'db.get_port_by_id',
374 'data':{'port_id': opts.show_port}})
Steve McIntyre08dd8392014-12-05 16:07:20 +0000375 if port is not None:
376 dump_port(port)
377 else:
378 print 'No port found for port_id %d' % opts.show_port
379 except InputError as inst:
380 print 'Failed: %s' % inst
Steve McIntyre73106572014-12-05 16:13:36 +0000381elif opts.lookup_port_by_switch_and_name is not None:
382 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000383 port = call_vland('query',
384 {'command':'db.get_port_by_switch_and_name',
385 'data':
386 {'switch_id': opts.lookup_port_by_switch_and_name[0],
387 'name': opts.lookup_port_by_switch_and_name[1]}})
Steve McIntyre73106572014-12-05 16:13:36 +0000388 if port is not None:
389 print port
390 else:
391 print 'No port found for switch_id %d, name %s' % (int(opts.lookup_port_by_switch_and_name[0]), opts.lookup_port_by_switch_and_name[1])
392 except InputError as inst:
393 print 'Failed: %s' % inst
Steve McIntyre71b41022014-12-05 17:17:44 +0000394elif opts.set_port_mode is not None:
395 try:
396 port_id = db.set_port_mode(opts.set_port_mode[0], opts.set_port_mode[1])
397 print "Updated mode for port_id %d" % port_id
398 except InputError as inst:
399 print 'Failed: %s' % inst
Steve McIntyre75dc4ec2014-12-05 17:20:42 +0000400elif opts.lock_port is not None:
401 try:
402 port_id = db.set_port_is_locked(opts.lock_port, True)
403 print "Locked port_id %d" % port_id
404 except InputError as inst:
405 print 'Failed: %s' % inst
406elif opts.unlock_port is not None:
407 try:
408 port_id = db.set_port_is_locked(opts.unlock_port, False)
409 print "Unlocked port_id %d" % port_id
410 except InputError as inst:
411 print 'Failed: %s' % inst
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000412elif opts.set_port_current_vlan is not None:
413 try:
414 port_id = db.set_current_vlan(opts.set_port_current_vlan[0], opts.set_port_current_vlan[1])
415 print "Set current VLAN on port_id %d" % port_id
416 except InputError as inst:
417 print 'Failed: %s' % inst
418elif opts.get_port_current_vlan is not None:
419 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000420 vlan_id = call_vland('query',
421 {'command':'db.get_current_vlan_id_by_port',
422 'data':{'port_id': opts.get_port_current_vlan}})
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000423 if vlan_id is not None:
424 print vlan_id
425 else:
426 print "No current_vlan_id found for port_id %d" % opts.get_port_current_vlan
427 except InputError as inst:
428 print 'Failed: %s' % inst
429elif opts.set_port_base_vlan is not None:
430 try:
431 port_id = db.set_base_vlan(opts.set_port_base_vlan[0], opts.set_port_base_vlan[1])
432 print "Set base VLAN on port_id %d" % port_id
433 except InputError as inst:
434 print 'Failed: %s' % inst
435elif opts.get_port_base_vlan is not None:
436 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000437 vlan_id = call_vland('query',
438 {'command':'db.get_base_vlan_id_by_port',
439 'data':{'port_id': opts.get_port_base_vlan}})
Steve McIntyrea2bbcda2014-12-05 17:57:36 +0000440 if vlan_id is not None:
441 print vlan_id
442 else:
443 print "No base_vlan_id found for port_id %d" % port_id
444 except InputError as inst:
445 print 'Failed: %s' % inst
446elif opts.restore_port_to_base_vlan is not None:
447 try:
448 port_id = db.restore_base_vlan(opts.restore_port_to_base_vlan)
449 print "Restored port_id %d back to base VLAN" % port_id
450 except InputError as inst:
451 print 'Failed: %s' % inst
Steve McIntyree41e3f32014-12-05 18:08:21 +0000452elif opts.show_vlan is not None:
453 try:
Steve McIntyref1c04f92014-12-16 18:23:15 +0000454 vlan = call_vland('query',
455 {'command':'db.get_vlan_by_id',
456 'data':{'vlan_id': opts.show_vlan}})
Steve McIntyree41e3f32014-12-05 18:08:21 +0000457 if vlan is not None:
458 dump_vlan(vlan)
459 else:
460 print 'No vlan found for vlan_id %d' % opts.show_vlan
461 except InputError as inst:
462 print 'Failed: %s' % inst
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000463elif opts.status:
464 print banner
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000465 print 'Config:'
466 print ' knows about %d switch(es)' % len(config.switches)
467 print 'DB:'
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000468 switches = db.all_switches()
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000469 print ' knows about %d switch(es)' % len(switches)
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000470 ports = db.all_ports()
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000471 print ' knows about %d port(s)' % len(ports)
Steve McIntyre9cd6c3d2014-12-05 18:10:35 +0000472 vlans = db.all_vlans()
Steve McIntyrebb718cf2014-12-15 16:57:25 +0000473 print ' DB knows about %d vlan(s)' % len(vlans)
Steve McIntyre0abacac2014-12-15 16:51:38 +0000474 print 'The default vlan tag (%d) is vlan_id %d' % (config.vland.default_vlan_tag, default_vlan_id)
Steve McIntyref1c04f92014-12-16 18:23:15 +0000475 ret = call_vland('query', {'command':'status', 'data': None})
476 print 'VLANd is running %s' % ret['running']
477 print 'DB via VLANd:'
478 switches = call_vland('query', {'command':'db.all_switches', 'data':None})
479 print ' knows about %d switch(es)' % len(switches)
480 ports = call_vland('query', {'command':'db.all_ports', 'data':None})
481 print ' knows about %d port(s)' % len(ports)
482 vlans = call_vland('query', {'command':'db.all_vlans', 'data':None})
483 print ' DB knows about %d vlan(s)' % len(vlans)
Steve McIntyrea0534a52014-12-05 17:58:40 +0000484else:
Steve McIntyre4a808912014-12-05 15:24:39 +0000485 print 'No recognised command given. Try -h for help'