Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion nova-simulator.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ quota_floating_ips = -1
quota_ram = -1
quota_cores = -1
quota_instances = -1
compute_driver = nova.virt.fake.FakeDriver
compute_driver = nova.virt.simulator.SimulatorDriver
simulator_delay_probability = 0.0
simulator_delay_ms = 0
simulator_error_probability = 0.0
compute_processes = 3
glance_api_servers = 10.0.2.15:9292
rabbit_password = password
Expand Down
17 changes: 4 additions & 13 deletions nova/cmd/compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@
from nova import utils

CONF = cfg.CONF
CONF.import_opt('host', 'nova.netconf')
CONF.import_opt('compute_topic', 'nova.compute.rpcapi')
CONF.import_opt('compute_processes', 'nova.compute.simulator')
CONF.import_opt('use_local', 'nova.conductor.api', group='conductor')


Expand Down Expand Up @@ -65,15 +63,8 @@ def main():
objects_base.NovaObject.indirection_api = \
conductor_rpcapi.ConductorAPI()

for i in xrange(CONF.compute_processes):
if i > 0:
host = '%s-%s' % (CONF.host, str(i))
else:
host = CONF.host

server = service.Service.create(binary='nova-compute',
topic=CONF.compute_topic,
host=host,
db_allowed=False)
service.serve(server)
server = service.Service.create(binary='nova-compute',
topic=CONF.compute_topic,
db_allowed=False)
service.serve(server)
service.wait()
10 changes: 6 additions & 4 deletions nova/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,16 @@ def process_launcher():
# NOTE(vish): the global launcher is to maintain the existing
# functionality of calling service.serve +
# service.wait
_launcher = []
_launcher = None


def serve(server, workers=None):
global _launcher
_launcher.append(service.launch(server, workers=workers))
if _launcher:
raise RuntimeError(_('serve() can only be called once'))

_launcher = service.launch(server, workers=workers)


def wait():
for service in _launcher:
service.wait()
_launcher.wait()
5 changes: 3 additions & 2 deletions nova/virt/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
cfg.StrOpt('compute_driver',
help='Driver to use for controlling virtualization. Options '
'include: libvirt.LibvirtDriver, xenapi.XenAPIDriver, '
'fake.FakeDriver, baremetal.BareMetalDriver, '
'vmwareapi.VMwareESXDriver, vmwareapi.VMwareVCDriver'),
'fake.FakeDriver, simulator.SimulatorDriver, '
'baremetal.BareMetalDriver, vmwareapi.VMwareESXDriver, '
'vmwareapi.VMwareVCDriver'),
cfg.StrOpt('default_ephemeral_format',
help='The default format an ephemeral_volume will be '
'formatted with on creation.'),
Expand Down
56 changes: 19 additions & 37 deletions nova/virt/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
semantics of real hypervisor connections.

"""

from oslo.config import cfg

from nova import block_device
Expand All @@ -45,19 +46,6 @@
_FAKE_NODES = None


host_resource = {'vcpus': 1,
'memory_mb': 1024,
'memory_mb_used' : 0,
'local_gb': 1028,
'vcpus_used': 0,
'memory_mb_used': 0,
'local_gb_used': 0,
'hypervisor_type': 'fake',
'hypervisor_version': '1.0',
'hypervisor_hostname': CONF.host,
'disk_available_least': 0,
'cpu_info': '?'}

def set_nodes(nodes):
"""Sets FakeDriver's node.list.

Expand Down Expand Up @@ -103,30 +91,22 @@ def __init__(self, virtapi, read_only=False):
super(FakeDriver, self).__init__(virtapi)
self.instances = {}
self.host_status_base = {
'vcpus': 2,
'memory_mb': 582,
'local_gb': 6000,
'vcpus': 100000,
'memory_mb': 8000000000,
'local_gb': 600000000000,
'vcpus_used': 0,
'memory_mb_used': 0,
'local_gb_used': 0,
'local_gb_used': 100000000000,
'hypervisor_type': 'fake',
'hypervisor_version': '1.0',
'hypervisor_hostname': CONF.host,
'cpu_info': {},
'disk_available_least': 5000,
'disk_available_least': 500000000000,
}

self._mounts = {}
self._interfaces = {}
if not _FAKE_NODES:
nodes = []
for i in xrange(CONF.compute_processes):
if i == 0:
nodes.append(CONF.host)
else:
nodes.append('%s-%s' % (CONF.host, str(i)))

set_nodes(nodes)
set_nodes([CONF.host])

def init_host(self, host):
return
Expand Down Expand Up @@ -362,16 +342,18 @@ def get_available_resource(self, nodename):
if nodename not in _FAKE_NODES:
return {}

host_resource['hypervisor_hostname'] = nodename

host = self.fake_get_host_resource()

return host


def fake_get_host_resource(self):
"""Any calculation of host resource cost in simulator project in the future shoule be added here"""
return host_resource
dic = {'vcpus': 1,
'memory_mb': 8192,
'local_gb': 1028,
'vcpus_used': 0,
'memory_mb_used': 0,
'local_gb_used': 0,
'hypervisor_type': 'fake',
'hypervisor_version': '1.0',
'hypervisor_hostname': nodename,
'disk_available_least': 0,
'cpu_info': '?'}
return dic

def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
return
Expand Down
135 changes: 135 additions & 0 deletions nova/virt/simulator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4 #
# 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.

"""
:mod:`simulator` -- Fake driver that simulates errors and cluster capacity
===========================================================================
"""

import logging
import random
import time

import fake
from nova import exception
from oslo.config import cfg

LOG = logging.getLogger(__name__)
CONF = cfg.CONF

simulator_opts = [
cfg.FloatOpt('simulator_delay_probability',
default=0.0,
help='Delay a request issued to the SimulatorDriver with the'
'specified probability'),
cfg.IntOpt('simulator_delay_ms',
default=0,
help='Delay a request by the specified number of milliseconds'),
cfg.FloatOpt('simulator_error_probability',
default=0.0,
help='Inject a NovaException to the SimulatorDriver with the'
'specified probability'),
]

CONF.register_opts(simulator_opts)

CONF = cfg.CONF
CONF.import_opt('host', 'nova.netconf')
CONF.import_opt('simulator_error_probability', 'nova.virt.simulator')
CONF.import_opt('simulator_delay_probability', 'nova.virt.simulator')
CONF.import_opt('simulator_delay_ms', 'nova.virt.simulator')

to_simulate = ['spawn', 'live_snapshot', 'snapshot', 'reboot',
'resume_state_on_host_boot', 'rescue', 'unrescue',
'migrate_disk_and_power_off', 'finish_revert_migration',
'power_off', 'power_on', 'soft_delete', 'restore',
'pause', 'unpause', 'suspend', 'resume', 'destroy',
'swap_volume', 'finish_migration', 'finish_migration']


def inject(p):
return random.random() < p


def simulate(method):
if callable(method) and method.__name__ not in to_simulate:
return method

if inject(CONF.simulator_delay_probability):
delay_duration = random.random() * CONF.simulator_delay_ms / 1000.0
LOG.debug("Simulator injecting delay of %s ms" % delay_duration)
time.sleep(delay_duration)

if inject(CONF.simulator_error_probability):
LOG.debug("Simulator injecting NovaException")
raise exception.NovaException

return method


class SimulatorDriver(fake.FakeDriver):
def __init__(self, virtapi, read_only=False):
super(SimulatorDriver, self).__init__(virtapi, read_only)

nodes = []
nodes.append(CONF.host)
fake.set_nodes(nodes)
self.host_status_base = {
'vcpus': 2,
'memory_mb': 512,
'local_gb': 6000,
'vcpus_used': 0,
'memory_mb_used': 0,
'local_gb_used': 0,
'hypervisor_type': 'fake',
'hypervisor_version': '1.0',
'hypervisor_hostname': CONF.host,
'cpu_info': {},
'disk_available_least': 5000,
}
self.host_resource = {
'vcpus': 1,
'memory_mb': 1024,
'memory_mb_used': 0,
'local_gb': 1028,
'vcpus_used': 0,
'memory_mb_used': 0,
'local_gb_used': 0,
'hypervisor_type': 'fake',
'hypervisor_version': '1.0',
'hypervisor_hostname': CONF.host,
'disk_available_least': 0,
'cpu_info': '?'
}

def get_available_resource(self, nodename):
"""Updates compute manager resource info on ComputeNode table.

Since we don't have a real hypervisor, pretend we have lots of
disk and ram.
"""
if nodename not in fake._FAKE_NODES:
return {}

host = self.fake_get_host_resource()

return host

def fake_get_host_resource(self):
"""Any calculation of host resource cost in simulator project "
in the future shoule be added here"""
return self.host_resource

def __getattribute__(self, *args):
f = super(SimulatorDriver, self).__getattribute__(*args)
return simulate(f)