1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# Copyright 2015 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.
from oslo_log import log as logging
from oslo_utils import importutils
from nova import exception
from nova.objects import fields
libosinfo = None
LOG = logging.getLogger(__name__)
# TODO(vladikr) The current implementation will serve only as a temporary
# solution, due to it's dependency on the libosinfo gobject library.
# In the future it will be replaced by a pure python library or by a direct
# parsing of the libosinfo XML files. However, it will be possible only when
# libosinfo project will declare the XML structure to be a stable ABI.
class _OsInfoDatabase(object):
_instance = None
def __init__(self):
global libosinfo
try:
if libosinfo is None:
libosinfo = importutils.import_module(
'gi.repository.Libosinfo')
except ImportError as exp:
LOG.info("Cannot load Libosinfo: (%s)", exp)
else:
self.loader = libosinfo.Loader()
self.loader.process_default_path()
self.db = self.loader.get_db()
self.oslist = self.db.get_os_list()
@classmethod
def get_instance(cls):
"""Get libosinfo connection
"""
if cls._instance is None:
cls._instance = _OsInfoDatabase()
return cls._instance
def get_os(self, os_name):
"""Retrieve OS object based on id, unique URI identifier of the OS
:param os_name: id - the unique operating systemidentifier
e.g. http://fedoraproject.org/fedora/21,
http://microsoft.com/win/xp,
or a
short-id - the short name of the OS
e.g. fedora21, winxp
:returns: The operation system object Libosinfo.Os
:raise exception.OsInfoNotFound: If os hasn't been found
"""
if libosinfo is None:
return
if not os_name:
raise exception.OsInfoNotFound(os_name='Empty')
fltr = libosinfo.Filter.new()
flt_field = 'id' if os_name.startswith('http') else 'short-id'
fltr.add_constraint(flt_field, os_name)
filtered = self.oslist.new_filtered(fltr)
list_len = filtered.get_length()
if not list_len:
raise exception.OsInfoNotFound(os_name=os_name)
return filtered.get_nth(0)
class OsInfo(object):
"""OS Information Structure
"""
def __init__(self, os_name):
self._os_obj = self._get_os_obj(os_name)
def _get_os_obj(self, os_name):
if os_name is not None:
try:
return _OsInfoDatabase.get_instance().get_os(os_name)
except exception.NovaException as e:
LOG.warning("Cannot find OS information - Reason: (%s)", e)
@property
def network_model(self):
if self._os_obj is not None:
fltr = libosinfo.Filter()
fltr.add_constraint("class", "net")
devs = self._os_obj.get_all_devices(fltr)
if devs.get_length():
net_model = devs.get_nth(0).get_name()
# convert to valid libvirt values
if net_model in ['virtio-net', 'virtio1.0-net']:
return 'virtio'
# ignore any invalid ones
if net_model in fields.VIFModel.ALL:
return net_model
@property
def disk_model(self):
if self._os_obj is not None:
fltr = libosinfo.Filter()
fltr.add_constraint("class", "block")
devs = self._os_obj.get_all_devices(fltr)
if devs.get_length():
disk_model = devs.get_nth(0).get_name()
# convert to valid libvirt values
if disk_model in ['virtio-block', 'virtio1.0-block']:
return 'virtio'
# ignore any invalid ones
if disk_model in fields.DiskBus.ALL:
return disk_model
class HardwareProperties(object):
def __init__(self, image_meta):
""":param image_meta: ImageMeta object
"""
self.img_props = image_meta.properties
os_key = self.img_props.get('os_distro')
self.os_info_obj = OsInfo(os_key)
@property
def network_model(self):
return self.img_props.get('hw_vif_model',
self.os_info_obj.network_model)
@property
def disk_model(self):
return self.img_props.get('hw_disk_bus',
self.os_info_obj.disk_model)
|