Replace support matrix ext with common library
The code to generate a support matrix has been pulled into a common library. Using this instead of duplicating code in various projects that need it. Change-Id: If01e440225fec2206e934ae7b0c6c2dce1266eab Co-Authored-By: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
b0256a71b2
commit
124e52062a
|
@ -1,518 +0,0 @@
|
|||
# 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
|
||||
"""
|
||||
if six.PY3:
|
||||
cfg = configparser.ConfigParser()
|
||||
else:
|
||||
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()
|
||||
sorted(impls)
|
||||
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()
|
||||
sorted(impls)
|
||||
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')
|
|
@ -1,2 +1,3 @@
|
|||
sphinx!=1.6.6,!=1.6.7,>=1.6.5 # BSD
|
||||
openstackdocstheme>=1.19.0 # Apache-2.0
|
||||
sphinx-feature-classification>=0.2.0 # Apache-2.0
|
||||
|
|
|
@ -25,7 +25,7 @@ sys.path.insert(0, os.path.abspath('../'))
|
|||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'openstackdocstheme',
|
||||
'ext.support_matrix'
|
||||
'sphinx_feature_classification.support_matrix'
|
||||
]
|
||||
|
||||
# The suffix of source filenames.
|
||||
|
|
|
@ -11,65 +11,12 @@
|
|||
# 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 <server>
|
||||
#
|
||||
[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
|
||||
|
||||
# For information about the format of this file, refer to the documentation
|
||||
# for sphinx-feature-classification:
|
||||
|
||||
[driver.powervm]
|
||||
title=PowerVM
|
||||
|
||||
[operation.attach-volume]
|
||||
title=Attach block volume to instance
|
||||
|
@ -83,7 +30,7 @@ notes=The attach volume operation provides a means to hotplug
|
|||
is considered to be more of a pet than cattle. Therefore
|
||||
this operation is not considered to be mandatory to support.
|
||||
cli=nova volume-attach <server> <volume>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.attach-tagged-volume]
|
||||
title=Attach tagged block device to instance
|
||||
|
@ -91,14 +38,14 @@ status=optional
|
|||
notes=Attach a block device with a tag to an existing server instance. See
|
||||
"Device tags" for more information.
|
||||
cli=nova volume-attach <server> <volume> [--tag <tag>]
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.detach-volume]
|
||||
title=Detach block volume from instance
|
||||
status=optional
|
||||
notes=See notes for attach volume operation.
|
||||
cli=nova volume-detach <server> <volume>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.extend-volume]
|
||||
title=Extend block volume attached to instance
|
||||
|
@ -112,8 +59,8 @@ notes=The extend volume operation provides a means to extend
|
|||
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=cinder extend <volume> <new_size>
|
||||
driver-impl-powervm=partial
|
||||
driver-notes-powervm=Not supported for rbd volumes.
|
||||
driver.powervm=partial
|
||||
driver-notes.powervm=Not supported for rbd volumes.
|
||||
|
||||
[operation.attach-interface]
|
||||
title=Attach virtual network interface to instance
|
||||
|
@ -126,7 +73,7 @@ notes=The attach interface operation provides a means to hotplug
|
|||
In a cloud model it would be more typical to just spin up a
|
||||
new instance with more interfaces.
|
||||
cli=nova interface-attach <server>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.attach-tagged-interface]
|
||||
title=Attach tagged virtual network interface to instance
|
||||
|
@ -134,14 +81,14 @@ status=optional
|
|||
notes=Attach a virtual network interface with a tag to an existing
|
||||
server instance. See "Device tags" for more information.
|
||||
cli=nova interface-attach <server> [--tag <tag>]
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.detach-interface]
|
||||
title=Detach virtual network interface from instance
|
||||
status=optional
|
||||
notes=See notes for attach-interface operation.
|
||||
cli=nova interface-detach <server> <port_id>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.maintenance-mode]
|
||||
title=Set the host in a maintenance mode
|
||||
|
@ -154,7 +101,7 @@ notes=This operation allows a host to be placed into maintenance
|
|||
The driver methods to implement are "host_maintenance_mode" and
|
||||
"set_host_enabled".
|
||||
cli=nova host-update <host>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.evacuate]
|
||||
title=Evacuate instances from a host
|
||||
|
@ -168,7 +115,7 @@ notes=A possible failure scenario in a cloud environment is the outage
|
|||
dropped. That happens in the same way as a rebuild.
|
||||
This is not considered to be a mandatory operation to support.
|
||||
cli=nova evacuate <server>;nova host-evacuate <host>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.rebuild]
|
||||
title=Rebuild instance
|
||||
|
@ -179,7 +126,7 @@ notes=A possible use case is additional attributes need to be set
|
|||
'personalities'. Though this is not considered to be a mandatory
|
||||
operation to support.
|
||||
cli=nova rebuild <server> <image>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.get-guest-info]
|
||||
title=Guest instance status
|
||||
|
@ -189,7 +136,7 @@ notes=Provides realtime information about the power state of the guest
|
|||
tracking changes in guests, this operation is considered mandatory to
|
||||
support.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.get-host-uptime]
|
||||
title=Guest host uptime
|
||||
|
@ -197,7 +144,7 @@ status=optional
|
|||
notes=Returns the result of host uptime since power on,
|
||||
it's used to report hypervisor status.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.get-host-ip]
|
||||
title=Guest host ip
|
||||
|
@ -205,7 +152,7 @@ status=optional
|
|||
notes=Returns the ip of this host, it's used when doing
|
||||
resize and migration.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.live-migrate]
|
||||
title=Live migrate instance across hosts
|
||||
|
@ -222,7 +169,7 @@ notes=Live migration provides a way to move an instance off one
|
|||
built on the container based virtualization. Therefore this
|
||||
operation is not considered mandatory to support.
|
||||
cli=nova live-migration <server>;nova host-evacuate-live <host>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.force-live-migration-to-complete]
|
||||
title=Force live migration to complete
|
||||
|
@ -238,7 +185,7 @@ notes=Live migration provides a way to move a running instance to another
|
|||
a switch to post-copy mode. Otherwise the instance will be suspended
|
||||
until the migration is completed or aborted.
|
||||
cli=nova live-migration-force-complete <server> <migration>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.launch]
|
||||
title=Launch instance
|
||||
|
@ -247,7 +194,7 @@ 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
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.pause]
|
||||
title=Stop instance CPUs (pause)
|
||||
|
@ -262,7 +209,7 @@ notes=Stopping an instances CPUs can be thought of as roughly
|
|||
implement it. Therefore this operation is considered optional
|
||||
to support in drivers.
|
||||
cli=nova pause <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.reboot]
|
||||
title=Reboot instance
|
||||
|
@ -273,7 +220,7 @@ notes=It is reasonable for a guest OS administrator to trigger a
|
|||
reboot can be achieved by a combination of stop+start. Therefore
|
||||
this operation is considered optional.
|
||||
cli=nova reboot <server>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.rescue]
|
||||
title=Rescue instance
|
||||
|
@ -287,7 +234,7 @@ notes=The rescue operation starts an instance in a special
|
|||
thrown away and a new instance created. Therefore this
|
||||
operation is considered optional to support in drivers.
|
||||
cli=nova rescue <server>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.resize]
|
||||
title=Resize instance
|
||||
|
@ -301,14 +248,14 @@ notes=The resize operation allows the user to change a running
|
|||
running instance. Therefore this operation is considered
|
||||
optional to support in drivers.
|
||||
cli=nova resize <server> <flavor>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.resume]
|
||||
title=Restore instance
|
||||
status=optional
|
||||
notes=See notes for the suspend operation
|
||||
cli=nova resume <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.set-admin-password]
|
||||
title=Set instance admin password
|
||||
|
@ -325,7 +272,7 @@ notes=Provides a mechanism to (re)set the password of the administrator
|
|||
this is just a convenient optimization. Therefore this operation is
|
||||
not considered mandatory for drivers to support.
|
||||
cli=nova set-password <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.snapshot]
|
||||
title=Save snapshot of instance disk
|
||||
|
@ -341,7 +288,7 @@ notes=The snapshot operation allows the current state of the
|
|||
snapshot cannot be assumed. Therefore this operation is not
|
||||
considered mandatory to support.
|
||||
cli=nova image-create <server> <name>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.suspend]
|
||||
title=Suspend instance
|
||||
|
@ -362,7 +309,7 @@ notes=Suspending an instance can be thought of as roughly
|
|||
the instance instead of suspending. Therefore this operation
|
||||
is considered optional to support.
|
||||
cli=nova suspend <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.swap-volume]
|
||||
title=Swap block volumes
|
||||
|
@ -376,7 +323,7 @@ notes=The swap volume operation is a mechanism for changing a running
|
|||
migration to work in the volume service. This is considered optional to
|
||||
support.
|
||||
cli=nova volume-update <server> <attachment> <volume>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.terminate]
|
||||
title=Shutdown instance
|
||||
|
@ -386,7 +333,7 @@ notes=The ability to terminate a virtual machine is required in
|
|||
avoid indefinitely ongoing billing. Therefore this operation
|
||||
is mandatory to support in drivers.
|
||||
cli=nova delete <server>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[operation.trigger-crash-dump]
|
||||
title=Trigger crash dump
|
||||
|
@ -397,14 +344,14 @@ notes=The trigger crash dump operation is a mechanism for triggering
|
|||
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=nova trigger-crash-dump <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.unpause]
|
||||
title=Resume instance CPUs (unpause)
|
||||
status=optional
|
||||
notes=See notes for the "Stop instance CPUs" operation
|
||||
cli=nova unpause <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[guest.disk.autoconfig]
|
||||
title=Auto configure disk
|
||||
|
@ -413,7 +360,7 @@ notes=Partition and resize FS to match the size specified by
|
|||
flavors.root_gb, As this is hypervisor specific feature.
|
||||
Therefore this operation is considered optional to support.
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[guest.disk.rate-limit]
|
||||
title=Instance disk I/O limits
|
||||
|
@ -425,7 +372,7 @@ notes=The ability to set rate limits on virtual disks allows for
|
|||
of doing fine grained tuning. Therefore this is not considered
|
||||
to be an mandatory configuration to support.
|
||||
cli=nova limits
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[guest.setup.configdrive]
|
||||
title=Config drive support
|
||||
|
@ -440,7 +387,7 @@ notes=The config drive provides an information channel into
|
|||
of the guest setup mechanisms is required to be supported by
|
||||
drivers, in order to enable login access.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[guest.setup.inject.file]
|
||||
title=Inject files into disk image
|
||||
|
@ -455,7 +402,7 @@ notes=This allows for the end user to provide data for multiple
|
|||
service or config drive. Therefore this operation is considered
|
||||
optional to support.
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[guest.setup.inject.networking]
|
||||
title=Inject guest networking config
|
||||
|
@ -471,7 +418,7 @@ notes=This allows for static networking configuration (IP
|
|||
config drive. Therefore this operation is considered optional
|
||||
to support.
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[console.rdp]
|
||||
title=Remote desktop over RDP
|
||||
|
@ -485,7 +432,7 @@ notes=This allows the administrator to interact with the graphical
|
|||
mandatory, however, a driver is required to support at least one
|
||||
of the listed console access operations.
|
||||
cli=nova get-rdp-console <server> <console-type>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[console.serial.log]
|
||||
title=View serial console logs
|
||||
|
@ -500,7 +447,7 @@ notes=This allows the administrator to query the logs of data
|
|||
operation is not mandatory, however, a driver is required to
|
||||
support at least one of the listed console access operations.
|
||||
cli=nova console-log <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[console.serial.interactive]
|
||||
title=Remote interactive serial console
|
||||
|
@ -516,7 +463,7 @@ notes=This allows the administrator to interact with the serial
|
|||
This feature was introduced in the Juno release with blueprint
|
||||
https://blueprints.launchpad.net/nova/+spec/serial-ports
|
||||
cli=nova get-serial-console <server>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[console.spice]
|
||||
title=Remote desktop over SPICE
|
||||
|
@ -530,7 +477,7 @@ notes=This allows the administrator to interact with the graphical
|
|||
mandatory, however, a driver is required to support at least one
|
||||
of the listed console access operations.
|
||||
cli=nova get-spice-console <server> <console-type>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[console.vnc]
|
||||
title=Remote desktop over VNC
|
||||
|
@ -544,7 +491,7 @@ notes=This allows the administrator to interact with the graphical
|
|||
mandatory, however, a driver is required to support at least one
|
||||
of the listed console access operations.
|
||||
cli=nova get-vnc-console <server> <console-type>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[storage.block]
|
||||
title=Block storage support
|
||||
|
@ -560,7 +507,7 @@ notes=Block storage provides instances with direct attached
|
|||
the network. Therefore support for this configuration is not
|
||||
considered mandatory for drivers to support.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[storage.block.backend.fibrechannel]
|
||||
title=Block storage over fibre channel
|
||||
|
@ -570,7 +517,7 @@ notes=To maximise performance of the block storage, it may be desirable
|
|||
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
|
||||
driver.powervm=complete
|
||||
|
||||
[storage.block.backend.iscsi]
|
||||
title=Block storage over iSCSI
|
||||
|
@ -583,7 +530,7 @@ notes=If the driver wishes to support block storage, it is common to
|
|||
block storage, then this is considered mandatory to support, otherwise
|
||||
it is considered optional.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[storage.block.backend.iscsi.auth.chap]
|
||||
title=CHAP authentication for iSCSI
|
||||
|
@ -593,7 +540,7 @@ notes=If accessing the cinder iSCSI service over an untrusted LAN it
|
|||
protocol. CHAP is the commonly used authentication protocol for
|
||||
iSCSI. This is not considered mandatory to support. (?)
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[storage.image]
|
||||
title=Image storage support
|
||||
|
@ -605,21 +552,21 @@ notes=This refers to the ability to boot an instance from an image
|
|||
on external PXE servers is out of scope. Therefore this is considered
|
||||
a mandatory storage feature to support.
|
||||
cli=nova boot --image <image> <name>
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[networking.firewallrules]
|
||||
title=Network firewall rules
|
||||
status=optional
|
||||
notes=Unclear how this is different from security groups
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[networking.routing]
|
||||
title=Network routing
|
||||
status=optional
|
||||
notes=Unclear what this refers to
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[networking.securitygroups]
|
||||
title=Network security groups
|
||||
|
@ -632,7 +579,7 @@ notes=The security groups feature provides a way to define rules
|
|||
superfluous requirement. Therefore this is considered to be an
|
||||
optional configuration to support.
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[networking.topology.flat]
|
||||
title=Flat networking
|
||||
|
@ -642,7 +589,7 @@ notes=Provide network connectivity to guests using a
|
|||
of the networking configurations is mandatory to
|
||||
support in the drivers.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.powervm=complete
|
||||
|
||||
[networking.topology.vlan]
|
||||
title=VLAN networking
|
||||
|
@ -651,14 +598,14 @@ notes=Provide network connectivity to guests using VLANs to define the
|
|||
topology when using nova-network. At least one of the networking
|
||||
configurations is mandatory to support in the drivers.
|
||||
cli=
|
||||
driver-impl-powervm=complete
|
||||
driver.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
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.device-tags]
|
||||
title=Device tags
|
||||
|
@ -676,7 +623,7 @@ notes=This allows users to set tags on virtual devices when creating a
|
|||
Instead, device role tags should be used. Device tags can be
|
||||
applied to virtual network interfaces and block devices.
|
||||
cli=nova boot
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.quiesce]
|
||||
title=quiesce
|
||||
|
@ -685,14 +632,14 @@ notes=Quiesce the specified instance to prepare for snapshots.
|
|||
For libvirt, guest filesystems will be frozen through qemu
|
||||
agent.
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.unquiesce]
|
||||
title=unquiesce
|
||||
status=optional
|
||||
notes=See notes for the quiesce operation
|
||||
cli=
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
||||
[operation.multiattach-volume]
|
||||
title=Attach block volume to multiple instances
|
||||
|
@ -704,4 +651,4 @@ notes=The multiattach volume operation is an extension to
|
|||
Note that for the libvirt driver, this is only supported
|
||||
if qemu<2.10 or libvirt>=3.10.
|
||||
cli=nova volume-attach <server> <volume>
|
||||
driver-impl-powervm=missing
|
||||
driver.powervm=missing
|
||||
|
|
Loading…
Reference in New Issue