Fwd: Re: [PATCH] Dbginfo report generation
by Megha Smriti
-------- Forwarded Message --------
Subject: Re: [PATCH] Dbginfo report generation
Date: Wed, 25 Nov 2015 11:27:20 +0530
From: Megha Smriti <mesmriti(a)linux.vnet.ibm.com>
To: Aline Manera <alinefm(a)linux.vnet.ibm.com>
Hi Aline,
Please find my comments inline and few suggestions.
Thanks & Regards,
Megha Smriti
On 17/11/2015 20:05, mesmriti(a)linux.vnet.ibm.com wrote:
> From: root <root(a)localhost.localdomain>
>
> Signed-off-by: root <root(a)localhost.localdomain>
> ---
> src/wok/plugins/gingerbase/i18n.py | 4 +-
> src/wok/plugins/gingerbase/model/debugreports.py | 212
> ++++++++++++++++++-----
> 2 files changed, 167 insertions(+), 49 deletions(-)
>
> diff --git a/src/wok/plugins/gingerbase/i18n.py
> b/src/wok/plugins/gingerbase/i18n.py
> index af75c70..6ff783b 100644
> --- a/src/wok/plugins/gingerbase/i18n.py
> +++ b/src/wok/plugins/gingerbase/i18n.py
> @@ -36,7 +36,9 @@ messages = {
> "GGBDR0007E": _("Debug report name must be a string. Only
> letters, digits, underscore ('_') and "
> "hyphen ('-') are allowed."),
> "GGBDR0008E": _("The debug report with specified name
> \"%(name)s\" already exists. Please use another one."),
> -
> + "GGBDR0009E": _("Unable to create dbginfo report with
> %(retcode)s. Details: %(err)s"),
> + "GGBDR0010E": _("Unable to compress the final debug report tar
> file with %(retcode)s. Details: %(error)s"),
> + "GGBDR0011E": _("Unable to generate final debug report %(name)s.
> Details: %(err)s"),
> "GGBHOST0001E": _("Unable to shutdown host machine as there are
> running virtual machines"),
> "GGBHOST0002E": _("Unable to reboot host machine as there are
> running virtual machines"),
> "GGBHOST0003E": _("There may be virtual machines running on the
> host"),
> diff --git a/src/wok/plugins/gingerbase/model/debugreports.py
> b/src/wok/plugins/gingerbase/model/debugreports.py
> index 94ab7fe..927e173 100644
> --- a/src/wok/plugins/gingerbase/model/debugreports.py
> +++ b/src/wok/plugins/gingerbase/model/debugreports.py
> @@ -19,13 +19,14 @@
> # License along with this library; if not, write to the Free Software
> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
>
> -import fnmatch
> import glob
> import logging
> import os
> import shutil
> import subprocess
> import time
> +import platform
> +import re
>
> from wok.exception import InvalidParameter, NotFoundError,
> OperationFailed
> from wok.exception import WokException
> @@ -71,54 +72,109 @@ class DebugReportsModel(object):
> raise OperationFailed("GGBDR0002E")
>
> @staticmethod
> - def sosreport_generate(cb, name):
> + def debugreport_generate(cb, name):
> def log_error(e):
> log = logging.getLogger('Model')
> log.warning('Exception in generating debug file: %s', e)
I know it is already there prior to your patch, but we should use
wok_log to log the errors.
This special wrapper can be removed.
I will incorporate this in my next patch
> try:
> - command = ['sosreport', '--batch', '--name=%s' % name]
> - output, error, retcode = run_command(command)
> -
> - if retcode != 0:
> - raise OperationFailed("GGBDR0003E", {'name': name,
> - 'err': retcode})
> -
> - # SOSREPORT might create file in /tmp or /var/tmp
> - # FIXME: The right way should be passing the tar.xz file
> directory
> - # though the parameter '--tmp-dir', but it is failing in
> Fedora 20
> - patterns = ['/tmp/sosreport-%s-*',
> '/var/tmp/sosreport-%s-*']
> - reports = []
> - reportFile = None
> - for p in patterns:
> - reports = reports + [f for f in glob.glob(p % name)]
> - for f in reports:
> - if not fnmatch.fnmatch(f, '*.md5'):
> - reportFile = f
> - break
> - # Some error in sosreport happened
> - if reportFile is None:
> - wok_log.error('Debug report file not found. See
> sosreport '
> - 'output for detail:\n%s', output)
> - fname = (patterns[0] % name).split('/')[-1]
> - raise OperationFailed('GGBDR0004E', {'name': fname})
> -
> - md5_report_file = reportFile + '.md5'
> - report_file_extension = '.' + reportFile.split('.', 1)[1]
> + # Sosreport generation
> + sosreport_file = sosreport_collection(name)
> + md5_report_file = sosreport_file + '.md5'
> + report_file_extension = '.' + sosreport_file.split('.',
> 1)[1]
> + # If the platform is a system Z machine.
> + if platform.machine().startswith('s390'):
The debugreport_generate() function will be called only if the system
has the dbginfo command
So you don't need to rely in the system arch to decide on that.
So the 'if' statement above can be safely removed.
Will take care of this in my next patch.
> + path_debugreport = '/var/tmp/'
> + dbgreport_regex = '(\S+\s+)(' + path_debugreport + \
> + 'DBGINFO-[\d+]{4}-[\d+]{2}' \
> + '-[\d+]{2}-[\d+]{2}-[\d+]{2}' \
> + '-[\d+]{2}-\w+-\d+\S+)(\s+\S+)'
> + command = ['/usr/sbin/dbginfo.sh', '-d',
> path_debugreport]
> + output, error, retcode = run_command(command)
> + if retcode != 0:
> + raise OperationFailed("GGBDR0009E",
> + {'retcode': retcode, 'err':
> error})
> + output = output.splitlines()
> + dbginfo_report = None
> + for line in output:
> + line = line.strip()
> + n = re.match(dbgreport_regex, line)
> + if n:
> + dbginfo_report = n.groups()[1]
> + break
> + final_tar_report_name = name + report_file_extension
> + if dbginfo_report is not None:
> + sosreport_tar = sosreport_file.split('/', 3)[3]
> + dbginfo_tar = dbginfo_report.split('/', 3)[3]
> + msg = 'Compressing the sosreport and debug info
> files into ' \
> + 'final report file'
> + wok_log.info(msg)
> + # Compressing the sosreport and dbginfo reports
> into one
> + # tar file
> + command = ['tar', '-cvzf', '%s' %
> final_tar_report_name,
> + '-C', path_debugreport, dbginfo_tar,
> + sosreport_tar]
You can use final_tar_report_name with the right debug report location
to avoid need to move the file after that.
Instead of the direct location compressing it would be good to do in
var/tmp and then moving it to target directory
rather trying to do any operation on the target directory. In some
cases if developer
makes a mistake it is possible that previous reports might get deleted
. Please correct me if any other suggestions.
> + output, error, retcode = run_command(command)
> + if retcode != 0:
> + raise OperationFailed("GGBDR0010E",
> + {'retcode': retcode,
> + 'error': error})
> + path = config.get_debugreports_path()
> + dbg_target = os.path.join(path,
> + name +
> report_file_extension)
Use the dbg_target value while running the 'tar' command above. So we
don't need to move the file.
Same as my comment above.
> + # Moving final tar file to debugreports path
> + msg = 'Moving final debug report file "%s" to
> "%s"' % \
> + (final_tar_report_name, dbg_target)
> + wok_log.info(msg)
> + shutil.move(final_tar_report_name, dbg_target)
The above block can be removed.
> + # Deleting the sosreport md5 file
> + delete_the_sosreport_md5_file(md5_report_file)
> + # Deleting the dbingo report file
> + msg = 'Deleting the dbginfo file "%s" ' \
> + % dbginfo_report
> + wok_log.info(msg)
> + os.remove(dbginfo_report)
> + # Deleting the sosreport file
> + msg = 'Deleting the sosreport file "%s" ' %
> sosreport_file
> + wok_log.info(msg)
> + os.remove(sosreport_file)
> + wok_log.info('The debug report file has been moved')
> + cb('OK', True)
> + return
> +
> + except WokException as e:
> + log_error(e)
> + raise
> +
> + except OSError as e:
> + log_error(e)
> + raise
> +
> + except Exception, e:
> + # No need to call cb to update the task status here.
> + # The task object will catch the exception raised here
> + # and update the task status there
> + log_error(e)
> + raise OperationFailed("GGBDR0011E", {'name': name, 'err':
> e})
> +
> + @staticmethod
> + def sosreport_generate(cb, name):
> + def log_error(e):
> + log = logging.getLogger('Model')
> + log.warning('Exception in generating debug file: %s', e)
The same I commented before. We can use wok_log to log the errors.
I will incorporate this in my next patch
> + try:
> + # Sosreport collection
> + sosreport_file = sosreport_collection(name)
> + md5_report_file = sosreport_file + '.md5'
> + report_file_extension = '.' + sosreport_file.split('.',
> 1)[1]
> path = config.get_debugreports_path()
> - target = os.path.join(path, name + report_file_extension)
> - # Moving report
> - msg = 'Moving debug report file "%s" to "%s"' % (reportFile,
> - target)
> + sosreport_target = os.path.join(path,
> + name +
> report_file_extension)
> + msg = 'Moving debug report file "%s" to "%s"' \
> + % (sosreport_file, sosreport_target)
> wok_log.info(msg)
> - shutil.move(reportFile, target)
> - # Deleting md5
> - msg = 'Deleting report md5 file: "%s"' % (md5_report_file)
> - wok_log.info(msg)
> - with open(md5_report_file) as f:
> - md5 = f.read().strip()
> - wok_log.info('Md5 file content: "%s"', md5)
> - os.remove(md5_report_file)
> + shutil.move(sosreport_file, sosreport_target)
As we are using --tmp-dir option, we know exactly where the sosreport
will be saved. So we don't need to move the file around.
When the sosreport is generated md5 file is generated along with the
sosreport. That is why we generate the sosreport
in a var/tmp dir and remove the md5 file and then move the final
file to the target location to avoid doing all the operations
on the target directory.
> + delete_the_sosreport_md5_file(md5_report_file)
> cb('OK', True)
> return
>
> @@ -142,17 +198,27 @@ class DebugReportsModel(object):
> # Please add new possible debug report command here
> # and implement the report generating function
> # based on the new report command
> - report_tools = ({'cmd': 'sosreport --help',
> + report_tools = ({'cmd': '/usr/sbin/dbginfo.sh --help',
> + 'fn': DebugReportsModel.debugreport_generate},
> + {'cmd': 'sosreport --help',
> 'fn': DebugReportsModel.sosreport_generate},)
>
> # check if the command can be found by shell one by one
> for helper_tool in report_tools:
> try:
> - retcode = subprocess.call(helper_tool['cmd'],
> shell=True,
> - stdout=subprocess.PIPE,
> - stderr=subprocess.PIPE)
> - if retcode == 0:
> - return helper_tool['fn']
> + if 'cmd' == '/usr/sbin/dbginfo.sh --help':
> + retcode = subprocess.call(helper_tool['cmd'],
> shell=True,
> + stdout=subprocess.PIPE,
> + stderr=subprocess.PIPE)
> + if retcode == 0:
> + return helper_tool['fn']
You don't need to a special condition to cover the dbginfo command. The
former code already does that.
I ll make the changes.
> + else:
> +
> + retcode = subprocess.call(helper_tool['cmd'],
> shell=True,
> + stdout=subprocess.PIPE,
> + stderr=subprocess.PIPE)
> + if retcode == 0:
> + return helper_tool['fn']
> except Exception, e:
> wok_log.info('Exception running command: %s', e)
>
> @@ -213,3 +279,53 @@ class DebugReportContentModel(object):
>
> def lookup(self, name):
> return self._debugreport.lookup(name)
> +
> +
> +def delete_the_sosreport_md5_file(md5_file):
> + """
> + Deleting md5 file and displaying the contents of the same.
> + """
> + msg = 'Deleting report md5 file: "%s"' % md5_file
> + wok_log.info(msg)
> + with open(md5_file) as f:
> + md5 = f.read().strip()
> + wok_log.info('Md5 file content: "%s"', md5)
> + os.remove(md5_file)
> +
> +
> +def sosreport_collection(name):
> + """
> + Code for the collection of sosreport n the path
> + /var/tmp as specified in the command.
> + """
> + path_sosreport = '/var/tmp/'
> + command = ['sosreport', '--batch', '--name=%s' % name,
> + '--tmp-dir=%s' % path_sosreport]
> + output, error, retcode = run_command(command)
> + if retcode != 0:
> + raise OperationFailed("GGBDR0003E", {'name': name,
> + 'err': retcode})
> +
> + # SOSREPORT might create file in /tmp or /var/tmp
> + # FIXME: The right way should be passing the tar.xz file directory
> + # though the parameter '--tmp-dir', but it is failing in Fedora 20
You can remove this comment.
> + sosreport_name = name.replace('_', '')
The same I commented before. We should not change the user input without
informing user about it.
So it is better to block underscore in the debug report name. Please,
update API.json accordingly.
I ll make the required changes.
> + sosreport_name_regex = '(\s+)(' + path_sosreport + \
> + ')(sosreport-' +\
> + sosreport_name + '-\d+.tar.xz)'
> + sosreport_file = None
> + output = output.splitlines()
> + for line in output:
> + if line:
> + matched_name = re.match(sosreport_name_regex, line)
> + if matched_name:
> + path = matched_name.groups()[1]
> + fname = matched_name.groups()[2]
> + sosreport_file = path + fname
While using --tmp-dir you know exactly where the sosreport file will be:
<tmp-dir>-sosreport-<name>.tar.gz
So you can need to parse the command output.
I will take care of this in the next patch.
> + break
> + # Some error in sosreport happened
> + if sosreport_file is None:
> + wok_log.error('Debug report file not found. See sosreport '
> + 'output for detail:\n%s', output)
> + raise OperationFailed('GGBDR0004E', {'name': name})
> + return sosreport_file
9 years, 1 month
[PATCH] Fix ISO error messages
by Ramon Medeiros
Make distinct "no ISO found" and "invalid iso format".
Signed-off-by: Ramon Medeiros <ramonn(a)linux.vnet.ibm.com>
---
src/wok/plugins/kimchi/vmtemplate.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/wok/plugins/kimchi/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
index 283d94d..0c35611 100644
--- a/src/wok/plugins/kimchi/vmtemplate.py
+++ b/src/wok/plugins/kimchi/vmtemplate.py
@@ -130,11 +130,15 @@ class VMTemplate(object):
iso_prefixes = ['/', 'http', 'https', 'ftp', 'ftps', 'tftp']
if len(filter(iso.startswith, iso_prefixes)) == 0:
raise InvalidParameter("KCHTMPL0006E", {'param': iso})
+ else:
+ if not os.path.exists(iso):
+ raise InvalidParameter("KCHISO0001E", {'filename': iso})
+
try:
iso_img = IsoImage(iso)
return iso_img.probe()
except IsoFormatError:
- raise InvalidParameter("KCHISO0001E", {'filename': iso})
+ raise InvalidParameter("KCHISO0007E", {'filename': iso})
def _get_cdrom_xml(self, libvirt_stream_protocols):
if 'cdrom' not in self.info:
--
2.1.0
9 years, 1 month
[PATCH 0/3] Fix UI code errors and messages
by Ramon Medeiros
Ramon Medeiros (3):
Remove unused messages in Kimchi UI
Fix WOK UI error messages
Add checking for UI codes when running make check-local
Makefile.am | 1 +
check_ui_code_errors.sh | 11 ++
src/wok/plugins/kimchi/Makefile.am | 2 +-
src/wok/plugins/kimchi/check_ui_code_errors.sh | 11 ++
src/wok/plugins/kimchi/model/vms.py | 6 +-
src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl | 81 ------------
ui/js/src/wok.confirm.js | 4 +-
ui/js/src/wok.grid.js | 10 +-
ui/js/src/wok.line-chart.js | 2 +-
ui/js/src/wok.list.js | 10 +-
ui/js/src/wok.main.js | 2 +-
ui/js/widgets/filter-select.js | 4 +-
ui/pages/i18n.json.tmpl | 168 ++-----------------------
13 files changed, 52 insertions(+), 260 deletions(-)
create mode 100755 check_ui_code_errors.sh
create mode 100755 src/wok/plugins/kimchi/check_ui_code_errors.sh
--
2.1.0
9 years, 1 month
[PATCH 0/2] Add support to update guest maxMemory {backend}
by Rodrigo Trujillo
V1:
In order to test, you can run something like this command:
curl -k -u <U>:<PW> -H "Content-Type: application/json" -H "Accept: application/json"
"<HOST>/plugins/kimchi/vms/<VM>" -X PUT -d '{"maxmemory": 3072}'
Rodrigo Trujillo (2):
Implement support to change guest maxMemory tag
Add and fixes tests for maxMemory tag
src/wok/plugins/kimchi/API.json | 6 ++
src/wok/plugins/kimchi/i18n.py | 6 +-
src/wok/plugins/kimchi/model/vms.py | 119 +++++++++++++++++-------------
src/wok/plugins/kimchi/tests/test_rest.py | 23 ++++++
4 files changed, 101 insertions(+), 53 deletions(-)
--
2.1.0
9 years, 1 month
[PATCH] [new-ui] Edit Guests
by sguimaraes943@gmail.com
From: samhenri <samuel.guimaraes(a)eldorado.org.br>
New-UI added to Edit Guest modal window.
This patch includes guest IP address from previous patches (added enough space for IPV6 addresses).
Includes some minor fixes such as:
*Added doctype to wok-ui.html.tmpl
*Fixed Edit Templates modal window in Firefox
*Some minor fixes to wok.message instances showing behind modal windows
samhenri (1):
[new-ui] Edit Guests modal window
.../kimchi/ui/css/theme-default/guest-edit.css | 420 ----------------
.../ui/css/theme-default/guest-storage-add.css | 81 ---
src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 6 +-
.../kimchi/ui/js/src/kimchi.guest_edit_main.js | 550 +++++++++++----------
.../ui/js/src/kimchi.guest_storage_add.main.js | 39 +-
.../plugins/kimchi/ui/pages/guest-edit.html.tmpl | 257 +++++-----
.../kimchi/ui/pages/guest-storage-add.html.tmpl | 99 ++--
ui/css/src/modules/_edit-guests.scss | 362 ++++++++++++++
ui/css/src/modules/_modal-flat.scss | 19 +-
ui/css/src/modules/_templates.scss | 16 +-
ui/css/src/wok.scss | 2 +
ui/pages/wok-ui.html.tmpl | 1 +
12 files changed, 873 insertions(+), 979 deletions(-)
delete mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
delete mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
create mode 100644 ui/css/src/modules/_edit-guests.scss
--
1.9.3
9 years, 1 month
[PATCH] [new-ui] Edit Guests v2
by sguimaraes943@gmail.com
From: samhenri <samuel.guimaraes(a)eldorado.org.br>
New-UI added to Edit Guest modal window.
This patch includes guest IP address from previous patches (added enough space for IPV6 addresses).
Includes some minor fixes such as:
*Added doctype to wok-ui.html.tmpl
*Fixed Edit Templates modal window in Firefox
*Some minor fixes to wok.message instances showing behind modal windows
V2
*Fixed new navigation bar to work with HTML5 strict mode. (markup was camelcase, CSS in lowercase)
*Other minor CSS issues with Storages and Network
samhenri (1):
[new-ui] Edit Guests modal window
.../kimchi/ui/css/theme-default/guest-edit.css | 420 ----------------
.../ui/css/theme-default/guest-storage-add.css | 81 ---
src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 6 +-
.../kimchi/ui/js/src/kimchi.guest_edit_main.js | 550 +++++++++++----------
.../ui/js/src/kimchi.guest_storage_add.main.js | 39 +-
.../plugins/kimchi/ui/pages/guest-edit.html.tmpl | 257 +++++-----
.../kimchi/ui/pages/guest-storage-add.html.tmpl | 99 ++--
ui/css/src/modules/_edit-guests.scss | 362 ++++++++++++++
ui/css/src/modules/_modal-flat.scss | 19 +-
ui/css/src/modules/_network.scss | 1 -
ui/css/src/modules/_storage.scss | 2 -
ui/css/src/modules/_templates.scss | 16 +-
ui/css/src/modules/_toolbar.scss | 46 +-
ui/css/src/wok.scss | 2 +
ui/js/src/wok.main.js | 13 +-
ui/pages/wok-ui.html.tmpl | 1 +
16 files changed, 897 insertions(+), 1017 deletions(-)
delete mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
delete mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
create mode 100644 ui/css/src/modules/_edit-guests.scss
--
1.9.3
9 years, 1 month
[RFC] Add disk type checking while creating template
by Ramon Medeiros
At template creation, add a checking to verify if the ISO or the disk
match the correct format, to avoid mistake like creating a disk template
with ISO.
Doubts:
Which disk types we are going to support? (raw, qcow2)?
There is only one type of ISO supported? (ISO 9600) ?
Thanks
--
Ramon Nunes Medeiros
Kimchi Developer
Linux Technology Center Brazil
IBM Systems & Technology Group
Phone : +55 19 2132 7878
ramonn(a)br.ibm.com
9 years, 1 month
[PATCH V3] Add OVS bridges recognition support
by Lucio Correia
Allow bridged networks to be created from OVS bridges, and
adapt VM XML to work with OVS networks.
In some distributions, i.e. Fedora, the directories "bridge"
and "brif" are not created for OVS bridges, and they are the
method Kimchi uses to detect bridges. This patch also fixes
that by recognizing OVS bridges through OVS commands,
allowing networks to be created using OVS bridges in those
distributions.
Signed-off-by: Lucio Correia <luciojhc(a)linux.vnet.ibm.com>
This patch depends on [PATCH V4] Support Linux Bridge creation.
Changes in V3:
- Added error KCHNET0026E
---
src/wok/plugins/kimchi/i18n.py | 1 +
src/wok/plugins/kimchi/model/networks.py | 8 +++++
src/wok/plugins/kimchi/netinfo.py | 53 ++++++++++++++++++++++++++++--
src/wok/plugins/kimchi/xmlutils/network.py | 5 +++
4 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/src/wok/plugins/kimchi/i18n.py b/src/wok/plugins/kimchi/i18n.py
index a72f1ee..de7962a 100644
--- a/src/wok/plugins/kimchi/i18n.py
+++ b/src/wok/plugins/kimchi/i18n.py
@@ -270,6 +270,7 @@ messages = {
"KCHNET0023E": _("Unable to get XML definition for interface %(name)s. Details: %(err)s"),
"KCHNET0024E": _("Unable to redefine interface %(name)s. Details: %(err)s"),
"KCHNET0025E": _("Unable to create bridge %(name)s. Details: %(err)s"),
+ "KCHNET0026E": _("Open VSwitch bridges can only host bridged networks."),
"KCHSR0001E": _("Storage server %(server)s was not used by Kimchi"),
diff --git a/src/wok/plugins/kimchi/model/networks.py b/src/wok/plugins/kimchi/model/networks.py
index 89c8c3a..3e75d7f 100644
--- a/src/wok/plugins/kimchi/model/networks.py
+++ b/src/wok/plugins/kimchi/model/networks.py
@@ -178,9 +178,17 @@ class NetworksModel(object):
# User specified bridge interface, simply use it
self._ensure_iface_up(iface)
+ params['ovs'] = False
if netinfo.is_bridge(iface):
params['bridge'] = iface
+ if netinfo.is_ovs_bridge(iface):
+ params['ovs'] = True
+
+ # OVS bridges don't work with macvtap
+ if params['connection'] != "bridge":
+ raise InvalidParameter('KCHNET0026E')
+
# User wants Linux bridge network, but didn't specify bridge interface
elif params['connection'] == "bridge":
# create Linux bridge interface first and use it as actual iface
diff --git a/src/wok/plugins/kimchi/netinfo.py b/src/wok/plugins/kimchi/netinfo.py
index c5746d7..ff91489 100644
--- a/src/wok/plugins/kimchi/netinfo.py
+++ b/src/wok/plugins/kimchi/netinfo.py
@@ -21,6 +21,9 @@ import ethtool
import glob
import os
+from distutils.spawn import find_executable
+from wok.utils import run_command
+from wok.utils import wok_log
NET_PATH = '/sys/class/net'
NIC_PATH = '/sys/class/net/*/device'
@@ -73,13 +76,51 @@ def is_vlan(iface):
def bridges():
- return [b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)]
+ return list(set([b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)] +
+ ovs_bridges()))
def is_bridge(iface):
return iface in bridges()
+# In some distributions, like Fedora, the files bridge and brif are not created
+# under /sys/class/net/<ovsbridge> for OVS bridges. These specific functions
+# allows one to differentiate OVS bridges from other types of bridges.
+def ovs_bridges():
+ ovs_cmd = find_executable("ovs-vsctl")
+
+ # openvswitch not installed: there is no OVS bridge configured
+ if ovs_cmd is None:
+ return []
+
+ out, error, rc = run_command([ovs_cmd, '--oneline', 'list-br'])
+ if rc != 0:
+ wok_log.info("Error listing OVS bridges")
+ return []
+
+ return list(set(out.split('\n')) - set(['']))
+
+
+def is_ovs_bridge(iface):
+ return iface in ovs_bridges()
+
+
+def ovs_bridge_ports(ovsbr):
+ ovs_cmd = find_executable("ovs-vsctl")
+
+ # openvswitch not installed: there is no OVS bridge configured
+ if ovs_cmd is None:
+ return []
+
+ out, error, rc = run_command([ovs_cmd, '--oneline', 'list-ports', ovsbr])
+ if rc != 0:
+ wok_log.info("Error listing OVS bridge ports for %s" % str(ovsbr))
+ return []
+
+ return list(set(out.split('\n')) - set(['']))
+
+
def all_interfaces():
return [d.rsplit("/", 1)[-1] for d in glob.glob(NET_PATH + '/*')]
@@ -91,11 +132,19 @@ def slaves(bonding):
def ports(bridge):
+ if bridge in ovs_bridges():
+ return ovs_bridge_ports(bridge)
+
return os.listdir(BRIDGE_PORTS % bridge)
def is_brport(nic):
- return os.path.exists(NET_BRPORT % nic)
+ ovs_brports = []
+
+ for ovsbr in ovs_bridges():
+ ovs_brports += ovs_bridge_ports(ovsbr)
+
+ return os.path.exists(NET_BRPORT % nic) or nic in ovs_brports
def is_bondlave(nic):
diff --git a/src/wok/plugins/kimchi/xmlutils/network.py b/src/wok/plugins/kimchi/xmlutils/network.py
index 14c7e13..f9594e6 100644
--- a/src/wok/plugins/kimchi/xmlutils/network.py
+++ b/src/wok/plugins/kimchi/xmlutils/network.py
@@ -95,6 +95,11 @@ def to_network_xml(**kwargs):
if bridge:
network.append(E.bridge(name=bridge))
+ # Add virtualport element for openvswitch bridges
+ ovs = kwargs.get('ovs')
+ if ovs:
+ network.append(E.virtualport(type='openvswitch'))
+
# None means is Isolated network, {} means default mode nat
params = kwargs.get('forward', {"mode": None})
forward = _get_forward_elem(**params)
--
1.9.1
9 years, 1 month
[PATCH] Add support for serial console
by Ramon Medeiros
Automatically create serial console device.
Signed-off-by: Ramon Medeiros <ramonn(a)linux.vnet.ibm.com>
---
src/wok/plugins/kimchi/vmtemplate.py | 7 +++++-
src/wok/plugins/kimchi/xmlutils/serial.py | 40 +++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
create mode 100644 src/wok/plugins/kimchi/xmlutils/serial.py
diff --git a/src/wok/plugins/kimchi/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
index 283d94d..d8f2f7f 100644
--- a/src/wok/plugins/kimchi/vmtemplate.py
+++ b/src/wok/plugins/kimchi/vmtemplate.py
@@ -37,7 +37,7 @@ from wok.plugins.kimchi.xmlutils.disk import get_disk_xml
from wok.plugins.kimchi.xmlutils.graphics import get_graphics_xml
from wok.plugins.kimchi.xmlutils.interface import get_iface_xml
from wok.plugins.kimchi.xmlutils.qemucmdline import get_qemucmdline_xml
-
+from wok.plugins.kimchi.xmlutils.serial import get_serial_xml
class VMTemplate(object):
def __init__(self, args, scan=False):
@@ -312,6 +312,10 @@ class VMTemplate(object):
params['cpu_info'] = self._get_cpu_xml()
params['disks'] = self._get_disks_xml(vm_uuid)
+ params['serial'] = ''
+ if params['arch'] not in ['ppc', 'ppc64']:
+ params['serial'] = get_serial_xml()
+
graphics = dict(self.info['graphics'])
graphics.update(kwargs.get('graphics', {}))
params['graphics'] = get_graphics_xml(graphics)
@@ -365,6 +369,7 @@ class VMTemplate(object):
%(networks)s
%(graphics)s
%(input_output)s
+ %(serial)s
<memballoon model='virtio' />
</devices>
</domain>
diff --git a/src/wok/plugins/kimchi/xmlutils/serial.py b/src/wok/plugins/kimchi/xmlutils/serial.py
new file mode 100644
index 0000000..2892c45
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/serial.py
@@ -0,0 +1,40 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import E
+
+def get_serial_xml():
+ """
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ """
+ serial = E.serial(type="pty")
+ serial.append(E.target(port='0'))
+ console = E.console(type="pty")
+ console.append(E.target(type="serial", port='0'))
+ return ET.tostring(serial, encoding='utf-8', pretty_print=True) + \
+ ET.tostring(console, encoding='utf-8', pretty_print=True)
+
+
+
--
2.1.0
9 years, 1 month