Add standard constants for CPU architectures

Introduce a nova/compute/arch.py module to serve a similar role
to nova/compute/vmmode.py, by providing constants for known
CPU architectures and validation/canonicalization APIs

Related-bug: #1348624
Change-Id: Idd4907b5488dd0832c15783d87d57d77ae654519
This commit is contained in:
Daniel P. Berrange 2014-07-14 14:25:14 +01:00
parent 7d1af66a70
commit e780b10189
3 changed files with 215 additions and 0 deletions

155
nova/compute/arch.py Normal file
View File

@ -0,0 +1,155 @@
# Copyright 2014 Red Hat, Inc.
# All Rights Reserved.
#
# 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.
"""Constants and helper APIs for dealing with CPU architectures
The constants provide the standard names for all known processor
architectures. Many have multiple variants to deal with big-endian
vs little-endian modes, as well as 32 vs 64 bit word sizes. These
names are chosen to be identical to the architecture names expected
by libvirt, so if ever adding new ones, ensure it matches libvirt's
expectation.
"""
import os
from nova import exception
ALPHA = "alpha"
ARMV6 = "armv6"
ARMV7 = "armv7l"
ARMV7B = "armv7b"
AARCH64 = "aarch64"
CRIS = "cris"
I686 = "i686"
IA64 = "ia64"
LM32 = "lm32"
M68K = "m68k"
MICROBLAZE = "microblaze"
MICROBLAZEEL = "microblazeel"
MIPS = "mips"
MIPSEL = "mipsel"
MIPS64 = "mips64"
MIPS64EL = "mips64el"
OPENRISC = "openrisc"
PARISC = "parisc"
PARISC64 = "parisc64"
PPC = "ppc"
PPCLE = "ppcle"
PPC64 = "ppc64"
PPC64LE = "ppc64le"
PPCEMB = "ppcemb"
S390 = "s390"
S390X = "s390x"
SH4 = "sh4"
SH4EB = "sh4eb"
SPARC = "sparc"
SPARC64 = "sparc64"
UNICORE32 = "unicore32"
X86_64 = "x86_64"
XTENSA = "xtensa"
XTENSAEB = "xtensaeb"
ALL = [
ALPHA,
ARMV6,
ARMV7,
ARMV7B,
AARCH64,
CRIS,
I686,
IA64,
LM32,
M68K,
MICROBLAZE,
MICROBLAZEEL,
MIPS,
MIPSEL,
MIPS64,
MIPS64EL,
OPENRISC,
PARISC,
PARISC64,
PPC,
PPCLE,
PPC64,
PPC64LE,
PPCEMB,
S390,
S390X,
SH4,
SH4EB,
SPARC,
SPARC64,
UNICORE32,
X86_64,
XTENSA,
XTENSAEB,
]
def from_host():
"""Get the architecture of the host OS
:returns: the canonicalized host architecture
"""
return canonicalize(os.uname()[4])
def is_valid(name):
"""Check if a string is a valid architecture
:param name: architecture name to validate
:returns: True if @name is valid
"""
return name in ALL
def canonicalize(name):
"""Canonicalize the architecture name
:param name: architecture name to canonicalize
:returns: a canonical architecture name
"""
if name is None:
return None
newname = name.lower()
if newname in ("i386", "i486", "i586"):
newname = I686
if not is_valid(newname):
raise exception.InvalidArchitectureName(arch=name)
return newname

View File

@ -1618,3 +1618,7 @@ class ImageVCPUTopologyRangeExceeded(Invalid):
class ImageVCPULimitsRangeImpossible(Invalid):
msg_fmt = _("Requested vCPU limits %(sockets)d:%(cores)d:%(threads)d "
"are impossible to satisfy for vcpus count %(vcpus)d")
class InvalidArchitectureName(Invalid):
msg_fmt = _("Architecture name '%(arch)s' is not recognised")

View File

@ -0,0 +1,56 @@
# 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.
import os
import mock
from nova.compute import arch
from nova import exception
from nova import test
class ArchTest(test.NoDBTestCase):
@mock.patch.object(os, "uname")
def test_host(self, mock_uname):
os.uname.return_value = (
'Linux',
'localhost.localdomain',
'3.14.8-200.fc20.x86_64',
'#1 SMP Mon Jun 16 21:57:53 UTC 2014',
'i686'
)
self.assertEqual(arch.I686, arch.from_host())
def test_valid_string(self):
self.assertTrue(arch.is_valid("x86_64"))
def test_valid_constant(self):
self.assertTrue(arch.is_valid(arch.X86_64))
def test_valid_bogus(self):
self.assertFalse(arch.is_valid("x86_64wibble"))
def test_canonicalize_i386(self):
self.assertEqual(arch.I686, arch.canonicalize("i386"))
def test_canonicalize_case(self):
self.assertEqual(arch.X86_64, arch.canonicalize("X86_64"))
def test_canonicalize_bogus(self):
self.assertRaises(exception.InvalidArchitectureName,
arch.canonicalize,
"x86_64wibble")