diff --git a/.gitignore b/.gitignore index 64112e73..2728ac17 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ nova_powervm.egg-info/ doc/build AUTHORS ChangeLog +*.DS_Store +.venv diff --git a/doc/ext/__init__.py b/doc/ext/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/doc/ext/support_matrix.py b/doc/ext/support_matrix.py new file mode 100644 index 00000000..67e9b44d --- /dev/null +++ b/doc/ext/support_matrix.py @@ -0,0 +1,516 @@ +# Copyright (C) 2014 Red Hat, Inc. +# +# 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. + +""" +This provides a sphinx extension able to render the source/support-matrix.ini +file into the developer documentation. + +It is used via a single directive in the .rst file + + .. support_matrix:: + +""" + +import re + +import six +from six.moves import configparser + +from docutils import nodes +from docutils.parsers import rst + + +class SupportMatrix(object): + """Represents the entire support matrix for Nova virt drivers + """ + + def __init__(self): + # List of SupportMatrixFeature instances, describing + # all the features present in Nova virt drivers + self.features = [] + + # Dict of (name, SupportMatrixTarget) enumerating + # all the hypervisor drivers that have data recorded + # for them in self.features. The 'name' dict key is + # the value from the SupportMatrixTarget.key attribute + self.targets = {} + + +class SupportMatrixFeature(object): + + STATUS_MANDATORY = "mandatory" + STATUS_CHOICE = "choice" + STATUS_CONDITION = "condition" + STATUS_OPTIONAL = "optional" + + STATUS_ALL = [STATUS_MANDATORY, STATUS_CHOICE, + STATUS_CONDITION, STATUS_OPTIONAL] + + def __init__(self, key, title, status=STATUS_OPTIONAL, + group=None, notes=None, cli=[]): + # A unique key (eg 'foo.bar.wizz') to identify the feature + self.key = key + # A human friendly short title for the feature + self.title = title + # One of the status constants + self.status = status + # Detail string if status was choice/condition + self.group = group + # Arbitrarily long string describing the feature in detail + self.notes = notes + # Dict of (name, SupportMatrixImplementation) detailing + # the implementation for each hypervisor driver. The + # 'name' dict key is the value from SupportMatrixTarget.key + # for the hypervisor in question + self.implementations = {} + # A list of CLI commands which are related to that feature + self.cli = cli + + +class SupportMatrixImplementation(object): + + STATUS_COMPLETE = "complete" + STATUS_PARTIAL = "partial" + STATUS_MISSING = "missing" + STATUS_UKNOWN = "unknown" + + STATUS_ALL = [STATUS_COMPLETE, STATUS_PARTIAL, STATUS_MISSING, + STATUS_UKNOWN] + + def __init__(self, status=STATUS_MISSING, notes=None): + # One of the status constants detailing the implementation + # level + self.status = status + # Arbitrary string describing any caveats of the implementation. + # Mandatory if status is 'partial', optional otherwise. + self.notes = notes + + +class SupportMatrixTarget(object): + + def __init__(self, key, title, driver, hypervisor=None, architecture=None): + """:param key: Unique identifier for the hypervisor driver + :param title: Human friendly name of the hypervisor + :param driver: Name of the Nova driver + :param hypervisor: (optional) Name of the hypervisor, if many + :param architecture: (optional) Name of the architecture, if many + """ + self.key = key + self.title = title + self.driver = driver + self.hypervisor = hypervisor + self.architecture = architecture + + +class SupportMatrixDirective(rst.Directive): + + # The argument is the filename, e.g. support-matrix.ini + required_arguments = 1 + + def run(self): + matrix = self._load_support_matrix() + return self._build_markup(matrix) + + def _load_support_matrix(self): + """Reads the support-matrix.ini file and populates an instance + of the SupportMatrix class with all the data. + + :returns: SupportMatrix instance + """ + + cfg = configparser.SafeConfigParser() + env = self.state.document.settings.env + fname = self.arguments[0] + rel_fpath, fpath = env.relfn2path(fname) + with open(fpath) as fp: + cfg.readfp(fp) + + # This ensures that the docs are rebuilt whenever the + # .ini file changes + env.note_dependency(rel_fpath) + + matrix = SupportMatrix() + matrix.targets = self._get_targets(cfg) + matrix.features = self._get_features(cfg, matrix.targets) + + return matrix + + def _get_targets(self, cfg): + # The 'targets' section is special - it lists all the + # hypervisors that this file records data for + + targets = {} + + for item in cfg.options("targets"): + if not item.startswith("driver-impl-"): + continue + + # The driver string will optionally contain + # a hypervisor and architecture qualifier + # so we expect between 1 and 3 components + # in the name + key = item[12:] + title = cfg.get("targets", item) + name = key.split("-") + if len(name) == 1: + target = SupportMatrixTarget(key, + title, + name[0]) + elif len(name) == 2: + target = SupportMatrixTarget(key, + title, + name[0], + name[1]) + elif len(name) == 3: + target = SupportMatrixTarget(key, + title, + name[0], + name[1], + name[2]) + else: + raise Exception("'%s' field is malformed in '[%s]' section" % + (item, "DEFAULT")) + + targets[key] = target + + return targets + + def _get_features(self, cfg, targets): + # All sections except 'targets' describe some feature of + # the Nova hypervisor driver implementation + + features = [] + + for section in cfg.sections(): + if section == "targets": + continue + if not cfg.has_option(section, "title"): + raise Exception( + "'title' field missing in '[%s]' section" % section) + + title = cfg.get(section, "title") + + status = SupportMatrixFeature.STATUS_OPTIONAL + if cfg.has_option(section, "status"): + # The value is a string "status(group)" where + # the 'group' part is optional + status = cfg.get(section, "status") + offset = status.find("(") + group = None + if offset != -1: + group = status[offset + 1:-1] + status = status[0:offset] + + if status not in SupportMatrixFeature.STATUS_ALL: + raise Exception( + "'status' field value '%s' in ['%s']" + "section must be %s" % + (status, section, + ",".join(SupportMatrixFeature.STATUS_ALL))) + + notes = None + if cfg.has_option(section, "notes"): + notes = cfg.get(section, "notes") + cli = [] + if cfg.has_option(section, "cli"): + cli = cfg.get(section, "cli") + feature = SupportMatrixFeature(section, + title, + status, + group, + notes, + cli) + + # Now we've got the basic feature details, we must process + # the hypervisor driver implementation for each feature + for item in cfg.options(section): + if not item.startswith("driver-impl-"): + continue + + key = item[12:] + if key not in targets: + raise Exception( + "Driver impl '%s' in '[%s]' not declared" % + (item, section)) + + status = cfg.get(section, item) + if status not in SupportMatrixImplementation.STATUS_ALL: + raise Exception( + "'%s' value '%s' in '[%s]' section must be %s" % + (item, status, section, + ",".join(SupportMatrixImplementation.STATUS_ALL))) + + noteskey = "driver-notes-" + item[12:] + notes = None + if cfg.has_option(section, noteskey): + notes = cfg.get(section, noteskey) + + target = targets[key] + impl = SupportMatrixImplementation(status, + notes) + feature.implementations[target.key] = impl + + for key in targets: + if key not in feature.implementations: + raise Exception("'%s' missing in '[%s]' section" % + (target.key, section)) + + features.append(feature) + + return features + + def _build_markup(self, matrix): + """Constructs the docutils content for the support matrix + """ + content = [] + self._build_summary(matrix, content) + self._build_details(matrix, content) + self._build_notes(content) + return content + + def _build_summary(self, matrix, content): + """Constructs the docutils content for the summary of + the support matrix. + + The summary consists of a giant table, with one row + for each feature, and a column for each hypervisor + driver. It provides an 'at a glance' summary of the + status of each driver + """ + + summarytitle = nodes.subtitle(text="Summary") + summary = nodes.table() + cols = len(matrix.targets.keys()) + cols += 2 + summarygroup = nodes.tgroup(cols=cols) + summarybody = nodes.tbody() + summaryhead = nodes.thead() + + for i in range(cols): + summarygroup.append(nodes.colspec(colwidth=1)) + summarygroup.append(summaryhead) + summarygroup.append(summarybody) + summary.append(summarygroup) + content.append(summarytitle) + content.append(summary) + + # This sets up all the column headers - two fixed + # columns for feature name & status + header = nodes.row() + blank = nodes.entry() + blank.append(nodes.emphasis(text="Feature")) + header.append(blank) + blank = nodes.entry() + blank.append(nodes.emphasis(text="Status")) + header.append(blank) + summaryhead.append(header) + + # then one column for each hypervisor driver + impls = matrix.targets.keys() + impls.sort() + for key in impls: + target = matrix.targets[key] + implcol = nodes.entry() + header.append(implcol) + implcol.append(nodes.strong(text=target.title)) + + # We now produce the body of the table, one row for + # each feature to report on + for feature in matrix.features: + item = nodes.row() + + # the hyperlink target name linking to details + id = re.sub("[^a-zA-Z0-9_]", "_", + feature.key) + + # first the to fixed columns for title/status + keycol = nodes.entry() + item.append(keycol) + keyref = nodes.reference(refid=id) + keytxt = nodes.inline() + keycol.append(keytxt) + keytxt.append(keyref) + keyref.append(nodes.strong(text=feature.title)) + + statuscol = nodes.entry() + item.append(statuscol) + statuscol.append(nodes.inline( + text=feature.status, + classes=["sp_feature_" + feature.status])) + + # and then one column for each hypervisor driver + impls = matrix.targets.keys() + impls.sort() + for key in impls: + target = matrix.targets[key] + impl = feature.implementations[key] + implcol = nodes.entry() + item.append(implcol) + + id = re.sub("[^a-zA-Z0-9_]", "_", + feature.key + "_" + key) + + implref = nodes.reference(refid=id) + impltxt = nodes.inline() + implcol.append(impltxt) + impltxt.append(implref) + + status = "" + if impl.status == SupportMatrixImplementation.STATUS_COMPLETE: + status = u"\u2714" + elif impl.status == SupportMatrixImplementation.STATUS_MISSING: + status = u"\u2716" + elif impl.status == SupportMatrixImplementation.STATUS_PARTIAL: + status = u"\u2714" + elif impl.status == SupportMatrixImplementation.STATUS_UKNOWN: + status = u"?" + + implref.append(nodes.literal( + text=status, + classes=["sp_impl_summary", "sp_impl_" + impl.status])) + + summarybody.append(item) + + def _build_details(self, matrix, content): + """Constructs the docutils content for the details of + the support matrix. + + This is generated as a bullet list of features. + Against each feature we provide the description of + the feature and then the details of the hypervisor + impls, with any driver specific notes that exist + """ + + detailstitle = nodes.subtitle(text="Details") + details = nodes.bullet_list() + + content.append(detailstitle) + content.append(details) + + # One list entry for each feature we're reporting on + for feature in matrix.features: + item = nodes.list_item() + + status = feature.status + if feature.group is not None: + status += "(" + feature.group + ")" + + # The hypervisor target name linked from summary table + id = re.sub("[^a-zA-Z0-9_]", "_", + feature.key) + + # Highlight the feature title name + item.append(nodes.strong(text=feature.title, + ids=[id])) + + para = nodes.paragraph() + para.append(nodes.strong(text="Status: " + status + ". ")) + if feature.notes is not None: + para.append(nodes.inline(text=feature.notes)) + item.append(para) + + if feature.cli: + item.append(self._create_cli_paragraph(feature)) + + para_divers = nodes.paragraph() + para_divers.append(nodes.strong(text="drivers:")) + # A sub-list giving details of each hypervisor target + impls = nodes.bullet_list() + for key in feature.implementations: + target = matrix.targets[key] + impl = feature.implementations[key] + subitem = nodes.list_item() + + id = re.sub("[^a-zA-Z0-9_]", "_", + feature.key + "_" + key) + subitem += [ + nodes.strong(text=target.title + ": "), + nodes.literal(text=impl.status, + classes=["sp_impl_" + impl.status], + ids=[id]), + ] + if impl.notes is not None: + subitem.append(self._create_notes_paragraph(impl.notes)) + impls.append(subitem) + + para_divers.append(impls) + item.append(para_divers) + details.append(item) + + def _build_notes(self, content): + """Constructs a list of notes content for the support matrix. + + This is generated as a bullet list. + """ + notestitle = nodes.subtitle(text="Notes") + notes = nodes.bullet_list() + + content.append(notestitle) + content.append(notes) + + NOTES = [ + "Virtuozzo was formerly named Parallels in this document" + ] + + for note in NOTES: + item = nodes.list_item() + item.append(nodes.strong(text=note)) + notes.append(item) + + def _create_cli_paragraph(self, feature): + ''' Create a paragraph which represents the CLI commands of the feature + + The paragraph will have a bullet list of CLI commands. + ''' + para = nodes.paragraph() + para.append(nodes.strong(text="CLI commands:")) + commands = nodes.bullet_list() + for c in feature.cli.split(";"): + cli_command = nodes.list_item() + cli_command += nodes.literal(text=c, classes=["sp_cli"]) + commands.append(cli_command) + para.append(commands) + return para + + def _create_notes_paragraph(self, notes): + """ Constructs a paragraph which represents the implementation notes + + The paragraph consists of text and clickable URL nodes if links were + given in the notes. + """ + para = nodes.paragraph() + # links could start with http:// or https:// + link_idxs = [m.start() for m in re.finditer('https?://', notes)] + start_idx = 0 + for link_idx in link_idxs: + # assume the notes start with text (could be empty) + para.append(nodes.inline(text=notes[start_idx:link_idx])) + # create a URL node until the next text or the end of the notes + link_end_idx = notes.find(" ", link_idx) + if link_end_idx == -1: + # In case the notes end with a link without a blank + link_end_idx = len(notes) + uri = notes[link_idx:link_end_idx + 1] + para.append(nodes.reference("", uri, refuri=uri)) + start_idx = link_end_idx + 1 + + # get all text after the last link (could be empty) or all of the + # text if no link was given + para.append(nodes.inline(text=notes[start_idx:])) + return para + + +def setup(app): + app.add_directive('support_matrix', SupportMatrixDirective) + app.add_stylesheet('support-matrix.css') diff --git a/doc/source/conf.py b/doc/source/conf.py index 39b03349..e723cf34 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -20,6 +20,8 @@ import os # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('../..')) +sys.path.insert(0, os.path.abspath('../')) +sys.path.insert(0, os.path.abspath('./')) # -- General configuration ------------------------------------------------ @@ -31,7 +33,8 @@ sys.path.insert(0, os.path.abspath('../..')) # ones. extensions = [ 'sphinx.ext.autodoc', - 'oslosphinx' + 'oslosphinx', + 'ext.support_matrix' ] # Add any paths that contain templates here, relative to this directory. diff --git a/doc/source/index.rst b/doc/source/index.rst index bd15fba3..6cfbe009 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -38,6 +38,7 @@ Contents: :maxdepth: 1 readme + support-matrix Nova-PowerVM Policies ===================== diff --git a/doc/source/support-matrix.ini b/doc/source/support-matrix.ini new file mode 100644 index 00000000..726151c6 --- /dev/null +++ b/doc/source/support-matrix.ini @@ -0,0 +1,597 @@ +# Copyright (C) 2014 Red Hat, Inc. +# +# 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. +# +# +# +# ========================================= +# Nova Hypervisor Feature Capability Matrix +# ========================================= +# +# This obsoletes the information previously at +# +# https://wiki.openstack.org/wiki/HypervisorSupportMatrix +# +# This file contains a specification of what feature capabilities each +# hypervisor driver in Nova is able to support. Feature capabilities include +# what API operations are supported, what storage / networking features can be +# used and what aspects of the guest machine can be configured. The capabilities +# can be considered to be structured into nested groups, but in this file they +# have been flattened for ease of representation. The section names represent +# the group structure. At the top level there are the following groups defined +# +# - operation - public API operations +# - storage - host storage configuration options +# - networking - host networking configuration options +# - guest - guest hardware configuration options +# +# When considering which capabilities should be marked as mandatory, +# consider the general guiding principles listed in the support-matrix.rst +# file +# +# The 'status' field takes possible values +# +# - mandatory - unconditionally required to be implemented +# - optional - optional to support, nice to have +# - choice(group) - at least one of the options within the named group +# must be implemented +# - conditional(cond) - required, if the referenced condition is met. +# +# The value against each 'driver-impl-XXXX' entry refers to the level +# of the implementation of the feature in that driver +# +# - complete - fully implemented, expected to work at all times +# - partial - implemented, but with caveats about when it will work +# eg some configurations or hardware or guest OS may not +# support it +# - missing - not implemented at all +# +# In the case of the driver being marked as 'partial', then +# 'driver-notes-XXX' entry should be used to explain the caveats +# around the implementation. +# +# The 'cli' field takes a list of nova client commands, separated by semicolon. +# These CLi commands are related to that feature. +# Example: +# cli=nova list;nova show +# +[targets] +# List of driver impls we are going to record info for later +# This list only covers the PowerVM driver. Please see the equivalent +# document in the Nova tree for information on in-tree hypervisors. +driver-impl-powervm=PowerVM + +[operation.attach-volume] +title=Attach block volume to instance +status=optional +notes=The attach volume operation provides a means to hotplug + additional block storage to a running instance. This allows + storage capabilities to be expanded without interruption of + service. In a cloud model it would be more typical to just + spin up a new instance with large storage, so the ability to + hotplug extra storage is for those cases where the instance + is considered to be more of a pet than cattle. Therefore + this operation is not considered to be mandatory to support. +cli= +driver-impl-powervm=complete + +[operation.detach-volume] +title=Detach block volume from instance +status=optional +notes=See notes for attach volume operation. +cli= +driver-impl-powervm=complete + +[operation.maintenance-mode] +title=Set the host in a maintenance mode +status=optional +notes=This operation allows a host to be placed into maintenance + mode, automatically triggering migration of any running + instances to an alternative host and preventing new + instances from being launched. This is not considered + to be a mandatory operation to support. + The CLI command is "nova host-update ". + The driver methods to implement are "host_maintenance_mode" and + "set_host_enabled". +cli= +driver-impl-powervm=complete + +[operation.evacuate] +title=Evacuate instances from a host +status=optional +notes=A possible failure scenario in a cloud environment is the outage + of one of the compute nodes. In such a case the instances of the down + host can be evacuated to another host. It is assumed that the old host + is unlikely ever to be powered back on, otherwise the evacuation + attempt will be rejected. When the instances get moved to the new + host, their volumes get re-attached and the locally stored data is + dropped. That happens in the same way as a rebuild. + This is not considered to be a mandatory operation to support. +cli=nova evacuate ;nova host-evacuate +driver-impl-powervm=complete + +[operation.rebuild] +title=Rebuild instance +status=optional +notes=A possible use case is additional attributes need to be set + to the instance, nova will purge all existing data from the system + and remakes the VM with given information such as 'metadata' and + 'personalities'. Though this is not considered to be a mandatory + operation to support. +cli=nova rebuild ; +driver-impl-powervm=complete + +[operation.get-guest-info] +title=Guest instance status +status=mandatory +notes=Provides a quick report on information about the guest instance, + including the power state, memory allocation, CPU allocation, number + of vCPUs and cummulative CPU execution time. As well as being + informational, the power state is used by the compute manager for + tracking changes in guests. Therefore this operation is considered + mandatory to support. +cli= +driver-impl-powervm=complete + +[operation.get-host-info] +title=Guest host status +status=optional +notes=Unclear what this refers to +cli= +driver-impl-powervm=complete + +[operation.live-migrate] +title=Live migrate instance across hosts +status=optional +notes=Live migration provides a way to move an instance off one + compute host, to another compute host. Administrators may use + this to evacuate instances from a host that needs to undergo + maintenance tasks, though of course this may not help if the + host is already suffering a failure. In general instances are + considered cattle rather than pets, so it is expected that an + instance is liable to be killed if host maintenance is required. + It is technically challenging for some hypervisors to provide + support for the live migration operation, particularly those + built on the container based virtualization. Therefore this + operation is not considered mandatory to support. +cli= +driver-impl-powervm=complete + +[operation.launch] +title=Launch instance +status=mandatory +notes=Importing pre-existing running virtual machines on a host is + considered out of scope of the cloud paradigm. Therefore this + operation is mandatory to support in drivers. +cli= +driver-impl-powervm=complete + +[operation.pause] +title=Stop instance CPUs (pause) +status=optional +notes=Stopping an instances CPUs can be thought of as roughly + equivalent to suspend-to-RAM. The instance is still present + in memory, but execution has stopped. The problem, however, + is that there is no mechanism to inform the guest OS that + this takes place, so upon unpausing, its clocks will no + longer report correct time. For this reason hypervisor vendors + generally discourage use of this feature and some do not even + implement it. Therefore this operation is considered optional + to support in drivers. +cli= +driver-impl-powervm=missing + +[operation.reboot] +title=Reboot instance +status=optional +notes=It is reasonable for a guest OS administrator to trigger a + graceful reboot from inside the instance. A host initiated + graceful reboot requires guest co-operation and a non-graceful + reboot can be achieved by a combination of stop+start. Therefore + this operation is considered optional. +cli= +driver-impl-powervm=complete + +[operation.rescue] +title=Rescue instance +status=optional +notes=The rescue operation starts an instance in a special + configuration whereby it is booted from an special root + disk image. The goal is to allow an administrator to + recover the state of a broken virtual machine. In general + the cloud model considers instances to be cattle, so if + an instance breaks the general expectation is that it be + thrown away and a new instance created. Therefore this + operation is considered optional to support in drivers. +cli= +driver-impl-powervm=complete + +[operation.resize] +title=Resize instance +status=optional +notes=The resize operation allows the user to change a running + instance to match the size of a different flavor from the one + it was initially launched with. There are many different + flavor attributes that potentially need to be updated. In + general it is technically challenging for a hypervisor to + support the alteration of all relevant config settings for a + running instance. Therefore this operation is considered + optional to support in drivers. +cli= +driver-impl-powervm=complete + +[operation.resume] +title=Restore instance +status=optional +notes=See notes for the suspend operation +cli= +driver-impl-powervm=missing + +[operation.service-control.wtf.com] +title=Service control +status=optional +notes=Something something, dark side, something something. + Hard to claim this is mandatory when no one seems to know + what "Service control" refers to in the context of virt + drivers. +cli= +driver-impl-powervm=missing + +[operation.set-admin-password] +title=Set instance admin password +status=optional +notes=Provides a mechanism to re(set) the password of the administrator + account inside the instance operating system. This requires that the + hypervisor has a way to communicate with the running guest operating + system. Given the wide range of operating systems in existence it is + unreasonable to expect this to be practical in the general case. The + configdrive and metadata service both provide a mechanism for setting + the administrator password at initial boot time. In the case where this + operation were not available, the administrator would simply have to + login to the guest and change the password in the normal manner, so + this is just a convenient optimization. Therefore this operation is + not considered mandatory for drivers to support. +cli= +driver-impl-powervm=missing + +[operation.snapshot] +title=Save snapshot of instance disk +status=optional +notes=The snapshot operation allows the current state of the + instance root disk to be saved and uploaded back into the + glance image repository. The instance can later be booted + again using this saved image. This is in effect making + the ephemeral instance root disk into a semi-persistent + storage, in so much as it is preserved even though the guest + is no longer running. In general though, the expectation is + that the root disks are ephemeral so the ability to take a + snapshot cannot be assumed. Therefore this operation is not + considered mandatory to support. +cli= +driver-impl-powervm=complete + +[operation.suspend] +title=Suspend instance +status=optional +notes=Suspending an instance can be thought of as roughly + equivalent to suspend-to-disk. The instance no longer + consumes any RAM or CPUs, with its live running state + having been preserved in a file on disk. It can later + be restored, at which point it should continue execution + where it left off. As with stopping instance CPUs, it suffers from the fact + that the guest OS will typically be left with a clock that + is no longer telling correct time. For container based + virtualization solutions, this operation is particularly + technically challenging to implement and is an area of + active research. This operation tends to make more sense + when thinking of instances as pets, rather than cattle, + since with cattle it would be simpler to just terminate + the instance instead of suspending. Therefore this operation + is considered optional to support. +cli= +driver-impl-powervm=missing + +[operation.swap-volume] +title=Swap block volumes +status=optional +notes=The swap volume operation is a mechanism for changing a running + instance so that its attached volume(s) are backed by different + storage in the host. An alternative to this would be to simply + terminate the existing instance and spawn a new instance with the + new storage. In other words this operation is primarily targeted towards + the pet use case rather than cattle, however, it is required for volume + migration to work in the volume service. This is considered optional to + support. +cli= +driver-impl-powervm=missing + +[operation.terminate] +title=Shutdown instance +status=mandatory +notes=The ability to terminate a virtual machine is required in + order for a cloud user to stop utilizing resources and thus + avoid indefinitely ongoing billing. Therefore this operation + is mandatory to support in drivers. +cli= +driver-impl-powervm=complete + +[operation.trigger-crash-dump] +title=Trigger crash dump +status=optional +notes=The trigger crash dump operation is a mechanism for triggering + a crash dump in an instance. The feature is typically implemented by + injecting an NMI (Non-maskable Interrupt) into the instance. It provides + a means to dump the production memory image as a dump file which is useful + for users. Therefore this operation is considered optional to support. +cli= +driver-impl-powervm=missing + +[operation.unpause] +title=Resume instance CPUs (unpause) +status=optional +notes=See notes for the "Stop instance CPUs" operation +cli= +driver-impl-powervm=missing + +[guest.disk.autoconfigure.wtf.com] +title=Auto configure disk +status=optional +notes=something something, dark side, something something. + Unclear just what this is about. +cli= +driver-impl-powervm=missing + +[guest.disk.rate-limit] +title=Instance disk I/O limits +status=optional +notes=The ability to set rate limits on virtual disks allows for + greater performance isolation between instances running on the + same host storage. It is valid to delegate scheduling of I/O + operations to the hypervisor with its default settings, instead + of doing fine grained tuning. Therefore this is not considered + to be an mandatory configuration to support. +cli= +driver-impl-powervm=missing + +[guest.setup.configdrive] +title=Config drive support +status=choice(guest.setup) +notes=The config drive provides an information channel into + the guest operating system, to enable configuration of the + administrator password, file injection, registration of + SSH keys, etc. Since cloud images typically ship with all + login methods locked, a mechanism to set the administrator + password of keys is required to get login access. Alternatives + include the metadata service and disk injection. At least one + of the guest setup mechanisms is required to be supported by + drivers, in order to enable login access. +cli= +driver-impl-powervm=complete + +[guest.setup.inject.file] +title=Inject files into disk image +status=optional +notes=This allows for the end user to provide data for multiple + files to be injected into the root filesystem before an instance + is booted. This requires that the compute node understand the + format of the filesystem and any partitioning scheme it might + use on the block device. This is a non-trivial problem considering + the vast number of filesystems in existence. The problem of injecting + files to a guest OS is better solved by obtaining via the metadata + service or config drive. Therefore this operation is considered + optional to support. +cli= +driver-impl-powervm=missing + +[guest.setup.inject.networking] +title=Inject guest networking config +status=optional +notes=This allows for static networking configuration (IP + address, netmask, gateway and routes) to be injected directly + into the root filesystem before an instance is booted. This + requires that the compute node understand how networking is + configured in the guest OS which is a non-trivial problem + considering the vast number of operating system types. The + problem of configuring networking is better solved by DHCP + or by obtaining static config via the metadata service or + config drive. Therefore this operation is considered optional + to support. +cli= +driver-impl-powervm=missing + +[console.rdp] +title=Remote desktop over RDP +status=choice(console) +notes=This allows the administrator to interact with the graphical + console of the guest OS via RDP. This provides a way to see boot + up messages and login to the instance when networking configuration + has failed, thus preventing a network based login. Some operating + systems may prefer to emit messages via the serial console for + easier consumption. Therefore support for this operation is not + mandatory, however, a driver is required to support at least one + of the listed console access operations. +cli= +driver-impl-powervm=missing + +[console.serial.log] +title=View serial console logs +status=choice(console) +notes=This allows the administrator to query the logs of data + emitted by the guest OS on its virtualized serial port. For + UNIX guests this typically includes all boot up messages and + so is useful for diagnosing problems when an instance fails + to successfully boot. Not all guest operating systems will be + able to emit boot information on a serial console, others may + only support graphical consoles. Therefore support for this + operation is not mandatory, however, a driver is required to + support at least one of the listed console access operations. +cli= +driver-impl-powervm=missing + +[console.serial.interactive] +title=Remote interactive serial console +status=choice(console) +notes=This allows the administrator to interact with the serial + console of the guest OS. This provides a way to see boot + up messages and login to the instance when networking configuration + has failed, thus preventing a network based login. Not all guest + operating systems will be able to emit boot information on a serial + console, others may only support graphical consoles. Therefore support + for this operation is not mandatory, however, a driver is required to + support at least one of the listed console access operations. + This feature was introduced in the Juno release with blueprint + https://blueprints.launchpad.net/nova/+spec/serial-ports +cli=nova get-serial-console +driver-impl-powervm=missing + +[console.spice] +title=Remote desktop over SPICE +status=choice(console) +notes=This allows the administrator to interact with the graphical + console of the guest OS via SPICE. This provides a way to see boot + up messages and login to the instance when networking configuration + has failed, thus preventing a network based login. Some operating + systems may prefer to emit messages via the serial console for + easier consumption. Therefore support for this operation is not + mandatory, however, a driver is required to support at least one + of the listed console access operations. +cli= +driver-impl-powervm=missing + +[console.vnc] +title=Remote desktop over VNC +status=choice(console) +notes=This allows the administrator to interact with the graphical + console of the guest OS via VNC. This provides a way to see boot + up messages and login to the instance when networking configuration + has failed, thus preventing a network based login. Some operating + systems may prefer to emit messages via the serial console for + easier consumption. Therefore support for this operation is not + mandatory, however, a driver is required to support at least one + of the listed console access operations. +cli= +driver-impl-powervm=complete + +[storage.block] +title=Block storage support +status=optional +notes=Block storage provides instances with direct attached + virtual disks that can be used for persistent storage of data. + As an alternative to direct attached disks, an instance may + choose to use network based persistent storage. OpenStack provides + object storage via the Swift service, or a traditional filesystem + such as NFS/GlusterFS may be used. Some types of instances may + not require persistent storage at all, being simple transaction + processing systems reading requests & sending results to and from + the network. Therefore support for this configuration is not + considered mandatory for drivers to support. +cli= +driver-impl-powervm=complete + +[storage.block.backend.fibrechannel] +title=Block storage over fibre channel +status=optional +notes=To maximise performance of the block storage, it may be desirable + to directly access fibre channel LUNs from the underlying storage + technology on the compute hosts. Since this is just a performance + optimization of the I/O path it is not considered mandatory to support. +cli= +driver-impl-powervm=complete + +[storage.block.backend.iscsi] +title=Block storage over iSCSI +status=condition(storage.block==complete) +notes=If the driver wishes to support block storage, it is common to + provide an iSCSI based backend to access the storage from cinder. + This isolates the compute layer for knowledge of the specific storage + technology used by Cinder, albeit at a potential performance cost due + to the longer I/O path involved. If the driver chooses to support + block storage, then this is considered mandatory to support, otherwise + it is considered optional. +cli= +driver-impl-powervm=missing + +[storage.block.backend.iscsi.auth.chap] +title=CHAP authentication for iSCSI +status=optional +notes=If accessing the cinder iSCSI service over an untrusted LAN it + is desirable to be able to enable authentication for the iSCSI + protocol. CHAP is the commonly used authentication protocol for + iSCSI. This is not considered mandatory to support. (?) +cli= +driver-impl-powervm=missing + +[storage.image] +title=Image storage support +status=mandatory +notes=This refers to the ability to boot an instance from an image + stored in the glance image repository. Without this feature it + would not be possible to bootstrap from a clean environment, since + there would be no way to get block volumes populated and reliance + on external PXE servers is out of scope. Therefore this is considered + a mandatory storage feature to support. +cli= +driver-impl-powervm=complete + +[networking.firewallrules] +title=Network firewall rules +status=optional +notes=Unclear how this is different from security groups +cli= +driver-impl-powervm=missing + +[networking.routing] +title=Network routing +status=optional +notes=Unclear what this refers to +cli= +driver-impl-powervm=complete + +[networking.securitygroups] +title=Network security groups +status=optional +notes=The security groups feature provides a way to define rules + to isolate the network traffic of different instances running + on a compute host. This would prevent actions such as MAC and + IP address spoofing, or the ability to setup rogue DHCP servers. + In a private cloud environment this may be considered to be a + superfluous requirement. Therefore this is considered to be an + optional configuration to support. +cli= +driver-impl-powervm=missing + +[networking.topology.flat] +title=Flat networking +status=choice(networking.topology) +notes=Provide network connectivity to guests using a + flat topology across all compute nodes. At least one + of the networking configurations is mandatory to + support in the drivers. +cli= +driver-impl-powervm=complete + +[networking.topology.vlan] +title=VLAN networking +status=choice(networking.topology) +notes=Provide network connectivity to guests using VLANs + to define the topology. At least one of the networking + configurations is mandatory to support in the drivers. +cli= +driver-impl-powervm=complete + +[operation.uefi-boot] +title=uefi boot +status=optional +notes=This allows users to boot a guest with uefi firmware. +cli= +driver-impl-powervm=missing diff --git a/doc/source/support-matrix.rst b/doc/source/support-matrix.rst new file mode 100644 index 00000000..ed08bdb3 --- /dev/null +++ b/doc/source/support-matrix.rst @@ -0,0 +1,41 @@ + +Feature Support Matrix +====================== + +.. warning:: + Please note, while this document is still being maintained, this is slowly + being updated to re-group and classify features + +When considering which capabilities should be marked as mandatory the +following general guiding principles were applied + +* **Inclusivity** - people have shown ability to make effective + use of a wide range of virtualization technologies with broadly + varying featuresets. Aiming to keep the requirements as inclusive + as possible, avoids second-guessing what a user may wish to use + the cloud compute service for. + +* **Bootstrapping** - a practical use case test is to consider that + starting point for the compute deploy is an empty data center + with new machines and network connectivity. The look at what + are the minimum features required of a compute service, in order + to get user instances running and processing work over the + network. + +* **Competition** - an early leader in the cloud compute service space + was Amazon EC2. A sanity check for whether a feature should be + mandatory is to consider whether it was available in the first + public release of EC2. This had quite a narrow featureset, but + none the less found very high usage in many use cases. So it + serves to illustrate that many features need not be considered + mandatory in order to get useful work done. + +* **Reality** - there are many virt drivers currently shipped with + Nova, each with their own supported feature set. Any feature which is + missing in at least one virt driver that is already in-tree, must + by inference be considered optional until all in-tree drivers + support it. This does not rule out the possibility of a currently + optional feature becoming mandatory at a later date, based on other + principles above. + +.. support_matrix:: support-matrix.ini