1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
# Copyright 2017 - Nokia
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
import sys
import cotyledon
from futurist import periodics
from futurist import ThreadPoolExecutor
from oslo_config import cfg
from oslo_log import log
import oslo_messaging
from tools.load_generator.notification_info import COMPUTE_INSTANCE_CREATE_END
from tools.load_generator.notification_info import PORT_CREATE_END
from tools.load_generator.notification_info import VOLUME_ATTACH_END
from tools.load_generator.notification_info import VOLUME_CREATE_END
from vitrage.common import config
from vitrage.messaging import get_transport
CONF = cfg.CONF
LOG = log.getLogger(__name__)
EXISTING_COMPUTES_NUM = 64
VMS_PER_COMPUTE = 2
NET_ID = '59fec1a4-7ab2-4bc6-8792-0ddf54b15dfe'
RUN_EVERY_X_SECONDS = 600
"""
Stress Notifications Tool:
Following service runs a timed action every X seconds.
Action will send mock bus notifications, as configured in the constants above.
Sends mock notifications for:
VM create
Port create
volume create
volume attach
1. To use this, place computes.yaml at /etc/vitrage/static_datasources/
and restart vitrage-graph.
2. EXISTING_COMPUTES_NUM should match the computes defined in computes.yaml
3. Configure NET_ID to an existing network (this tool doesnt create networks)
4. Run 'python load_generator.py'
Number of vms = VMS_PER_COMPUTE * EXISTING_COMPUTES_NUM
Number of ports = VMS_PER_COMPUTE * EXISTING_COMPUTES_NUM
Number of volumes = VMS_PER_COMPUTE * EXISTING_COMPUTES_NUM
Notifications are sent repeatedly every RUN_EVERY_X_SECONDS, this is
to avoid Vitrage consistency deleting the created resources.
* Folder /templates also includes templates to create load on the evaluator
"""
class StressNotificationsService(cotyledon.Service):
def __init__(self, worker_id):
super(StressNotificationsService, self).__init__(worker_id)
self.oslo_notifier = None
topics = CONF.datasources.notification_topics
self.oslo_notifier = oslo_messaging.Notifier(
get_transport(),
driver='messagingv2',
publisher_id='vitrage.stress',
topics=topics)
self.periodic = periodics.PeriodicWorker.create(
[], executor_factory=lambda: ThreadPoolExecutor(max_workers=10))
def run(self):
LOG.info("StressNotificationsService - Started!")
self.periodic.add(self.stress_notifications)
self.periodic.start()
def terminate(self):
self.periodic.stop()
LOG.info("StressNotificationsService - Stopped!")
@periodics.periodic(spacing=RUN_EVERY_X_SECONDS)
def stress_notifications(self):
notifications = []
for i in range(EXISTING_COMPUTES_NUM * VMS_PER_COMPUTE):
vm = create_vm(i, i % EXISTING_COMPUTES_NUM)
port = create_port(i, vm[0][1]['instance_id'], vm[0][1]['host'],
NET_ID)
storage = create_storage(i, vm[0][1]['instance_id'])
notifications.extend(vm)
notifications.extend(port)
notifications.extend(storage)
LOG.info("Notifications Created - " + str(len(notifications)))
LOG.info("Sending...")
for n in notifications:
self._send(*n)
LOG.info("Sent!")
def _send(self, notification_type, payload):
try:
self.oslo_notifier.info(
{},
notification_type,
payload)
except Exception:
LOG.exception('Cannot notify - %s', notification_type)
def create_port(port_num, instance_id, host_id, net_id):
payload = copy.deepcopy(PORT_CREATE_END)
payload['port']['id'] = 'StressPort-' + str(port_num)
payload['port']['device_id'] = instance_id
payload['port']['binding:host_id'] = host_id
payload['port']['network_id'] = net_id
return [('port.create.end', payload)]
def create_storage(volume_num, instance_id):
payload_1 = copy.deepcopy(VOLUME_CREATE_END)
payload_1['volume_id'] = 'StressVolume-' + str(volume_num)
payload_2 = copy.deepcopy(VOLUME_ATTACH_END)
payload_2['volume_id'] = payload_1['volume_id']
payload_2['volume_attachment'][0]['volume']['id'] = payload_1['volume_id']
payload_2['volume_attachment'][0]['instance_uuid'] = instance_id
return [('volume.create.end', payload_1),
('volume.attach.end', payload_2)]
def create_vm(instance_num, compute_num):
payload = copy.deepcopy(COMPUTE_INSTANCE_CREATE_END)
payload['instance_id'] = 'StressVM-' + str(instance_num)
payload['node'] = payload['host'] = "compute-0-" + str(compute_num)
return [('compute.instance.create.end', payload)]
def main():
config.parse_config(sys.argv)
sm = cotyledon.ServiceManager()
sm.add(StressNotificationsService)
sm.run()
if __name__ == "__main__":
sys.exit(main())
|