4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
30 from rift
.rwlib
.util
import certs
31 import rift
.rwcal
.cloudsim
32 import rift
.rwcal
.cloudsim
.net
34 import rift
.vcs
.core
as core
38 import rift
.rwcal
.cloudsim
39 import rift
.rwcal
.cloudsim
.net
41 from rift
.vcs
.ext
import ClassProperty
43 logger
= logging
.getLogger(__name__
)
46 class NsmTasklet(rift
.vcs
.core
.Tasklet
):
48 This class represents a network services manager tasklet.
51 def __init__(self
, name
='network-services-manager', uid
=None,
53 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
54 data_storetype
=core
.DataStore
.NOSTORE
.value
,
57 Creates a NsmTasklet object.
60 name - the name of the tasklet
61 uid - a unique identifier
63 super(NsmTasklet
, self
).__init
__(name
=name
, uid
=uid
,
64 config_ready
=config_ready
,
65 recovery_action
=recovery_action
,
66 data_storetype
=data_storetype
,
69 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwnsmtasklet')
70 plugin_name
= ClassProperty('rwnsmtasklet')
73 class VnsTasklet(rift
.vcs
.core
.Tasklet
):
75 This class represents a network services manager tasklet.
78 def __init__(self
, name
='virtual-network-service', uid
=None,
80 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
81 data_storetype
=core
.DataStore
.NOSTORE
.value
,
84 Creates a VnsTasklet object.
87 name - the name of the tasklet
88 uid - a unique identifier
90 super(VnsTasklet
, self
).__init
__(name
=name
, uid
=uid
,
91 config_ready
=config_ready
,
92 recovery_action
=recovery_action
,
93 data_storetype
=data_storetype
,
96 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwvnstasklet')
97 plugin_name
= ClassProperty('rwvnstasklet')
100 class VnfmTasklet(rift
.vcs
.core
.Tasklet
):
102 This class represents a virtual network function manager tasklet.
105 def __init__(self
, name
='virtual-network-function-manager', uid
=None,
107 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
108 data_storetype
=core
.DataStore
.NOSTORE
.value
,
111 Creates a VnfmTasklet object.
114 name - the name of the tasklet
115 uid - a unique identifier
117 super(VnfmTasklet
, self
).__init
__(name
=name
, uid
=uid
,
118 config_ready
=config_ready
,
119 recovery_action
=recovery_action
,
120 data_storetype
=data_storetype
,
123 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwvnfmtasklet')
124 plugin_name
= ClassProperty('rwvnfmtasklet')
127 class ResMgrTasklet(rift
.vcs
.core
.Tasklet
):
129 This class represents a Resource Manager tasklet.
132 def __init__(self
, name
='Resource-Manager', uid
=None,
134 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
135 data_storetype
=core
.DataStore
.NOSTORE
.value
,
138 Creates a ResMgrTasklet object.
141 name - the name of the tasklet
142 uid - a unique identifier
144 super(ResMgrTasklet
, self
).__init
__(name
=name
, uid
=uid
,
145 config_ready
=config_ready
,
146 recovery_action
=recovery_action
,
147 data_storetype
=data_storetype
,
150 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwresmgrtasklet')
151 plugin_name
= ClassProperty('rwresmgrtasklet')
154 class ImageMgrTasklet(rift
.vcs
.core
.Tasklet
):
156 This class represents a Image Manager tasklet.
159 def __init__(self
, name
='Image-Manager', uid
=None,
161 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
162 data_storetype
=core
.DataStore
.NOSTORE
.value
,
165 Creates a Image Manager Tasklet object.
168 name - the name of the tasklet
169 uid - a unique identifier
171 super(ImageMgrTasklet
, self
).__init
__(
173 config_ready
=config_ready
,
174 recovery_action
=recovery_action
,
175 data_storetype
=data_storetype
,
178 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwimagemgrtasklet')
179 plugin_name
= ClassProperty('rwimagemgrtasklet')
182 class MonitorTasklet(rift
.vcs
.core
.Tasklet
):
184 This class represents a tasklet that is used to monitor NFVI metrics.
187 def __init__(self
, name
='nfvi-metrics-monitor', uid
=None,
189 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
190 data_storetype
=core
.DataStore
.NOSTORE
.value
,
193 Creates a MonitorTasklet object.
196 name - the name of the tasklet
197 uid - a unique identifier
200 super(MonitorTasklet
, self
).__init
__(name
=name
, uid
=uid
,
201 config_ready
=config_ready
,
202 recovery_action
=recovery_action
,
203 data_storetype
=data_storetype
,
206 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwmonitor')
207 plugin_name
= ClassProperty('rwmonitor')
209 class RedisServer(rift
.vcs
.NativeProcess
):
210 def __init__(self
, name
="RW.Redis.Server",
212 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
213 data_storetype
=core
.DataStore
.NOSTORE
.value
,
215 super(RedisServer
, self
).__init
__(
217 exe
="/usr/bin/redis-server",
218 config_ready
=config_ready
,
219 recovery_action
=recovery_action
,
220 data_storetype
=data_storetype
,
225 return "./usr/bin/active_redis.conf --port 9999"
228 class MonitoringParameterTasklet(rift
.vcs
.core
.Tasklet
):
230 This class represents a tasklet that is used to generate monitoring
234 def __init__(self
, name
='Monitoring-Parameter', uid
=None,
236 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
237 data_storetype
=core
.DataStore
.NOSTORE
.value
,
240 Creates a MonitoringParameterTasklet object.
243 name - the name of the tasklet
244 uid - a unique identifier
247 super(MonitoringParameterTasklet
, self
).__init
__(name
=name
, uid
=uid
,
248 config_ready
=config_ready
,
249 recovery_action
=recovery_action
,
250 data_storetype
=data_storetype
,
253 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwmonparam')
254 plugin_name
= ClassProperty('rwmonparam')
257 class AutoscalerTasklet(rift
.vcs
.core
.Tasklet
):
259 This class represents a tasklet that is used to generate monitoring
263 def __init__(self
, name
='Autoscaler', uid
=None,
265 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
266 data_storetype
=core
.DataStore
.NOSTORE
.value
,
269 Creates a MonitoringParameterTasklet object.
272 name - the name of the tasklet
273 uid - a unique identifier
276 super(AutoscalerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
277 config_ready
=config_ready
,
278 recovery_action
=recovery_action
,
279 data_storetype
=data_storetype
,
282 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwautoscaler')
283 plugin_name
= ClassProperty('rwautoscaler')
285 class StagingManagerTasklet(rift
.vcs
.core
.Tasklet
):
287 A class that provide a simple staging area for all tasklets
290 def __init__(self
, name
='StagingManager', uid
=None,
292 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
293 data_storetype
=core
.DataStore
.NOSTORE
.value
,
296 Creates a StagingMangerTasklet object.
299 name - the name of the tasklet
300 uid - a unique identifier
303 super(StagingManagerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
304 config_ready
=config_ready
,
305 recovery_action
=recovery_action
,
306 data_storetype
=data_storetype
,
309 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwstagingmgr')
310 plugin_name
= ClassProperty('rwstagingmgr')
312 def get_ui_ssl_args():
313 """Returns the SSL parameter string for launchpad UI processes"""
316 use_ssl
, certfile_path
, keyfile_path
= certs
.get_bootstrap_cert_and_key()
317 except certs
.BootstrapSslMissingException
:
318 logger
.error('No bootstrap certificates found. Disabling UI SSL')
321 # If we're not using SSL, no SSL arguments are necessary
325 return "--enable-https --keyfile-path=%s --certfile-path=%s" % (keyfile_path
, certfile_path
)
328 class UIServer(rift
.vcs
.NativeProcess
):
329 def __init__(self
, name
="RW.MC.UI",
331 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
332 data_storetype
=core
.DataStore
.NOSTORE
.value
,
334 super(UIServer
, self
).__init
__(
336 exe
="./usr/share/rw.ui/skyquake/scripts/launch_ui.sh",
337 config_ready
=config_ready
,
338 recovery_action
=recovery_action
,
339 data_storetype
=data_storetype
,
344 return get_ui_ssl_args()
346 class ConfigManagerTasklet(rift
.vcs
.core
.Tasklet
):
348 This class represents a Resource Manager tasklet.
351 def __init__(self
, name
='Configuration-Manager', uid
=None,
353 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
354 data_storetype
=core
.DataStore
.NOSTORE
.value
,
357 Creates a ConfigManagerTasklet object.
360 name - the name of the tasklet
361 uid - a unique identifier
363 super(ConfigManagerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
364 config_ready
=config_ready
,
365 recovery_action
=recovery_action
,
366 data_storetype
=data_storetype
,
369 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwconmantasklet')
370 plugin_name
= ClassProperty('rwconmantasklet')
372 class PackageManagerTasklet(rift
.vcs
.core
.Tasklet
):
374 This class represents a Resource Manager tasklet.
377 def __init__(self
, name
='Package-Manager', uid
=None,
379 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
380 data_storetype
=core
.DataStore
.NOSTORE
.value
,
383 Creates a PackageManager object.
386 name - the name of the tasklet
387 uid - a unique identifier
389 super(PackageManagerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
390 config_ready
=config_ready
,
391 recovery_action
=recovery_action
,
392 data_storetype
=data_storetype
,
395 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwpkgmgr')
396 plugin_name
= ClassProperty('rwpkgmgr')
398 class GlanceServer(rift
.vcs
.NativeProcess
):
399 def __init__(self
, name
="glance-image-catalog",
401 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
402 data_storetype
=core
.DataStore
.NOSTORE
.value
,
404 super(GlanceServer
, self
).__init
__(
406 exe
="./usr/bin/glance_start_wrapper",
407 config_ready
=config_ready
,
408 recovery_action
=recovery_action
,
409 data_storetype
=data_storetype
,
414 return "./etc/glance"
417 class Demo(rift
.vcs
.demo
.Demo
):
418 def __init__(self
, no_ui
=False, ha_mode
=None, mgmt_ip_list
=[], test_name
=None):
420 ConfigManagerTasklet(),
422 rift
.vcs
.DtsRouterTasklet(),
423 rift
.vcs
.MsgBrokerTasklet(),
424 rift
.vcs
.RestPortForwardTasklet(),
425 rift
.vcs
.RestconfTasklet(),
427 rift
.vcs
.uAgentTasklet(),
428 rift
.vcs
.Launchpad(),
433 rift
.vcs
.DtsRouterTasklet(),
434 rift
.vcs
.MsgBrokerTasklet(),
437 datastore
= core
.DataStore
.BDB
.value
439 procs
.append(RedisServer())
440 datastore
= core
.DataStore
.REDIS
.value
443 procs
.append(UIServer())
446 VnfmTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
447 VnsTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
448 # MonitorTasklet(recovery_action=core.RecoveryType.RESTART.value, data_storetype=datastore),
449 MonitoringParameterTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
450 NsmTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
451 ResMgrTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
452 ImageMgrTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
453 AutoscalerTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
454 PackageManagerTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
455 StagingManagerTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
458 if not mgmt_ip_list
or len(mgmt_ip_list
) == 0:
459 mgmt_ip_list
.append("127.0.0.1")
461 colony
= rift
.vcs
.core
.Colony(name
='top', uid
=1)
463 lead_lp_vm
= rift
.vcs
.VirtualMachine(
464 name
='vm-launchpad-1',
467 restart_procs
=restart_procs
,
469 lead_lp_vm
.leader
= True
470 colony
.append(lead_lp_vm
)
473 stby_lp_vm
= rift
.vcs
.VirtualMachine(
474 name
='launchpad-vm-2',
479 # WA to Agent mode_active flag reset
480 stby_lp_vm
.add_tasklet(rift
.vcs
.uAgentTasklet(), mode_active
=False)
481 colony
.append(stby_lp_vm
)
483 sysinfo
= rift
.vcs
.SystemInfo(
485 zookeeper
=rift
.vcs
.manifest
.RaZookeeper(master_ip
=mgmt_ip_list
[0]),
488 multi_dtsrouter
=True,
489 mgmt_ip_list
=mgmt_ip_list
,
493 super(Demo
, self
).__init
__(
494 # Construct the system. This system consists of 1 cluster in 1
495 # colony. The master cluster houses CLI and management VMs
498 # Define the generic portmap.
501 # Define a mapping from the placeholder logical names to the real
502 # port names for each of the different modes supported by this demo.
510 # Define the connectivity between logical port names.
515 def main(argv
=sys
.argv
[1:]):
516 logging
.basicConfig(format
='%(asctime)-15s %(levelname)s %(message)s')
518 # Create a parser which includes all generic demo arguments
519 parser
= rift
.vcs
.demo
.DemoArgParser()
520 parser
.add_argument("--no-ui", action
='store_true')
521 args
= parser
.parse_args(argv
)
523 # Disable loading any kernel modules for the launchpad VM
524 # since it doesn't need it and it will fail within containers
525 os
.environ
["NO_KERNEL_MODS"] = "1"
527 cleanup_dir_name
= None
528 if os
.environ
["INSTALLDIR"] in ["/", "/home/rift", "/home/rift/.install",
529 "/usr/rift/build/fc20_debug/install/usr/rift", "/usr/rift"]:
530 cleanup_dir_name
= os
.environ
["INSTALLDIR"] + "/var/rift/"
532 if args
.test_name
and not cleanup_dir_name
:
533 cleanup_dir_name
= "find {rift_install}/var/rift -name '*{pattern}*' -type d".format( \
534 rift_install
=os
.environ
['RIFT_INSTALL'],
535 pattern
= args
.test_name
)
537 cleanup_dir_name
= subprocess
.check_output(cleanup_dir_name
, shell
=True)
538 cleanup_dir_name
= cleanup_dir_name
[:-1].decode("utf-8") + "/"
539 except Exception as e
:
540 print ("Directory not found exception occurred. Probably running for first time")
541 print ("Zookeper cleanup cmd = {}".format(cleanup_dir_name
))
543 if not cleanup_dir_name
:
544 cleanup_dir_name
= os
.environ
["INSTALLDIR"] + "/"
546 # Remove the persistent Redis data
548 for f
in os
.listdir(cleanup_dir_name
):
549 if f
.endswith(".aof") or f
.endswith(".rdb"):
550 os
.remove(os
.path
.join(cleanup_dir_name
, f
))
552 # Remove the persistant DTS recovery files
553 for f
in os
.listdir(cleanup_dir_name
):
554 if f
.endswith(".db"):
555 os
.remove(os
.path
.join(cleanup_dir_name
, f
))
557 shutil
.rmtree(os
.path
.join(cleanup_dir_name
, "zk/server-1"))
558 shutil
.rmtree(os
.path
.join(os
.environ
["INSTALLDIR"], "var/rift/tmp*"))
559 except FileNotFoundError
as e
:
561 except Exception as e
:
562 print ("Error while cleanup: {}".format(str(e
)))
564 ha_mode
= args
.ha_mode
565 mgmt_ip_list
= [] if not args
.mgmt_ip_list
else args
.mgmt_ip_list
567 #load demo info and create Demo object
568 demo
= Demo(args
.no_ui
, ha_mode
, mgmt_ip_list
, args
.test_name
)
570 # Create the prepared system from the demo
571 system
= rift
.vcs
.demo
.prepared_system_from_demo_and_args(demo
, args
,
572 northbound_listing
="cli_launchpad_schema_listing.txt",
573 netconf_trace_override
=True)
575 # Search for externally accessible IP address with netifaces
576 gateways
= netifaces
.gateways()
577 # Check for default route facing interface and then get its ip address
578 if 'default' in gateways
:
579 interface
= gateways
['default'][netifaces
.AF_INET
][1]
580 confd_ip
= netifaces
.ifaddresses(interface
)[netifaces
.AF_INET
][0]['addr']
582 # no default gateway. Revert to 127.0.0.1
583 confd_ip
= "127.0.0.1"
584 # TODO: This need to be changed when launchpad starts running on multiple VMs
585 rift
.vcs
.logger
.configure_sink(config_file
=None, confd_ip
=confd_ip
)
587 # Start the prepared system
591 if __name__
== "__main__":
592 resource
.setrlimit(resource
.RLIMIT_CORE
, (resource
.RLIM_INFINITY
, resource
.RLIM_INFINITY
) )
595 except rift
.vcs
.demo
.ReservationError
:
596 print("ERROR: unable to retrieve a list of IP addresses from the reservation system")
598 except rift
.vcs
.demo
.MissingModeError
:
599 print("ERROR: you need to provide a mode to run the script")
602 os
.system("stty sane")