Pablo Iranzo Gómez has uploaded a new change for review.
Change subject: Add license
......................................................................
Add license
Change-Id: Ib439e74f0010ca9921351421cabdf286e8fa21f5
Signed-off-by: Pablo <Pablo.Iranzo(a)gmail.com>
---
A contrib/forceVMstart/COPYING.GPLv2
1 file changed, 339 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/9475/1
diff --git a/contrib/forceVMstart/COPYING.GPLv2 b/contrib/forceVMstart/COPYING.GPLv2
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/contrib/forceVMstart/COPYING.GPLv2
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--
To view, visit http://gerrit.ovirt.org/9475
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib439e74f0010ca9921351421cabdf286e8fa21f5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Pablo Iranzo Gómez <Pablo.Iranzo(a)redhat.com>
Dan Kenigsberg has submitted this change and it was merged.
Change subject: Remove REST bindings
......................................................................
Remove REST bindings
No one uses them and no one should. We are going in a different
direction for a supported API and keeping the rest bindings alive is
confusing and cumbersome.
Change-Id: I6c2a2909323e943e076db8443ce84f839eab874c
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M Makefile.am
M configure.ac
M tests/Makefile.am
M tests/functional/Makefile.am
D tests/functional/restTests.py
D tests/restData.py
D tests/restTests.py
M vdsm.spec.in
M vdsm/Makefile.am
M vdsm/clientIF.py
M vdsm/config.py.in
D vdsm/rest/BindingREST.py
D vdsm/rest/Controller.py
D vdsm/rest/Dispatcher.py
D vdsm/rest/Makefile.am
D vdsm/rest/__init__.py
D vdsm/rest/templates/Makefile.am
D vdsm/rest/templates/api.xsd
D vdsm/rest/templates/image.json.x
D vdsm/rest/templates/image.xml.x
D vdsm/rest/templates/images.json.x
D vdsm/rest/templates/images.xml.x
D vdsm/rest/templates/response.json.x
D vdsm/rest/templates/response.xml.x
D vdsm/rest/templates/root.json.x
D vdsm/rest/templates/root.xml.x
D vdsm/rest/templates/rsdl.xml
D vdsm/rest/templates/storageconnectionref.json.x
D vdsm/rest/templates/storageconnectionref.xml.x
D vdsm/rest/templates/storageconnectionrefs.json.x
D vdsm/rest/templates/storageconnectionrefs.xml.x
D vdsm/rest/templates/storagedomain.json.x
D vdsm/rest/templates/storagedomain.xml.x
D vdsm/rest/templates/storagedomains.json.x
D vdsm/rest/templates/storagedomains.xml.x
D vdsm/rest/templates/storagepool.json.x
D vdsm/rest/templates/storagepool.xml.x
D vdsm/rest/templates/storagepools.json.x
D vdsm/rest/templates/storagepools.xml.x
D vdsm/rest/templates/task.json.x
D vdsm/rest/templates/task.xml.x
D vdsm/rest/templates/tasks.json.x
D vdsm/rest/templates/tasks.xml.x
D vdsm/rest/templates/volume.json.x
D vdsm/rest/templates/volume.xml.x
D vdsm/rest/templates/volumes.json.x
D vdsm/rest/templates/volumes.xml.x
47 files changed, 3 insertions(+), 4,195 deletions(-)
Approvals:
Adam Litke: Looks good to me, but someone else must approve
Dan Kenigsberg: Verified; Looks good to me, approved
--
To view, visit http://gerrit.ovirt.org/7754
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6c2a2909323e943e076db8443ce84f839eab874c
Gerrit-PatchSet: 2
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: Adam Litke <agl(a)us.ibm.com>
Gerrit-Reviewer: Barak Azulay <bazulay(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
Adam Litke has posted comments on this change.
Change subject: Remove REST bindings
......................................................................
Patch Set 2: Looks good to me, but someone else must approve
--
To view, visit http://gerrit.ovirt.org/7754
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I6c2a2909323e943e076db8443ce84f839eab874c
Gerrit-PatchSet: 2
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: Adam Litke <agl(a)us.ibm.com>
Gerrit-Reviewer: Barak Azulay <bazulay(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
Adam Litke has uploaded a new change for review.
Change subject: mom: Report the status of the mom threads
......................................................................
mom: Report the status of the mom threads
It will be useful to check on the status of the MOM threads. Add a new field to
the HostStats structure to provide this information.
Change-Id: Ibd36a5c3a91abfa3fa29c811ce9b3586bf0bda36
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm/API.py
M vdsm/momIF.py
M vdsm_api/vdsmapi-schema.json
3 files changed, 28 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/87/9287/1
diff --git a/vdsm/API.py b/vdsm/API.py
index 202afc8..cb1f4cc 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1120,8 +1120,10 @@
stats['dateTime'] = '%02d-%02d-%02dT%02d:%02d:%02d GMT' % (
tm_year, tm_mon, tm_day, tm_hour, tm_min, tm_sec)
if self._cif.mom:
+ stats['momStatus'] = self._cif.mom.getStatus()
stats.update(self._cif.mom.getKsmStats())
else:
+ stats['momStatus'] = 'disabled'
stats['ksmState'] = self._cif.ksmMonitor.state
stats['ksmPages'] = self._cif.ksmMonitor.pages
stats['ksmCpu'] = self._cif.ksmMonitor.cpuUsage
diff --git a/vdsm/momIF.py b/vdsm/momIF.py
index 827e9e4..cbe94d0 100644
--- a/vdsm/momIF.py
+++ b/vdsm/momIF.py
@@ -55,3 +55,9 @@
if self._mom is not None:
self.log.info("Shutting down MOM")
self._mom.shutdown()
+
+ def getStatus(self):
+ if self.isAlive():
+ return 'active'
+ else:
+ return 'stopped'
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 6591410..149bfef 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -1420,6 +1420,22 @@
'key': 'str', 'value': 'PathStats'}
##
+# @MOMStatus:
+#
+# An enumeration of possible MOM statuses.
+#
+# @disabled: MOM is not enabled on this host
+#
+# @active: MOM is enabled and running
+#
+# @stopped: MOM has terminated
+#
+# Since: 4.10.1
+##
+{'enum': 'MOMStatus', 'data': ['disabled', 'active', 'stopped']}
+
+
+##
# @HostStats:
#
# Statistics about this host.
@@ -1490,6 +1506,8 @@
#
# @generationID: A @UUID that is refreshed each time vdsm starts
#
+# @momStatus: The current status of the MOM policy engine
+#
# Since: 4.10.0
##
{'type': 'HostStats',
@@ -1506,7 +1524,8 @@
'swapTotal': 'int', 'swapFree': 'int','vmCount': 'int',
'vmActive': 'int', 'vmMigrating': 'int', 'dateTime': 'str',
'ksmState': 'bool', 'ksmPages': 'int', 'ksmCpu': 'float',
- 'netConfigDirty': 'bool', 'generationID': 'UUID'}
+ 'netConfigDirty': 'bool', 'generationID': 'UUID',
+ 'momStatus': 'MOMStatus'}
##
# @Host.getStats:
--
To view, visit http://gerrit.ovirt.org/9287
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibd36a5c3a91abfa3fa29c811ce9b3586bf0bda36
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Adam Litke has uploaded a new change for review.
Change subject: spec: Add MOM as a package dependency
......................................................................
spec: Add MOM as a package dependency
For oVirt 3.2, we are switching to MOM for KSM tuning. One of the goals of this
release is to ensure that MOM is running in all deployed oVirt hosts (ovirt-node
and standalone). A recent enough version of MOM is now available upstream for
Fedora and RHEL and we build nightly RPMs on ovirt.org. I think we are ready to
add this packaging dependency now.
Change-Id: I8e8c5a67066f270b8f19881ac5871ff844dbecaa
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm.spec.in
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/72/9272/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 20ad1dc..2fb7254 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -120,6 +120,7 @@
Requires: libselinux-python
Requires: %{name}-python = %{version}-%{release}
Requires: pyparted
+Requires: mom <= 0.3.0
Requires(pre,preun): policycoreutils-python
Requires(post): /usr/sbin/saslpasswd2
--
To view, visit http://gerrit.ovirt.org/9272
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8e8c5a67066f270b8f19881ac5871ff844dbecaa
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Igor Lvovsky has uploaded a new change for review.
Change subject: Allow break bond with attached network while VM is running.
......................................................................
Allow break bond with attached network while VM is running.
The problem was that we counted tap device on the bridge as part of bond
because of wrong behaviour of getNicsVlanAndBondingForNetwork.
Change-Id: I183e2f4cf780a0eb79a416cdc4afc387893ee106
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=875487
Signed-off-by: Igor Lvovsky <ilvovsky(a)redhat.com>
---
M vdsm/netinfo.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/84/9384/1
diff --git a/vdsm/netinfo.py b/vdsm/netinfo.py
index b6d1a1f..80b0925 100644
--- a/vdsm/netinfo.py
+++ b/vdsm/netinfo.py
@@ -488,7 +488,7 @@
assert bonding is None
bonding = port
lnics += self.bondings[bonding]['slaves']
- else:
+ elif port in self.nics:
lnics.append(port)
return lnics, vlan, bonding
--
To view, visit http://gerrit.ovirt.org/9384
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I183e2f4cf780a0eb79a416cdc4afc387893ee106
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Igor Lvovsky <ilvovsky(a)redhat.com>
Mark Wu has uploaded a new change for review.
Change subject: Bz#839919 remoteFileHandler.py: Add storage into python path
......................................................................
Bz#839919 remoteFileHandler.py: Add storage into python path
pickle need import modules in vdsm/storage, so add it to python path.
Actually it's already done for RPC server side. This patch adds it
for client side, and merge the code.
Change-Id: Id23c3d0be6eb2e2212172613ea8f3b0c58edce06
Signed-off-by: Mark Wu <wudxw(a)linux.vnet.ibm.com>
---
M vdsm/storage/remoteFileHandler.py
1 file changed, 3 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/6354/1
--
To view, visit http://gerrit.ovirt.org/6354
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id23c3d0be6eb2e2212172613ea8f3b0c58edce06
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Mark Wu <wudxw(a)linux.vnet.ibm.com>
Royce Lv has uploaded a new change for review.
Change subject: change misc.retry to make it more general
......................................................................
change misc.retry to make it more general
add argument list to misc.retry to make it usable for function
with arguments.
Change-Id: I2b7d87629762d4d8f248d50fa4da71a0af3645d8
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
M vdsm/storage/misc.py
M vdsm/supervdsm.py
2 files changed, 4 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/4032/1
--
To view, visit http://gerrit.ovirt.org/4032
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2b7d87629762d4d8f248d50fa4da71a0af3645d8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Hello Adam Litke,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/5860
to review the following change.
Change subject: Add local storage xmlrpc functional test
......................................................................
Add local storage xmlrpc functional test
Add defintion parser for functional test case reusable,
add local storage xmlrpc tests
it can be extend to nfs and iscsi type
Change-Id: I4e2e80fa88d66d9bc1a4ba855e2df51ba8165e0a
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M configure.ac
M tests/functional/Makefile.am
A tests/functional/xmlrpcTests.py
M vdsm.spec.in
4 files changed, 198 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/60/5860/1
--
To view, visit http://gerrit.ovirt.org/5860
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4e2e80fa88d66d9bc1a4ba855e2df51ba8165e0a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Gerrit-Reviewer: Adam Litke <agl(a)us.ibm.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: misc: use approriate raise form in RollbackContext
......................................................................
misc: use approriate raise form in RollbackContext
To avoid a pep8 error (W602 deprecated form of raising exception) the
RollbackContext.__exit__ method should use the appropriate form to raise
an exception.
Change-Id: I390771ad2465069400bd777c4463019609ae17d8
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/misc.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/60/9360/1
diff --git a/vdsm/storage/misc.py b/vdsm/storage/misc.py
index 6360dcf..9126080 100644
--- a/vdsm/storage/misc.py
+++ b/vdsm/storage/misc.py
@@ -738,7 +738,7 @@
# re-raise the earliest exception
if firstException is not None:
- raise firstException, None, traceback
+ raise firstException(None, traceback)
def defer(self, func, *args, **kwargs):
self._finally.append((func, args, kwargs))
--
To view, visit http://gerrit.ovirt.org/9360
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I390771ad2465069400bd777c4463019609ae17d8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Dan Kenigsberg has uploaded a new change for review.
Change subject: confNet: report missing net params as ERR_BAD_PARAMS
......................................................................
confNet: report missing net params as ERR_BAD_PARAMS
Change-Id: I6e6b48332f27d1b976a8cd8069d252133ff32378
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm/configNetwork.py
1 file changed, 12 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/59/6959/1
--
To view, visit http://gerrit.ovirt.org/6959
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6e6b48332f27d1b976a8cd8069d252133ff32378
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
ShaoHe Feng has uploaded a new change for review.
Change subject: move betterPopen to storage for HSM service standalone
......................................................................
move betterPopen to storage for HSM service standalone
move betterPopen to the hsm python lib
This is one of step to make HSM service standalone
wiki-page: http://wiki.ovirt.org/wiki/HSM_service_stand_alone
Change-Id: Ide9c63ec0072d44c717dd78e8613352b5e3e5e12
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
---
M configure.ac
M tests/betterPopenTests.py
M tests/testrunner.py
M vdsm.spec.in
M vdsm/Makefile.am
M vdsm/storage/Makefile.am
R vdsm/storage/betterPopen/.gitignore
R vdsm/storage/betterPopen/Makefile.am
R vdsm/storage/betterPopen/__init__.py
R vdsm/storage/betterPopen/createprocess.c
R vdsm/storage/betterPopen/setup.py
M vdsm/storage/misc.py
M vdsm/storage/remoteFileHandler.py
13 files changed, 10 insertions(+), 10 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/56/9356/1
diff --git a/configure.ac b/configure.ac
index 2412a01..b6de932 100644
--- a/configure.ac
+++ b/configure.ac
@@ -218,9 +218,9 @@
vdsm_hooks/vmdisk/Makefile
vdsm/Makefile
vdsm_reg/Makefile
- vdsm/betterPopen/Makefile
vdsm/gluster/Makefile
vdsm/sos/Makefile
+ vdsm/storage/betterPopen/Makefile
vdsm/storage/Makefile
vdsm/storage/imageRepository/Makefile
vdsm/storage/protect/Makefile
diff --git a/tests/betterPopenTests.py b/tests/betterPopenTests.py
index 6347460..b48288a 100644
--- a/tests/betterPopenTests.py
+++ b/tests/betterPopenTests.py
@@ -28,7 +28,7 @@
if __name__ != "__main__":
# This will not be available when we use this module as a subprocess
- from vdsm.betterPopen import BetterPopen
+ from hsmd.betterPopen import BetterPopen
class TestBetterPopen(TestCaseBase):
diff --git a/tests/testrunner.py b/tests/testrunner.py
index 596ced1..73cd629 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -235,7 +235,7 @@
sys.modules['vdsm'] = mod = vdsm()
for name in ('config', 'constants', 'utils', 'define', 'netinfo',
- 'SecureXMLRPCServer', 'libvirtconnection', 'betterPopen',
+ 'SecureXMLRPCServer', 'libvirtconnection',
'exception', 'vdscli', 'qemuImg'):
sub = __import__(name, globals(), locals(), [], -1)
setattr(mod, name, sub)
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c5997e8..c1140ce 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -771,13 +771,13 @@
%{python_sitearch}/%{vdsm_name}/SecureXMLRPCServer.py*
%{python_sitearch}/%{vdsm_name}/utils.py*
%{python_sitearch}/%{vdsm_name}/vdscli.py*
-%{python_sitearch}/%{vdsm_name}/betterPopen/__init__.py*
-%{python_sitearch}/%{vdsm_name}/betterPopen/createprocess.so
%{python_sitearch}/%{vdsm_name}/tool/__init__.py*
%{python_sitearch}/%{vdsm_name}/tool/passwd.py*
%{python_sitearch}/%{vdsm_name}/tool/validate_ovirt_certs.py*
%{python_sitearch}/%{vdsm_name}/tool/load_needed_modules.py*
%{python_sitearch}/%{hsm_name}/__init__.py*
+%{python_sitearch}/%{hsm_name}/betterPopen/__init__.py*
+%{python_sitearch}/%{hsm_name}/betterPopen/createprocess.so
%{python_sitearch}/%{hsm_name}/config.py*
%{python_sitearch}/%{hsm_name}/constants.py*
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 7c79036..b127168 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -18,7 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
-SUBDIRS = sos storage betterPopen rest gluster
+SUBDIRS = sos storage rest gluster
include $(top_srcdir)/build-aux/Makefile.subs
diff --git a/vdsm/storage/Makefile.am b/vdsm/storage/Makefile.am
index 09028a5..188943f 100644
--- a/vdsm/storage/Makefile.am
+++ b/vdsm/storage/Makefile.am
@@ -18,7 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
-SUBDIRS = protect imageRepository
+SUBDIRS = betterPopen protect imageRepository
include $(top_srcdir)/build-aux/Makefile.subs
diff --git a/vdsm/betterPopen/.gitignore b/vdsm/storage/betterPopen/.gitignore
similarity index 100%
rename from vdsm/betterPopen/.gitignore
rename to vdsm/storage/betterPopen/.gitignore
diff --git a/vdsm/betterPopen/Makefile.am b/vdsm/storage/betterPopen/Makefile.am
similarity index 96%
rename from vdsm/betterPopen/Makefile.am
rename to vdsm/storage/betterPopen/Makefile.am
index 9a14e86..b76c3db 100644
--- a/vdsm/betterPopen/Makefile.am
+++ b/vdsm/storage/betterPopen/Makefile.am
@@ -18,7 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
-betterpopendir = $(vdsmpylibdir)/betterPopen
+betterpopendir = $(hsmpylibdir)/betterPopen
dist_betterpopen_PYTHON = \
__init__.py
diff --git a/vdsm/betterPopen/__init__.py b/vdsm/storage/betterPopen/__init__.py
similarity index 100%
rename from vdsm/betterPopen/__init__.py
rename to vdsm/storage/betterPopen/__init__.py
diff --git a/vdsm/betterPopen/createprocess.c b/vdsm/storage/betterPopen/createprocess.c
similarity index 100%
rename from vdsm/betterPopen/createprocess.c
rename to vdsm/storage/betterPopen/createprocess.c
diff --git a/vdsm/betterPopen/setup.py b/vdsm/storage/betterPopen/setup.py
similarity index 100%
rename from vdsm/betterPopen/setup.py
rename to vdsm/storage/betterPopen/setup.py
diff --git a/vdsm/storage/misc.py b/vdsm/storage/misc.py
index 9de1e93..ea874df 100644
--- a/vdsm/storage/misc.py
+++ b/vdsm/storage/misc.py
@@ -58,7 +58,7 @@
sys.path.append("../")
from hsmd import constants
import storage_exception as se
-from vdsm.betterPopen import BetterPopen
+from hsmd.betterPopen import BetterPopen
import logUtils
diff --git a/vdsm/storage/remoteFileHandler.py b/vdsm/storage/remoteFileHandler.py
index 47f4f1c..d28ef23 100644
--- a/vdsm/storage/remoteFileHandler.py
+++ b/vdsm/storage/remoteFileHandler.py
@@ -43,7 +43,7 @@
# If you don't have the vdsm package installed this will fail. Luckily we
# don't need anything when the child spawns. Plus anything you don't have
# to import is less memory taken by each helper.
- from vdsm.betterPopen import BetterPopen
+ from hsmd.betterPopen import BetterPopen
from hsmd import constants
else:
# We add the parent directory so that imports that import the storage
--
To view, visit http://gerrit.ovirt.org/9356
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ide9c63ec0072d44c717dd78e8613352b5e3e5e12
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Zhou Zheng Sheng has uploaded a new change for review.
Change subject: avoid creating hangover in storage domain cache after formatting
......................................................................
avoid creating hangover in storage domain cache after formatting
HSM._recycle(self, dom) tries to delete the storage domain from cache by
calling "sdCache.manuallyRemoveDomain(dom.sdUUID)". This is OK, but when
it invokes "dom.format(dom.sdUUID)" to format storage domain, the "dom"
is a proxy object and have to look for the true storage domain object by
calling 'StorageDomainCache._realProduce()', thus cause the storage
domain added to the cache again. This bug will prevent us re-using the
storage domain UUID even though we format it.
This patch invokes the format method of the proxy object first, then
delete the storage domain from cache, and can avoid creating hangovers.
Change-Id: Ie13a97ad6830553cbd099189dfb82d6f02ce82fe
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=806774
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
M vdsm/storage/hsm.py
1 file changed, 7 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/44/8144/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index a89274a..8512f08 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -2192,11 +2192,14 @@
#TODO: Remove this function when formatStorageDomain() is removed.
def _recycle(self, dom):
try:
- sdCache.manuallyRemoveDomain(dom.sdUUID)
- except KeyError:
- self.log.warn("Storage domain %s doesn't exist in cache. Trying recycle leftovers ...", dom.sdUUID)
+ dom.format(dom.sdUUID)
+ finally:
+ try:
+ sdCache.manuallyRemoveDomain(dom.sdUUID)
+ except KeyError:
+ self.log.warn("Storage domain %s doesn't exist in cache. "
+ "Trying recycle leftovers ...", dom.sdUUID)
- dom.format(dom.sdUUID)
@public
def formatStorageDomain(self, sdUUID, autoDetach = False, options = None):
--
To view, visit http://gerrit.ovirt.org/8144
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie13a97ad6830553cbd099189dfb82d6f02ce82fe
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Adam Litke has uploaded a new change for review.
Change subject: tests: Support parallel testing in apiTests
......................................................................
tests: Support parallel testing in apiTests
The apiTests module tests the JSON-RPC server by creating a server instance on a
specific port and then connecting clients to that port. Unfortunately, this
means that only one instance of the test can be running on a host at any given
time. Our Jenkins infrastructure would like to run parallel tests. To enable
this, we allow the test to find an open port to use.
Change-Id: Icee7a7cac15ba271374b622d4227d5c15e190341
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M tests/apiTests.py
1 file changed, 17 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/42/9342/1
diff --git a/tests/apiTests.py b/tests/apiTests.py
index c51c9fc..4b1a56b 100644
--- a/tests/apiTests.py
+++ b/tests/apiTests.py
@@ -22,6 +22,7 @@
import os
import os.path
import socket
+import errno
import json
import struct
@@ -123,6 +124,7 @@
1. Override the API so we can program our own return values
2. Start an embedded server to process our requests
"""
+ global port
log = logging.getLogger('apiTests')
handler = logging.StreamHandler()
fmt_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
@@ -137,9 +139,22 @@
# Bridge imports the API module so we must set up the fake API first
import Bridge
bridge = Bridge.DynamicBridge(schema)
- server = BindingJsonRpc.BindingJsonRpc(bridge, ip, port)
- server.start()
+ # Support parallel testing. Try hard to find an open port to use
+ while True:
+ try:
+ server = BindingJsonRpc.BindingJsonRpc(bridge, ip, port)
+ break
+ except socket.error as ex:
+ if ex.errno == errno.EADDRINUSE:
+ port += 1
+ if port > 65535:
+ raise socket.error(
+ errno.EADDRINUSE,
+ "Can not find available port to bind")
+ else:
+ raise
+ server.start()
class APITest(TestCaseBase):
def expectAPI(self, obj, meth, retval):
--
To view, visit http://gerrit.ovirt.org/9342
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icee7a7cac15ba271374b622d4227d5c15e190341
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Verify cleaning of supervdsm subprocesses after terminated to avoid defunct
......................................................................
Verify cleaning of supervdsm subprocesses after terminated to avoid defunct
After killing subprocess register its pid to zombieRepear to verify
that svdsm process will wait and clear the pid when the process is
terminated.
Change-Id: I21837f6f707e5e6f64fbb6968ac25294622bd22b
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M vdsm/supervdsmServer.py
1 file changed, 2 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/36/9236/1
diff --git a/vdsm/supervdsmServer.py b/vdsm/supervdsmServer.py
index 34fefdb..0979ba0 100755
--- a/vdsm/supervdsmServer.py
+++ b/vdsm/supervdsmServer.py
@@ -30,6 +30,7 @@
from multiprocessing import Pipe, Process
import storage.misc as misc
from vdsm import utils
+import zombieReaper
try:
from gluster import cli as gcli
@@ -199,6 +200,7 @@
res, err = pipe.recv()
pipe.send("Bye")
proc.terminate()
+ zombieReaper.autoReapPID(proc.pid)
if err is not None:
raise err
--
To view, visit http://gerrit.ovirt.org/9236
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I21837f6f707e5e6f64fbb6968ac25294622bd22b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
Dan Kenigsberg has uploaded a new change for review.
Change subject: drop type() call
......................................................................
drop type() call
Python method resolution knows to find class methods as it is.
Change-Id: Ifd37f580c392412159cc7641336074d8894bd501
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm/storage/imageRepository/formatConverter.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/16/8816/1
diff --git a/vdsm/storage/imageRepository/formatConverter.py b/vdsm/storage/imageRepository/formatConverter.py
index d118e87..422cb39 100644
--- a/vdsm/storage/imageRepository/formatConverter.py
+++ b/vdsm/storage/imageRepository/formatConverter.py
@@ -149,7 +149,7 @@
log.debug("Creating the volume lease for %s", volUUID)
metaId = vol.getMetadataId()
- type(vol).newVolumeLease(metaId, domain.sdUUID, volUUID)
+ vol.newVolumeLease(metaId, domain.sdUUID, volUUID)
# If this volume is used as a template let's update the other
# volume's permissions and share the volume lease (at the moment
--
To view, visit http://gerrit.ovirt.org/8816
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifd37f580c392412159cc7641336074d8894bd501
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
Zhou Zheng Sheng has uploaded a new change for review.
Change subject: tests: add a rollback manager for easy undoing
......................................................................
tests: add a rollback manager for easy undoing
Sometimes we need to perform a series of operations:
op[0], op[1], ... op[N]
These operations may allocate files, locks, connections, and op[K] may
depend on op[K-1] 's result
Consider these are contexts, after constructing contexts, we want to
perform some computing using these contexts. Exception may be raised in
the complicated construction stage of the contexts or when we're using
the contexes.
So if op[K] fails, we need to:
undo op[K-1], undo op[K-2], ... undo op[0]
These undo operations release the resources,
or if all the operations succeed, at last we need to:
undo op[N], undo op[N-1], ... undo op[0]
Furthermore, We want to suppress the exceptions occured in "undo op[X]",
and continue the rollback, so that all the resources can be freed.
At last, we want to see the first exception raised so that we can fix
the root cause, so we want to have the oldest exception occured in this
batch of operation reraised.
This patch proposes a concise framework to do this kind of
rollback. It's an upgrade version of contextlib.contextmanager .
Change-Id: Ibc932637dd81c3becf92de34ea647c1cea136111
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
M tests/Makefile.am
A tests/rollbackManagerTests.py
M tests/testrunner.py
3 files changed, 161 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/71/8671/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2b61dde..02f48ab 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -45,6 +45,7 @@
persistentDictTests.py \
restTests.py \
restData.py \
+ rollbackManagerTests.py \
tcTests.py \
vdsClientTests.py \
remoteFileHandlerTests.py \
diff --git a/tests/rollbackManagerTests.py b/tests/rollbackManagerTests.py
new file mode 100644
index 0000000..db3a5a0
--- /dev/null
+++ b/tests/rollbackManagerTests.py
@@ -0,0 +1,85 @@
+#
+# Copyright IBM Corp. 2012
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+import glob
+import os
+import tempfile
+import uuid
+
+from testrunner import VdsmTestCase as TestCaseBase
+from testrunner import rollbackManager
+
+
+class ContextError(Exception):
+ pass
+
+
+class ConsumerError(Exception):
+ pass
+
+
+class TestRollbackManager(TestCaseBase):
+ def setUp(self):
+ self.tmpdirPrefix = 'testrollback' + str(uuid.uuid4())
+
+ @rollbackManager
+ def tempfiles(self, fileCount, excClass, rollback):
+ dirPath = tempfile.mkdtemp(prefix=self.tmpdirPrefix)
+ undo = lambda: os.rmdir(dirPath)
+ rollback.append(undo)
+
+ for i in range(0, fileCount):
+ path = os.path.join(dirPath, str(i))
+ with open(path, "wb") as f:
+ undo = \
+ lambda path=path: os.remove(path)
+ rollback.append(undo)
+ f.write(str(i))
+
+ if excClass is not None:
+ raise excClass("context error")
+
+ return dirPath
+
+ def testExceptionInContext(self):
+ def exceptionInContext():
+ with self.tempfiles(10, ContextError):
+ pass
+
+ self.assertRaises(ContextError, exceptionInContext)
+ # Directory and files should be removed
+ self.assertEquals(glob.glob(self.tmpdirPrefix + "*"), [])
+
+ def testExceptionInConsumer(self):
+ def exceptionInConsumer():
+ with self.tempfiles(10, None):
+ raise ConsumerError("consumer error")
+
+ self.assertRaises(ConsumerError, exceptionInConsumer)
+ # Directory and files should be removed
+ self.assertEquals(glob.glob(self.tmpdirPrefix + "*"), [])
+
+ def testNormalConsumer(self):
+ fileCount = 10
+ with self.tempfiles(fileCount, None) as dirPath:
+ for i in range(0, fileCount):
+ with open(os.path.join(dirPath, str(i)), "rb") as f:
+ self.assertEquals(int(f.read()), i)
+ # Directory and files should be removed
+ self.assertEquals(glob.glob(self.tmpdirPrefix + "*"), [])
diff --git a/tests/testrunner.py b/tests/testrunner.py
index cdbc9d3..f9cc323 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -22,6 +22,7 @@
import os
import unittest
from functools import wraps
+from contextlib import contextmanager
from nose import config
from nose import core
@@ -239,6 +240,80 @@
return False
+def rollbackManager(transaction):
+ '''
+ A contextmanager-like manager for easy undoing. It's an upgraded
+ contextlib.contextmanager and can manage a variable number of contextes.
+
+ It is used as a decorator to a function. There must exist a parameter
+ named "rollback" of the decorated function. Then the function can treat
+ the "rollback" as a list and append undo operations(lambdas, closures, ...)
+ to the list. The function will be put in the "with" statement, the return
+ value of the function will be assigned to the "as" variable. If an
+ exception is raised, whether it's raised in the function or in the block
+ under the "with" statement, the registered undo operations will be played
+ in reverse order. When peforming rollback, exceptions will be swalloweded
+ to let rollback continue, at last, the earliest exception with original
+ line number and stack trace infomation will be raised.
+
+ Simple example:
+ _________________________________________
+ @rollbackManager
+ def foo(a, b, rollback):
+ x = allocate_X(a)
+ rollback.append(lambda: release_X(x))
+
+ # Need not to catch the exception when allocating Y
+ # and release x in a "try..final" block.
+ # The rollback Manager will do that.
+ y = allocate_Y_using(x)
+ rollback.append(lambda: release_Y(y))
+
+ # Need not to catch the exception when computing z
+ # and release x, y. Let rollback Manager do it for you.
+ z = do_something_with(x, y)
+ return z
+
+ with foo(blah1, blah2) as z:
+ visit(z)
+ _________________________________________
+ When the "with" block is exited, resource y will be released first, then
+ resource x. If exception is raised when constructing y, then only the
+ allocated x will be released, and the original exception will be re-raised.
+ '''
+
+ @contextmanager
+ def wrapper(*args, **kwargs):
+ rollback = []
+ exception = None
+ traceback = None
+ try:
+ yield transaction(rollback=rollback, *args, **kwargs)
+ except Exception as e:
+ # keep the original exception and traceback info
+ exception = e
+ traceback = sys.exc_info()[2]
+ finally:
+ rollback.reverse()
+ _playRollback(rollback, exception, traceback)
+ return wrapper
+
+
+def _playRollback(rollback, exception=None, traceback=None):
+ for undo in rollback:
+ try:
+ undo()
+ except Exception as e:
+ # keep the earliest exception info
+ if not exception:
+ exception = e
+ # keep the original traceback info
+ traceback = sys.exc_info()[2]
+ # re-raise the earliest exception
+ if exception:
+ raise exception, None, traceback
+
+
if __name__ == '__main__':
if "--help" in sys.argv:
print("testrunner options:\n"
--
To view, visit http://gerrit.ovirt.org/8671
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibc932637dd81c3becf92de34ea647c1cea136111
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Alon Bar-Lev has posted comments on this change.
Change subject: add and use hypervisor autodetection in bootstrap.
......................................................................
Patch Set 5: I would prefer that you didn't submit this
Hello,
I use nested kvm and the hardware detection works just fine, why shouldn't this work with other hypervisors?
plain qemu: add the following at command-line:
-cpu core2duo,+vmx
And even if is not, I don't think that placing a file at host before bootstrap in these debug cases is something that worth the extra complexity.
Alon
--
To view, visit http://gerrit.ovirt.org/7657
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I79f4ab08b838bd75af5d4c26f98923fca0d65d8e
Gerrit-PatchSet: 5
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)gmail.com>
Gerrit-Reviewer: Alon Bar-Lev <alonbl(a)redhat.com>
Gerrit-Reviewer: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Douglas Schilling Landgraf <dougsland(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)gmail.com>
Gerrit-Reviewer: Ryan Harper <ryanh(a)us.ibm.com>
Gerrit-Reviewer: Shu Ming <shuming(a)linux.vnet.ibm.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
Federico Simoncelli has uploaded a new change for review.
Change subject: [wip] pool: refresh multipath on connectStoragePool
......................................................................
[wip] pool: refresh multipath on connectStoragePool
On connectStoragePool we should rescan the iscsi connections to
reactivate them in case they were previously interrupted.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=870768
Change-Id: Ie26a7a2577b65d3fb70586a849e0245e64344e3b
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/sp.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/9275/1
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index fdd146c..ffe1b92 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -639,7 +639,7 @@
self.id = hostID
self.scsiKey = scsiKey
# Make sure SDCache doesn't have stale data (it can be in case of FC)
- sdCache.refresh()
+ sdCache.invalidateStorage()
# Rebuild whole Pool
self.__rebuild(msdUUID=msdUUID, masterVersion=masterVersion)
self.__createMailboxMonitor()
--
To view, visit http://gerrit.ovirt.org/9275
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie26a7a2577b65d3fb70586a849e0245e64344e3b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Adam Litke has uploaded a new change for review.
Change subject: mom: Redirect mom init stacktrace to debug log
......................................................................
mom: Redirect mom init stacktrace to debug log
When MOM initialization fails we are currently falling back to the old
KsmMonitor. When this happens we print a warning which is appropriate. Since
the error is handled, we should not print the stack trace at warning level.
This information is useful in debug mode however.
Split the stack trace printout into a separate debug logging message.
Change-Id: I8e85fafadd3e9180b6c5911baa6552b380476e3c
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm/clientIF.py
1 file changed, 2 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/71/9271/1
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index 38aa0d7..ed3a0f0 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -194,7 +194,8 @@
self.mom = MomThread(momconf)
except:
self.log.warn("MOM initialization failed and fall "
- "back to KsmMonitor", exc_info=True)
+ "back to KsmMonitor")
+ self.log.debug("Details:", exc_info=True)
self.ksmMonitor = ksm.KsmMonitorThread(self)
def _syncLibvirtNetworks(self):
--
To view, visit http://gerrit.ovirt.org/9271
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8e85fafadd3e9180b6c5911baa6552b380476e3c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Adam Litke has uploaded a new change for review.
Change subject: build: Add BuildDepends for m2crypto
......................................................................
build: Add BuildDepends for m2crypto
During the build, I get the following traceback:
Traceback (most recent call last):
File "../tests/testrunner.py", line 274, in <module>
hackVdsmModule()
File "../tests/testrunner.py", line 252, in hackVdsmModule
sub = __import__(name, globals(), locals(), [], -1)
File "/home/aglitke/rpmbuild/BUILD/vdsm-4.10.2/vdsm/SecureXMLRPCServer.py",
line 39, in <module>
from M2Crypto import SSL, X509
ImportError: No module named M2Crypto
We need the m2crypto package at build time now as well (in order to run tests).
Change-Id: I4bfe0c6ca979f868be665d48bce395c896bec1f7
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm.spec.in
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/53/9253/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 20ad1dc..9ba254f 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -42,6 +42,7 @@
BuildRequires: libvirt-python
BuildRequires: genisoimage
BuildRequires: openssl
+BuildRequires: m2crypto
%if 0%{?rhel}
BuildRequires: python-ordereddict
%endif
--
To view, visit http://gerrit.ovirt.org/9253
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4bfe0c6ca979f868be665d48bce395c896bec1f7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Royce Lv has uploaded a new change for review.
Change subject: join supervdsm subprocess after terminated to avoid defunct status
......................................................................
join supervdsm subprocess after terminated to avoid defunct status
After validateAccess there leaves a defunct process
clear it by join after termination
Change-Id: I0cdcfb3b467e9226f14a4ebc2845ff2db0f19b5f
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M vdsm/supervdsmServer.py
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/03/6503/1
--
To view, visit http://gerrit.ovirt.org/6503
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0cdcfb3b467e9226f14a4ebc2845ff2db0f19b5f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Zhou Zheng Sheng has uploaded a new change for review.
Change subject: xmlrpcTests: narrow the expected exception when using retry
......................................................................
xmlrpcTests: narrow the expected exception when using retry
Change the expected exception from the default Exception to
AssertionError
Change-Id: I0deded14d02a21bcfbca49dbdfadfe8652added3
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
M tests/functional/xmlrpcTests.py
1 file changed, 4 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/44/8444/1
diff --git a/tests/functional/xmlrpcTests.py b/tests/functional/xmlrpcTests.py
index 6ccaf66..1d44059 100644
--- a/tests/functional/xmlrpcTests.py
+++ b/tests/functional/xmlrpcTests.py
@@ -122,7 +122,8 @@
'vmName': 'foo'})
self.assertVdsOK(r)
try:
- retry(lambda: self.assertVmUp(VMID), timeout=20)
+ retry(lambda: self.assertVmUp(VMID),
+ expectedException=AssertionError, timeout=20)
finally:
# FIXME: if the server dies now, we end up with a leaked VM.
r = self.s.destroy(VMID)
@@ -154,7 +155,8 @@
try:
self.assertVdsOK(self.s.create(conf))
# wait 65 seconds for VM to come up until timeout
- retry(assertVMAndGuestUp, timeout=65)
+ retry(assertVMAndGuestUp, expectedException=AssertionError,
+ timeout=65)
finally:
destroyResult = self.s.destroy(VMID)
--
To view, visit http://gerrit.ovirt.org/8444
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0deded14d02a21bcfbca49dbdfadfe8652added3
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Juan Hernandez has uploaded a new change for review.
Change subject: Implement SSL session cache
......................................................................
Implement SSL session cache
We are currently implementing SSL for the XML-RPC communications with
the ssl module. Unfortunately this module uses OpenSSL in such a way
that a new context is created for each TCP connection. This means that
the heavy part of the SSL handshake (asymmetric encryption) is
performed for each connection. In addition as we use HTTP 1.0 this
also means that we use one connection per request, and thus one
handshake per request. This is a potential performance problem in the
VDSM side and a huge performance problem in the engine side: when the
number of hosts managed by the engine the use of CPU grows to a point
where almost all the CPU is used for SSL handshares.
This patch uses the OpenSSL.SSL module (pyOpenSSL) in a way such that
SSL sessions are cached, thus greatly reducing the amount of CPU
needed for handshakes, specially in the engine.
Bug-Id: https://bugzilla.redhat.com/857035
Change-Id: Ic75adee4070b415b8855af1f2ea289825496fbc1
Signed-off-by: Juan Hernandez <juan.hernandez(a)redhat.com>
---
M vdsm/SecureXMLRPCServer.py
1 file changed, 125 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/23/8123/1
diff --git a/vdsm/SecureXMLRPCServer.py b/vdsm/SecureXMLRPCServer.py
index 9396a28..744e594 100644
--- a/vdsm/SecureXMLRPCServer.py
+++ b/vdsm/SecureXMLRPCServer.py
@@ -35,6 +35,129 @@
import socket
import SocketServer
+from OpenSSL import SSL
+
+
+class SSLServerSocket(object):
+ """SSL decorator for server sockets.
+
+ This class wraps a normal socket so that when the accept method
+ is called the client socket as also decorated with SSL functionality.
+ The rest of the methods are just delegated to the raw socket.
+ """
+
+ def __init__(self, raw, certfile=None, keyfile=None, ca_certs=None):
+ # Save the reference to the raw socket so that we can delegate
+ # calls to it later:
+ self.raw = raw
+
+ # Create the OpenSSL context:
+ self.context = SSL.Context(SSL.SSLv3_METHOD)
+ self.context.set_session_id("vdsm")
+
+ # Load the crendentials:
+ if certfile and keyfile:
+ self.context.use_certificate_file(certfile)
+ self.context.use_privatekey_file(keyfile)
+
+ # Load the CA certificates used to verify certifictes presented
+ # by the clients:
+ if ca_certs:
+ self.context.load_verify_locations(ca_certs)
+ self.context.set_verify(
+ SSL.VERIFY_PEER |
+ SSL.VERIFY_FAIL_IF_NO_PEER_CERT |
+ SSL.VERIFY_CLIENT_ONCE,
+ SSLServerSocket.verify)
+
+ @staticmethod
+ def verify(connection, certificate, x, y, z):
+ # No need for additional verifications:
+ return True
+
+ def accept(self):
+ # Get the client socket and address calling the accept method of
+ # the raw socket and replace the client socket with a wrapper:
+ client, address = self.raw.accept()
+ client = SSLClientSocket(client, self.context)
+ return client, address
+
+ def bind(self, address):
+ return self.raw.bind(address)
+
+ def fileno(self):
+ return self.raw.fileno()
+
+ def getsockname(self):
+ return self.raw.getsockname()
+
+ def gettimeout(self):
+ return self.raw.gettimeout()
+
+ def listen(self, backlog=5):
+ return self.raw.listen(backlog)
+
+ def setsockopt(self, level, optname, value):
+ return self.raw.setsockopt(level, optname, value)
+
+
+class SSLClientSocket(object):
+ """SSL decorator for client sockets.
+
+ This class wraps a client socket returned by the accept
+ method of a server socket providing the SSL functionality.
+
+ Note that most methods are delegated to the wrapped raw
+ and many are just not implemented because they are not used
+ in our use case.
+ """
+
+ def __init__(self, raw, context):
+ # Save the reference to the raw client socket so that we can
+ # delegate calls to it later:
+ self.raw = raw
+ self.context = context
+
+ # Create a new SSL connection and a file like object on top of it
+ # in order to be able to implement the makefile method used by
+ # the XML RPC server:
+ self.connection = SSL.Connection(self.context, self.raw)
+
+ # Configure the connection to that it will automatically do the
+ # hand shake before the first read or write operation:
+ self.connection.set_accept_state()
+
+ def close(self):
+ return self.connection.close()
+
+ def do_handshake(self):
+ return self.connection.do_handshake()
+
+ def makefile(self, mode="r", bufsize=-1):
+ # In order to implement this method we borrow the _fileobject
+ # function from the socket module, and that forces us to
+ # implement correcty the recv and send family of methods:
+ return socket._fileobject(self, mode, bufsize)
+
+ def recv(self, bufsize, flags=0):
+ return self.connection.recv(bufsize)
+
+ def send(self, string, flags=0):
+ return self.connection.send(string)
+
+ def sendall(self, string, flags=0):
+ return self.connection.sendall(string)
+
+ def setsockopt(self, level, optname, value):
+ self.connection.setsockopt(level, optname, value)
+
+ def shutdown(self, how):
+ # Not completly sure, but I think we should first shutdown the
+ # SSL connection and then the raw socket:
+ self.connection.shutdown()
+ self.raw.shutdown(how)
+
+
SecureXMLRPCRequestHandler = SimpleXMLRPCServer.SimpleXMLRPCRequestHandler
@@ -53,11 +176,9 @@
requestHandler,
logRequests, allow_none, encoding,
bind_and_activate=False)
- self.socket = ssl.wrap_socket(self.socket,
+ self.socket = SSLServerSocket(self.socket,
keyfile=keyfile, certfile=certfile,
- ca_certs=ca_certs, server_side=True,
- cert_reqs=ssl.CERT_REQUIRED,
- do_handshake_on_connect=False)
+ ca_certs=ca_certs)
if timeout is not None:
self.socket.settimeout = timeout
if bind_and_activate:
--
To view, visit http://gerrit.ovirt.org/8123
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic75adee4070b415b8855af1f2ea289825496fbc1
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <juan.hernandez(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: tests: add FileVolumeGetVSizeTest
......................................................................
tests: add FileVolumeGetVSizeTest
This patch adds a test for the getVSize method for file domains.
Change-Id: Iac8b28f9fa1268f83c658bde1d0302e013584826
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M tests/Makefile.am
A tests/volumeTests.py
2 files changed, 70 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/03/9203/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f53470f..1753c75 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -49,6 +49,7 @@
vdsClientTests.py \
remoteFileHandlerTests.py \
resourceManagerTests.py \
+ volumeTests.py \
$(NULL)
dist_noinst_DATA = \
diff --git a/tests/volumeTests.py b/tests/volumeTests.py
new file mode 100644
index 0000000..5dfd8e0
--- /dev/null
+++ b/tests/volumeTests.py
@@ -0,0 +1,69 @@
+# Copyright 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import os
+import shutil
+import tempfile
+import uuid
+
+from testrunner import VdsmTestCase as TestCaseBase
+
+from storage import outOfProcess
+from storage.fileVolume import FileVolume
+
+
+class FileDomainMockObject(object):
+ def __init__(self, repoPath, sdUUID):
+ self.repoPath = repoPath
+ self.sdUUID = sdUUID
+
+ def _getRepoPath(self):
+ return self.repoPath
+
+ @property
+ def oop(self):
+ return outOfProcess.getProcessPool(self.sdUUID)
+
+
+class FileVolumeGetVSizeTest(TestCaseBase):
+ VOLSIZE = 1024
+ SDBLKSZ = 512
+
+ def setUp(self):
+ self.repoPath = tempfile.mkdtemp()
+
+ self.sdUUID = str(uuid.uuid4())
+ self.imgUUID = str(uuid.uuid4())
+ self.volUUID = str(uuid.uuid4())
+
+ imgPath = os.path.join(self.repoPath, self.sdUUID, "images",
+ self.imgUUID)
+ volPath = os.path.join(imgPath, self.volUUID)
+
+ os.makedirs(imgPath)
+ open(volPath, "w").truncate(self.VOLSIZE * self.SDBLKSZ)
+ self.sdobj = FileDomainMockObject(self.repoPath, self.sdUUID)
+
+ def tearDown(self):
+ shutil.rmtree(self.repoPath)
+
+ def test(self):
+ volSize = FileVolume.getVSize(self.sdobj, self.imgUUID,
+ self.volUUID)
+ assert volSize == self.VOLSIZE
--
To view, visit http://gerrit.ovirt.org/9203
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iac8b28f9fa1268f83c658bde1d0302e013584826
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Dan Kenigsberg has uploaded a new change for review.
Change subject: build on el6: import OrderedDict from elsewhere
......................................................................
build on el6: import OrderedDict from elsewhere
Commit 1db772c71e has introduced usage of collections.OrderedDict which
is not part of el6's Python 2.6. This patch imports Raymond Hettinger's
implementation if OrderedDict is missing in the default location.
Change-Id: I92079c2639d892f283c771576ca25e333d0b1936
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm.spec.in
M vdsm_api/vdsmapi.py
2 files changed, 11 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/12/9212/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index d268948..88e3a1f 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -42,6 +42,9 @@
BuildRequires: libvirt-python
BuildRequires: sanlock-python >= 2.3
BuildRequires: genisoimage
+%if 0%{?rhel}
+BuildRequires: python-ordereddict
+%endif
# Autotools BuildRequires
%if 0%{?enable_autotools}
@@ -162,6 +165,9 @@
BuildArch: noarch
Requires: %{name}-python = %{version}-%{release}
+%if 0%{?rhel}
+Requires: python-ordereddict
+%endif
%description jsonrpc
A Json-based RPC interface that serves as the protocol for libvdsm.
diff --git a/vdsm_api/vdsmapi.py b/vdsm_api/vdsmapi.py
index a91b233..c68daa1 100644
--- a/vdsm_api/vdsmapi.py
+++ b/vdsm_api/vdsmapi.py
@@ -24,7 +24,11 @@
# Refer to the README and COPYING files for full details of the license
#
-from collections import OrderedDict
+try:
+ from collections import OrderedDict
+ OrderedDict # make pyflakes happy
+except ImportError:
+ from ordereddict import OrderedDict
def tokenize(data):
--
To view, visit http://gerrit.ovirt.org/9212
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I92079c2639d892f283c771576ca25e333d0b1936
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: tests: override the P_VDSM definition in local tests
......................................................................
tests: override the P_VDSM definition in local tests
The P_VDSM constant is used to configure the PYTHONPATH variable for
the out of process handlers and it should be overridden during the
local tests (vdsm is not installed).
Change-Id: I06a11ab32b0adc635fe236c6033b6b3d2257b235
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M tests/testrunner.py
1 file changed, 2 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/17/9217/1
diff --git a/tests/testrunner.py b/tests/testrunner.py
index ff09862..36d76c6 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -240,6 +240,8 @@
setattr(mod, name, sub)
sys.modules['vdsm.%s' % name] = getattr(mod, name)
+ sys.modules['vdsm.constants'].P_VDSM = "../"
+
def findRemove(listR, value):
"""used to test if a value exist, if it is, return true and remove it."""
--
To view, visit http://gerrit.ovirt.org/9217
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I06a11ab32b0adc635fe236c6033b6b3d2257b235
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Hello Ayal Baron,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/9209
to review the following change.
Change subject: BZ#836161 - Changed code obsoleted by deleteImage() rewrite.
......................................................................
BZ#836161 - Changed code obsoleted by deleteImage() rewrite.
Change image.move and image.multipleMove to call the new
deleteImage implementation instead of image.delete
Change-Id: Icee221a3e8282194971afefd21540dc759a02aab
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
Reviewed-on: https://gerrit.eng.lab.tlv.redhat.com/3141
Reviewed-by: Ayal Baron <abaron(a)redhat.com>
Tested-by: Daniel Paikov <dpaikov(a)redhat.com>
---
M vdsm/storage/image.py
M vdsm/storage/sp.py
2 files changed, 30 insertions(+), 83 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/09/9209/1
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index 4cd9785..73274fe 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -67,6 +67,19 @@
TEMPORARY_VOLUME_SIZE = 20480 # in sectors (10M)
+def _deleteImage(dom, imgUUID, postZero):
+ """This ancillary function will be removed.
+
+ Replaces Image.delete() in Image.[copy(), move(),multimove()].
+ """
+ allVols = dom.getAllVolumes()
+ imgVols = sd.getVolsOfImage(allVols, imgUUID)
+ if postZero:
+ dom.zeroImage(dom.sdUUID, imgUUID, imgVols)
+ else:
+ dom.deleteImage(dom.sdUUID, imgUUID, imgVols)
+
+
class Image:
""" Actually represents a whole virtual disk.
Consist from chain of volumes.
@@ -612,7 +625,7 @@
# in destination domain, if we got the overwrite command
if force:
self.log.info("delete image %s on domain %s before overwriting", imgUUID, destDom.sdUUID)
- self.delete(destDom.sdUUID, imgUUID, postZero, force=True)
+ _deleteImage(destDom, imgUUID, postZero)
chains = self._createTargetImage(destDom, srcSdUUID, imgUUID)
self._interImagesCopy(destDom, srcSdUUID, imgUUID, chains)
@@ -627,7 +640,12 @@
vars.task.clearRecoveries()
# If it's 'move' operation, we should delete src image after copying
if op == MOVE_OP:
- self.delete(srcSdUUID, imgUUID, postZero, force=True)
+ try:
+ dom = sdCache.produce(srcSdUUID)
+ _deleteImage(dom, imgUUID, postZero)
+ except se.StorageException:
+ self.log.warning("Failed to remove img: %s from srcDom %s: "
+ "after it was copied to: %s", imgUUID, srcSdUUID, dstSdUUID)
self.log.info("%s task on image %s was successfully finished", OP_TYPES[op], imgUUID)
return True
@@ -676,9 +694,11 @@
"""
for imgUUID in imgList:
try:
- self.delete(sdUUID, imgUUID, postZero, force=True)
- except Exception:
- pass
+ dom = sdCache.produce(sdUUID)
+ _deleteImage(dom, imgUUID, postZero)
+ except se.StorageException:
+ self.log.warning("Delete image failed for image: %s in SD: %s",
+ imgUUID, sdUUID, exc_info=True)
def multiMove(self, srcSdUUID, dstSdUUID, imgDict, vmUUID, force):
"""
@@ -706,9 +726,11 @@
# Remove images from source domain only after successfull copying of all images to the destination domain
for (imgUUID, postZero) in imgDict.iteritems():
try:
- self.delete(srcSdUUID, imgUUID, postZero, force=True)
- except Exception:
- pass
+ dom = sdCache.produce(srcSdUUID)
+ _deleteImage(dom, imgUUID, postZero)
+ except se.StorageException:
+ self.log.warning("Delete image failed for image %s in SD: %s",
+ imgUUID, dom.sdUUID, exc_info=True)
def __cleanupCopy(self, srcVol, dstVol):
"""
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index c9489b8..fdd146c 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1823,73 +1823,6 @@
image.Image(repoPath).multiMove(srcDomUUID, dstDomUUID, imgDict, vmUUID, force)
- def deleteImage(self, sdUUID, imgUUID, postZero, force):
- """
- Deletes an Image folder with all its volumes.
-
- This function assumes that imgUUID is locked.
- In addition to removing image, this function also does the following:
- If removing a template from a backup SD which has dependent images:
- - creates a fake template.
- If removing the last image which depends on a fake template:
- - removes the fake template as well
- :param sdUUID: The UUID of the storage domain that contains the images.
- :type sdUUID: UUID
- :param imgUUID: The UUID of the image you want to delete.
- :type imgUUID: UUID
- :param postZero: bool
- :param force: Should the operation be forced.
- :type force: bool
- """
- # TODO: This function works on domains. No relation with pools.
- # Therefore move this to the relevant *sd module
- repoPath = os.path.join(self.storage_repository, self.spUUID)
- img = image.Image(repoPath)
- dom = sdCache.produce(sdUUID)
- allVols = dom.getAllVolumes()
- # Filter volumes related to this image
- imgsByVol = sd.getVolsOfImage(allVols, imgUUID)
- if all(len(v.imgs) == 1 for k, v in imgsByVol.iteritems()):
- # This is a self contained regular image, i.e. it's either an image
- # which is not based on a template or a template which has no
- # derived images, e.g. not derived from a template
- img.delete(sdUUID=sdUUID, imgUUID=imgUUID, postZero=postZero, force=force)
- else:
- # This is either a template with derived images or a derived image
- # so needs further scrutiny
- ts = tuple((volName, vol.imgs) for volName, vol in
- imgsByVol.iteritems() if len(vol.imgs) > 1)
- if len(ts) != 1:
- raise se.ImageValidationError("Image points to multiple"
- "templates %s in %s from %s" %
- (ts, imgsByVol, allVols))
- # TODO: Lock the template, reload allVols.
- # template = ts[0] = [(tName, tImgs)]
- tName, tImgs = ts[0]
- # getAllVolumes makes the template self img the 1st one in tImgs
- templateImage = tImgs[0]
- numOfDependentImgs = len(tImgs) - 1
- if templateImage != imgUUID:
- # Removing an image based on a template
- img.delete(sdUUID=sdUUID, imgUUID=imgUUID, postZero=postZero, force=force)
- if numOfDependentImgs == 1 and dom.produceVolume(templateImage, tName).isFake():
- # Remove the fake template since last consumer was removed
- img.delete(sdUUID=sdUUID, imgUUID=templateImage, postZero=False, force=True)
-
- # Removing a template with dependencies
- elif force:
- img.delete(sdUUID=sdUUID, imgUUID=templateImage, postZero=postZero,
- force=force)
- elif not dom.isBackup():
- raise se.ImagesActionError("Can't remove template with children %s" %
- allVols)
- else:
- # Removing a template with dependencies in backup domain
- # A fake template will be created
- img.delete(sdUUID=sdUUID, imgUUID=imgUUID, postZero=postZero, force=True)
- tParams = dom.produceVolume(imgUUID, tName).getVolumeParams()
- img.createFakeTemplate(sdUUID=sdUUID, volParams=tParams)
-
def mergeSnapshots(self, sdUUID, vmUUID, imgUUID, ancestor, successor, postZero):
"""
Merges the source volume to the destination volume.
@@ -2065,14 +1998,6 @@
vol.teardown(sdUUID, volUUID)
except:
self.log.warning("SP %s SD %s img %s Vol %s - teardown failed")
-
- def preDeleteRename(self, sdUUID, imgUUID):
- repoPath = os.path.join(self.storage_repository, self.spUUID)
- return image.Image(repoPath).preDeleteRename(sdUUID, imgUUID)
-
- def validateDelete(self, sdUUID, imgUUID):
- repoPath = os.path.join(self.storage_repository, self.spUUID)
- image.Image(repoPath).validateDelete(sdUUID, imgUUID)
def validateVolumeChain(self, sdUUID, imgUUID):
repoPath = os.path.join(self.storage_repository, self.spUUID)
--
To view, visit http://gerrit.ovirt.org/9209
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icee221a3e8282194971afefd21540dc759a02aab
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
Gerrit-Reviewer: Ayal Baron <abaron(a)redhat.com>
Hello Ayal Baron, Igor Lvovsky,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/9208
to review the following change.
Change subject: BZ#836161 - Rewrite of deleteImage() complement.
......................................................................
BZ#836161 - Rewrite of deleteImage() complement.
Volume operations should be done at the SD level to avoid
retrieving static data multiple times from disk.
Added lvm.lvDmDev() returning the dm-X for active LVs.
Use this to get active LV size without issue a lvm command.
Change-Id: I6c8c9baecee1ad7aa7789026e533aa254a738097
Complements: I304ff5cd70186ffc9789cd1ac9337efa6c5ff695
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
Reviewed-on: https://gerrit.eng.lab.tlv.redhat.com/3140
Reviewed-by: Ayal Baron <abaron(a)redhat.com>
Tested-by: Igor Lvovsky <ilvovsky(a)redhat.com>
---
M vdsm/storage/blockSD.py
M vdsm/storage/fileSD.py
M vdsm/storage/hsm.py
3 files changed, 63 insertions(+), 11 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/08/9208/1
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index 26d4380..506059c 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -207,8 +207,10 @@
lvm.changelv(sdUUID, volUUIDs, (("-a", "y"), ("--deltag", imgUUID),
("--addtag", sd.REMOVED_IMAGE_PREFIX + imgUUID)))
except se.StorageException as e:
- log.debug("SD %s, Image %s pre zeroing ops failed", sdUUID, imgUUID,
- volUUIDs)
+ log.error("Can't activate or change LV tags in SD %s. "
+ "failing Image %s pre zeroing operation for vols: %s. %s",
+ sdUUID, imgUUID, volUUIDs, e)
+ raise
# Following call to changelv is separate since setting rw permission on an
# LV fails if the LV is already set to the same value, hence we would not
# be able to differentiate between a real failure of deltag/addtag and one
@@ -915,11 +917,39 @@
if i.startswith(blockVolume.TAG_PREFIX_IMAGE) ]
return images
+ def rmDCVolLinks(self, imgPath, volsImgs):
+ for vol in volsImgs:
+ lPath = os.path.join(imgPath, vol)
+ removedPaths = []
+ try:
+ os.unlink(lPath)
+ except OSError as e:
+ self.log.warning("Can't unlink %s. %s", lPath, e)
+ else:
+ removedPaths.append(lPath)
+ self.log.debug("removed: %s", removedPaths)
+ return tuple(removedPaths)
+
+ def rmDCImgDir(self, imgUUID, volsImgs):
+ imgPath = os.path.join(self.domaindir, sd.DOMAIN_IMAGES, imgUUID)
+ self.rmDCVolLinks(imgPath, volsImgs)
+ try:
+ os.rmdir(imgPath)
+ except OSError:
+ self.log.warning("Can't rmdir %s. %s", imgPath, exc_info = True)
+ else:
+ self.log.debug("removed image dir: %s", imgPath)
+ return imgPath
+
def deleteImage(self, sdUUID, imgUUID, volsImgs):
- return deleteVolumes(sdUUID, volsImgs)
+ toDel = tuple(vName for vName, v in volsImgs.iteritems()
+ if v.imgs[0] == imgUUID)
+ deleteVolumes(sdUUID, toDel)
+ self.rmDCImgDir(imgUUID, volsImgs)
def zeroImage(self, sdUUID, imgUUID, volsImgs):
- return zeroImgVolumes(sdUUID, imgUUID, volsImgs)
+ zeroImgVolumes(sdUUID, imgUUID, volsImgs)
+ self.rmDCImgDir(imgUUID, volsImgs)
def getAllVolumes(self):
"""
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index 90ffecd..c4415da 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -496,9 +496,8 @@
remove the remnants of the removed images (they could be left sometimes
(on NFS mostly) due to lazy file removal
"""
- removedPattern = os.path.join(
- self.domaindir, sd.DOMAIN_IMAGES,
- sd.REMOVED_IMAGE_PREFIX + '*')
+ removedPattern = os.path.join(self.domaindir, sd.DOMAIN_IMAGES,
+ sd.REMOVED_IMAGE_PREFIX + '*')
removedImages = self.oop.glob.glob(removedPattern)
self.log.debug("Removing remnants of deleted images %s" %
removedImages)
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 4d696bf..e712102 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1308,6 +1308,8 @@
def deleteImage(self, sdUUID, spUUID, imgUUID, postZero=False, force=False):
"""
Delete Image folder with all volumes
+
+ force parameter is deprecated and not evaluated.
"""
#vars.task.setDefaultException(se.ChangeMeError("%s" % args))
self.getPool(spUUID) #Validates that the pool is connected. WHY?
@@ -1317,15 +1319,31 @@
vars.task.getSharedLock(STORAGE, sdUUID)
allVols = dom.getAllVolumes()
volsByImg = sd.getVolsOfImage(allVols, imgUUID)
+ if not volsByImg:
+ self.log.error("Empty or not found image %s in SD %s. %s",
+ imgUUID, sdUUID, allVols)
+ raise se.ImageDoesNotExistInSD(imgUUID, sdUUID)
+
# on data domains, images should not be deleted if they are templates
# being used by other images.
- if not misc.parseBool(force) and not dom.isBackup() \
- and not all(len(v.imgs) == 1 for v in volsByImg.itervalues()):
- raise se.CannotDeleteSharedVolume("Cannot delete shared image"
- "%s. volImgs: %s" % (imgUUID, volsByImg))
+ isTemplateWithChildren = False
+ for v in volsByImg.itervalues():
+ if len(v.imgs) > 1 and v.imgs[0] == imgUUID:
+ isTemplateWithChildren = True
+ break
+
+ if not isTemplateWithChildren:
+ needFake = False
+ elif dom.isBackup():
+ needFake = True
+ else:
+ raise se.CannotDeleteSharedVolume("Cannot delete shared image %s. "
+ "volImgs: %s" % (imgUUID, volsByImg))
# zeroImage will delete zeroed volumes at the end.
if misc.parseBool(postZero):
+ # postZero implies block domain. Backup domains are always NFS
+ # hence no need to create fake template if postZero is true.
self._spmSchedule(spUUID, "zeroImage_%s" % imgUUID, dom.zeroImage,
sdUUID, imgUUID, volsByImg.keys())
else:
@@ -1337,6 +1355,11 @@
# intended to quickly fix the integration issue with rhev-m. In 2.3
# we should use the new resource system to synchronize the process
# an eliminate all race conditions
+ if needFake:
+ img = image.Image(os.path.join(self.storage_repository, spUUID))
+ tName = volsByImg.iterkeys()[0]
+ tParams = dom.produceVolume(imgUUID, tName).getVolumeParams()
+ img.createFakeTemplate(sdUUID=sdUUID, volParams=tParams)
self._spmSchedule(spUUID, "deleteImage_%s" % imgUUID, lambda : True)
--
To view, visit http://gerrit.ovirt.org/9208
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6c8c9baecee1ad7aa7789026e533aa254a738097
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
Gerrit-Reviewer: Ayal Baron <abaron(a)redhat.com>
Gerrit-Reviewer: Igor Lvovsky <ilvovsky(a)redhat.com>
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Another missing of joinAll after using ThreadPool
......................................................................
Another missing of joinAll after using ThreadPool
ThreadPool initiates threads during its construct. The threads are
cleaned only by calling joinAll function.
This patch adds this call after using HSM_MailMonitor's threadPool.
Otherwise, the threads will stay alive until vdsm process will be
killed, and this was a leak.
Change-Id: I207d8db5863e11e89394b9144600b625282c51b6
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M vdsm/storage/storage_mailbox.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/09/9009/1
diff --git a/vdsm/storage/storage_mailbox.py b/vdsm/storage/storage_mailbox.py
index c537883..f6f5337 100644
--- a/vdsm/storage/storage_mailbox.py
+++ b/vdsm/storage/storage_mailbox.py
@@ -446,7 +446,7 @@
self.log.info("HSM_MailboxMonitor - Incoming mail monitoring thread stopped, clearing outgoing mail")
self._outgoingMail = EMPTYMAILBOX
self._sendMail() # Clear outgoing mailbox
-
+ self.tp.joinAll(waitForTasks=False)
class SPM_MailMonitor:
--
To view, visit http://gerrit.ovirt.org/9009
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I207d8db5863e11e89394b9144600b625282c51b6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
Zhou Zheng Sheng has uploaded a new change for review.
Change subject: remoteFileHandler: set PYTHONPATH properly for new process
......................................................................
remoteFileHandler: set PYTHONPATH properly for new process
PoolHandler.__init__() starts new process of remoteFileHandler.py.
To set the corrected PYTHONPATH for the new process, it copies existing
os.environ['PYTHONPATH'] and prepends "../:" to it. It's good for unit
test, but not for vdsmd service. When vdsmd.service is running as a
daemon, the current working dir is "/", and PYTHONPATH is not set
actually when vdsm is started. So the existing PYTHONPATH is empty and
"../" refers to "/". When new process of remoteFileHandler.py is started
this way, any attempt to import modules under /usr/share/vdsm will fail.
remoteFileHandler imports misc, and misc imports logUtils. logUtils.py
is under /usr/share/vdsm.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=875678
Change-Id: I8d4a38d5848f74d327b1d9f4ecadc6de6a0cc091
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
M vdsm/storage/remoteFileHandler.py
1 file changed, 7 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/83/9183/1
diff --git a/vdsm/storage/remoteFileHandler.py b/vdsm/storage/remoteFileHandler.py
index 34de3ef..a2a9c41 100644
--- a/vdsm/storage/remoteFileHandler.py
+++ b/vdsm/storage/remoteFileHandler.py
@@ -227,7 +227,13 @@
try:
# Some imports in vdsm assume /usr/share/vdsm is in your PYTHONPATH
env = os.environ.copy()
- env['PYTHONPATH'] = "../:" + env.get('PYTHONPATH', "")
+ env['PYTHONPATH'] = "../"
+ try:
+ if os.environ['PYTHONPATH'] != "":
+ env['PYTHONPATH'] += ":" + os.environ['PYTHONPATH']
+ except KeyError:
+ pass
+ env['PYTHONPATH'] += ":" + constants.P_VDSM
self.process = BetterPopen([constants.EXT_PYTHON, __file__,
str(hisRead), str(hisWrite)], close_fds=False, env=env)
--
To view, visit http://gerrit.ovirt.org/9183
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8d4a38d5848f74d327b1d9f4ecadc6de6a0cc091
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Saggi Mizrahi has uploaded a new change for review.
Change subject: Handle a race where it takes some time fot the cmdline to disappear after killing a process
......................................................................
Handle a race where it takes some time fot the cmdline to disappear after killing a process
Change-Id: I2d7a8190bb3b8e2251309b91f341a00f89618be5
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M tests/miscTests.py
1 file changed, 4 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/04/9204/1
diff --git a/tests/miscTests.py b/tests/miscTests.py
index 6d6b234..964fc74 100644
--- a/tests/miscTests.py
+++ b/tests/miscTests.py
@@ -24,6 +24,7 @@
import threading
from testrunner import VdsmTestCase as TestCaseBase
import inspect
+from vdsm import utils
import storage.outOfProcess as oop
import storage.misc as misc
@@ -86,7 +87,9 @@
sproc = misc.execCmd(args, sync=False, sudo=False)
sproc.kill()
try:
- self.assertEquals(misc.getCmdArgs(sproc.pid), tuple())
+ test = lambda: self.assertEquals(misc.getCmdArgs(sproc.pid),
+ tuple())
+ utils.retry(AssertionError, test, tries=10, sleep=0.1)
finally:
sproc.wait()
--
To view, visit http://gerrit.ovirt.org/9204
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2d7a8190bb3b8e2251309b91f341a00f89618be5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
Saggi Mizrahi has uploaded a new change for review.
Change subject: Fix problem where a 0 error code will cause remoteFileHandler to become a zombie
......................................................................
Fix problem where a 0 error code will cause remoteFileHandler to become a zombie
Change-Id: I738d9739673d11c15b882743d412b9b267013208
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M vdsm/storage/remoteFileHandler.py
1 file changed, 6 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/07/8907/1
diff --git a/vdsm/storage/remoteFileHandler.py b/vdsm/storage/remoteFileHandler.py
index 43ee951..446087b 100644
--- a/vdsm/storage/remoteFileHandler.py
+++ b/vdsm/storage/remoteFileHandler.py
@@ -240,10 +240,12 @@
except:
pass
- # For some reason Thread might have been released if python is going
- # down. This makes sure that there are no issues when this happens
- if self.process.poll() and Thread:
- Thread(target=self.process.wait).start()
+ if not self.process.wait(0):
+ # For some reason Thread might have been released if python is
+ # going down. This makes sure that there are no issues when this
+ # happens
+ if Thread:
+ Thread(target=self.process.wait).start()
def __del__(self):
self.stop()
--
To view, visit http://gerrit.ovirt.org/8907
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I738d9739673d11c15b882743d412b9b267013208
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
Saggi Mizrahi has uploaded a new change for review.
Change subject: Implement a zombie reaper
......................................................................
Implement a zombie reaper
This is meant to solve the issues where one starts a process but doesn't
care about the return value.
By using zombieReaper.autoReapPID(pid) you can register the reaper to
automatically reap your process when it dies.
Change-Id: I0fdf96e195135284b2733b21f611918ffbf69791
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M tests/Makefile.am
A tests/zombieReaperTests.py
M vdsm.spec.in
M vdsm/Makefile.am
M vdsm/vdsm
A vdsm/zombieReaper.py
6 files changed, 81 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/37/8937/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0e3763b..ac9804a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -47,7 +47,9 @@
tcTests.py \
vdsClientTests.py \
remoteFileHandlerTests.py \
- resourceManagerTests.py
+ resourceManagerTests.py \
+ zombieReaperTests.py \
+ $(NULL)
dist_noinst_DATA = \
run_tests_local.sh
diff --git a/tests/zombieReaperTests.py b/tests/zombieReaperTests.py
new file mode 100644
index 0000000..6406ce3
--- /dev/null
+++ b/tests/zombieReaperTests.py
@@ -0,0 +1,42 @@
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+from time import sleep
+import os
+
+from testrunner import VdsmTestCase as TestCaseBase
+import zombieReaper
+from vdsm.betterPopen import BetterPopen
+
+
+class zombieReaperTests(TestCaseBase):
+ def setUp(self):
+ zombieReaper.registerSignalHandler()
+
+ def tearDown(self):
+ zombieReaper.unregisterSignalHandler()
+
+ def test(self):
+ p = BetterPopen(["sleep", "1"])
+ zombieReaper.autoReapPID(p.pid)
+ # wait for the grim reaper to arrive
+ sleep(4)
+
+ # Throws error because pid is not found or is not child
+ self.assertRaises(OSError, os.waitpid, p.pid, os.WNOHANG)
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 37f37a3..649581f 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -625,6 +625,7 @@
%{_datadir}/%{vdsm_name}/vdsm-store-net-config
%{_datadir}/%{vdsm_name}/vm.py*
%{_datadir}/%{vdsm_name}/write-net-config
+%{_datadir}/%{vdsm_name}/zombieReaper.py*
%attr (755,vdsm,kvm) %{_datadir}/%{vdsm_name}/nwfilter.py*
%config(noreplace) %{_sysconfdir}/%{vdsm_name}/logger.conf
%config(noreplace) %{_sysconfdir}/%{vdsm_name}/mom.conf
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 7c79036..76a81c6 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -52,6 +52,7 @@
vdsmDebugPlugin.py \
vmChannels.py \
vm.py \
+ zombieReaper.py \
$(NULL)
dist_vdsmpylib_PYTHON = \
diff --git a/vdsm/vdsm b/vdsm/vdsm
index f2db404..00b99a0 100755
--- a/vdsm/vdsm
+++ b/vdsm/vdsm
@@ -20,6 +20,7 @@
from logging import config as lconfig
from vdsm import constants
+import zombieReaper
import dsaversion
if sys.version_info[0] == 2:
# as long as we work with Python 2, we need to monkey-patch threading
@@ -49,6 +50,7 @@
signal.signal(signal.SIGTERM, sigtermHandler)
signal.signal(signal.SIGUSR1, sigusr1Handler)
+ zombieReaper.registerSignalHandler()
from clientIF import clientIF # must import after config is read
cif = clientIF.getInstance(log)
diff --git a/vdsm/zombieReaper.py b/vdsm/zombieReaper.py
new file mode 100644
index 0000000..74b311d
--- /dev/null
+++ b/vdsm/zombieReaper.py
@@ -0,0 +1,32 @@
+import os
+import signal
+
+_trackedPids = set()
+
+
+def autoReapPID(pid):
+ _trackedPids.add(pid)
+ # SIGCHLD happend before we added the pid to the set
+ _tryReap(pid)
+
+
+def _tryReap(pid):
+ try:
+ pid, rv = os.waitpid(pid, os.WNOHANG)
+ if pid != 0:
+ _trackedPids.discard(pid)
+ except OSError:
+ _trackedPids.discard(pid)
+
+
+def _zombieReaper(signum, frame):
+ for pid in _trackedPids.copy():
+ _tryReap(pid)
+
+
+def registerSignalHandler():
+ signal.signal(signal.SIGCHLD, _zombieReaper)
+
+
+def unregisterSignalHandler():
+ signal.signal(signal.SIGCHLD, signal.SIG_DFL)
--
To view, visit http://gerrit.ovirt.org/8937
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0fdf96e195135284b2733b21f611918ffbf69791
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
Adam Litke has uploaded a new change for review.
Change subject: jsonrpc: Implement the JsonRPC server for the next-gen API
......................................................................
jsonrpc: Implement the JsonRPC server for the next-gen API
This patch implements a new Binding plugin to serve the next generation vdsm API
over a JsonRPC wire protocol. The basic format of a message is:
<size><json-data>
<size> is an unsigned 64 bit integer in big endian format that indicates the
length of <json-data> in bytes. <json-data> is either a request or a response
in Javascript object notation (JSON).
A request object has the following fields:
id: An integer which will be repeated in the matching response
methodName: The name of the API method to be called
args (optional): A JSON object containing arguments to the method
A response object has the following fields:
id: An integer which will be the same as the matching request
result: The return value of the method (defined in the API schema)
error: A JSON object containing error information
code: An integer error code
message: Error context information
Method calls are dispatched to vdsm using a MethodBridge. The DynamicBridge
dispatches calls based on an API schema document and a set of schema exceptions.
In this way, the API can be expanded without the need to add more code to this
server infrastructure. When a request is made, the DynamicBridge attempts to
resolve 'methodName' to a schema defined method. If found, the necessary
arguments are collected from the request and the function call is dispatched to
the internal vdsm API.
Schema exceptions:
Currently, vdsm does not completely conform to its own API schema. It is not
possible to correct all of the discrepencies due to the need to maintain
backwards compatibility with current API users. To facilitate migration to this
API, the DynamicBridge implements a set of overrides to translate between the
schema-defined API and what is implemented in vdsm today. There are three types
of method overrides and one type of argument override:
Method overrides:
1. Custom call function: If a new API does not map directly to an existing vdsm
API (or multiple functions must be called to get the result), a custom 'call'
function can be defined for the API. This function will be called instead of
trying to find a vdsm API to call.
2. Return field name: Many vdsm functions' return values are nested in a
dictionary. This override specifies the key to use when accessing the result
so that it can be returned un-nested to the caller.
3. Custom result post-processing function: Some vdsm APIs return results in a
non-standard format and a special function must be used to reformat the data
to comply with the schema.
Type override:
Some data types have a different representation internally to vdsm than we have
defined in the schema. A type override can be used to convert between the two
formats. Currently, the only kind of translation we do is to rename fields
within a given type.
Change-Id: Idae0faa80ffc6a5af002a8a7151aa40dc9a6673d
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M Makefile.am
M configure.ac
M tests/Makefile.am
A tests/apiData.py
A tests/apiTests.py
M tests/run_tests_local.sh.in
M vdsm.spec.in
M vdsm/clientIF.py
M vdsm/config.py.in
A vdsm_api/BindingJsonRpc.py
A vdsm_api/Bridge.py
A vdsm_api/Makefile.am
12 files changed, 725 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/14/8614/1
diff --git a/Makefile.am b/Makefile.am
index 7548f42..b1a0418 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
-SUBDIRS = vdsm vdsm_cli vds_bootstrap vdsm_reg vdsm_hooks tests vdsm-tool
+SUBDIRS = vdsm vdsm_cli vds_bootstrap vdsm_reg vdsm_hooks tests vdsm-tool vdsm_api
include $(top_srcdir)/build-aux/Makefile.subs
@@ -112,8 +112,7 @@
vds_bootstrap/miniyum.py \
$(NULL)
-PEP8_BLACKLIST = \
- restData.py
+PEP8_BLACKLIST = apiData.py,restData.py
check-local:
find . -path './.git' -prune -type f -o \
diff --git a/configure.ac b/configure.ac
index 450f714..679ad04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,6 +79,7 @@
AC_SUBST([vdsmpylibdir], ['${pyexecdir}/vdsm'])
AC_SUBST([vdsmtooldir], ['${vdsmpylibdir}/tool'])
AC_SUBST([vdsmtestsdir], ['${datarootdir}/vdsm/tests'])
+AC_SUBST([vdsmapidir], ['${datarootdir}/vdsm_api'])
# VDSM registration default paths
AC_SUBST([vdsmregdir], ['${datarootdir}/vdsm-reg'])
@@ -191,6 +192,7 @@
tests/Makefile
tests/functional/Makefile
vds_bootstrap/Makefile
+ vdsm_api/Makefile
vdsm_cli/Makefile
vdsm_hooks/directlun/Makefile
vdsm_hooks/faqemu/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2b61dde..d1fca34 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -22,6 +22,7 @@
test_modules = \
alignmentScanTests.py \
+ apiTests.py \
betterPopenTests.py \
betterThreadingTests.py \
capsTests.py \
@@ -66,6 +67,7 @@
dist_vdsmtests_PYTHON = \
$(test_modules) \
+ apiData.py \
monkeypatch.py \
testrunner.py \
testValidation.py
diff --git a/tests/apiData.py b/tests/apiData.py
new file mode 100644
index 0000000..fdb2611
--- /dev/null
+++ b/tests/apiData.py
@@ -0,0 +1,10 @@
+class APIData(object):
+ def __init__(self, obj, meth, data):
+ self.obj = obj
+ self.meth = meth
+ self.data = data
+
+testPing_apidata = [
+ APIData('Global', 'ping', {
+ 'status': {'code': 0, 'message': 'OK'}})
+]
diff --git a/tests/apiTests.py b/tests/apiTests.py
new file mode 100644
index 0000000..9bfe347
--- /dev/null
+++ b/tests/apiTests.py
@@ -0,0 +1,228 @@
+#
+# Copyright 2012 Adam Litke, IBM Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import logging
+import os
+import os.path
+import socket
+import json
+import struct
+import time
+
+from testrunner import VdsmTestCase as TestCaseBase
+from vdsm import constants
+import apiData
+
+ip = '0.0.0.0'
+port = 9824
+_fakeret = {}
+
+apiWhitelist = ('StorageDomain.Classes', 'StorageDomain.Types',
+ 'Volume.Formats', 'Volume.Types', 'Volume.Roles', 'Image.DiskTypes')
+
+
+def getFakeAPI():
+ """
+ Create a Mock API module for testing. Mock API will return data from
+ the _fakeret global variable instead of calling into vdsm. _fakeret is
+ expected to have the following format:
+
+ {
+ '<class1>': {
+ '<func1>': [ <ret1>, <ret2>, ... ],
+ '<func2>': [ ... ],
+ }, '<class2>': {
+ ...
+ }
+ }
+ """
+ class FakeObj(object):
+ def __new__(cls, *args, **kwargs):
+ return object.__new__(cls)
+
+ def default(self, *args, **kwargs):
+ try:
+ return _fakeret[self.type][self.lastFunc].pop(0)
+ except (KeyError, IndexError):
+ raise Exception("No API data avilable for %s.%s" % \
+ (self.type, self.lastFunc))
+
+ def __getattr__(self, name):
+ # While we are constructing the API module, use the normal getattr
+ if 'API' not in sys.modules:
+ return object.__getattr__(name)
+ self.lastFunc = name
+ return self.default
+
+ import sys
+ import imp
+ from new import classobj
+
+ _API = __import__('API', globals(), locals(), {}, -1)
+ _newAPI = imp.new_module('API')
+
+ for obj in ('Global', 'ConnectionRefs', 'StorageDomain', 'Image', 'Volume',
+ 'Task', 'StoragePool', 'VM'):
+ cls = classobj(obj, (FakeObj,), {'type': obj})
+ setattr(_newAPI, obj, cls)
+
+ # Apply the whitelist to our version of API
+ for name in apiWhitelist:
+ parts = name.split('.')
+ dstObj = _newAPI
+ srcObj = _API
+ # Walk the object hierarchy copying each component of the whitelisted
+ # attribute from the real API to our fake one
+ for obj in parts:
+ srcObj = getattr(srcObj, obj)
+ try:
+ dstObj = getattr(dstObj, obj)
+ except AttributeError:
+ setattr(dstObj, obj, srcObj)
+
+ # Install our fake API into the module table for use by the whole program
+ sys.modules['API'] = _newAPI
+
+
+def findSchema():
+ """
+ Find the API schema file whether we are running tests from the source dir
+ or from the tests install location
+ """
+ scriptdir = os.path.dirname(__file__)
+ localpath = os.path.join(scriptdir, '../vdsm_api/vdsmapi-schema.json')
+ installedpath = os.path.join(constants.P_VDSM, 'vdsmapi-schema.json')
+ for f in localpath, installedpath:
+ if os.access(f, os.R_OK):
+ return f
+ raise Exception("Unable to find schema in %s or %s",
+ localpath, installedpath)
+
+def setUpModule():
+ """
+ Set up the environment for all tests:
+ 1. Override the API so we can program our own return values
+ 2. Start an embedded server to process our requests
+ """
+ log = logging.getLogger('apiTests')
+ handler = logging.StreamHandler()
+ fmt_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
+ formatter = logging.Formatter(fmt_str)
+ handler.setFormatter(formatter)
+ handler.setLevel(logging.INFO)
+ log.addHandler(handler)
+
+ schema = findSchema()
+ getFakeAPI()
+ import BindingJsonRpc
+ import Bridge
+ bridge = Bridge.DynamicBridge(schema)
+ server = BindingJsonRpc.BindingJsonRpc(bridge, ip, port)
+ server.start()
+
+
+class APITest(TestCaseBase):
+ def expectAPI(self, obj, meth, retval):
+ global _fakeret
+ if obj not in _fakeret:
+ _fakeret[obj] = {}
+ if meth not in _fakeret[obj]:
+ _fakeret[obj][meth] = []
+ _fakeret[obj][meth].append(retval)
+
+ def programAPI(self, key):
+ key += '_apidata'
+ for item in getattr(apiData, key):
+ self.expectAPI(item.obj, item.meth, item.data)
+
+ def clearAPI(self):
+ global _fakeret
+ _fakeret = {}
+
+class JsonRawTest(APITest):
+ _Size = struct.Struct("!Q")
+
+ def buildMessage(self, data):
+ msg = json.dumps(data)
+ msg = msg.encode('utf-8')
+ msize = JsonRawTest._Size.pack(len(msg))
+ resp = msize + msg
+ return resp
+
+ def sendMessage(self, msg):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ sock.connect((ip, port))
+ sock.sendall(msg)
+ data = sock.recv(JsonRawTest._Size.size)
+ msgLen = JsonRawTest._Size.unpack(data)[0]
+ data = sock.recv(msgLen)
+ return json.loads(data)
+ finally:
+ sock.close()
+
+ def testPing(self):
+ self.clearAPI()
+ self.programAPI("testPing")
+ msg = self.buildMessage({'id': 1, 'methodName': 'Host.ping',
+ 'args': {}})
+ reply = self.sendMessage(msg)
+ self.assertEquals(0, reply['error']['code'])
+ self.assertEquals('Success', reply['error']['message'])
+
+ def testNoMethod(self):
+ msg = self.buildMessage({'id': 1, 'methodName': 'Host.fake'})
+ reply = self.sendMessage(msg)
+ self.assertEquals(4, reply['error']['code'])
+
+ def testBadMethod(self):
+ msg = self.buildMessage({'id': 1, 'methodName': 'malformed\''})
+ reply = self.sendMessage(msg)
+ self.assertEquals(4, reply['error']['code'])
+
+ def testMissingSize(self):
+ self.assertRaises(struct.error, self.sendMessage,
+ "malformed message")
+
+ def testNotJson(self):
+ msg = "malformed message"
+ msize = JsonRawTest._Size.pack(len(msg))
+ msg = msize + msg
+ self.assertRaises(struct.error, self.sendMessage, msg)
+
+ def testSynchronization(self):
+ def doPing(msg):
+ self.clearAPI()
+ self.programAPI("testPing")
+ return self.sendMessage(msg)['error']['code']
+
+ msg = self.buildMessage({'id': 1, 'methodName': 'Host.ping'})
+ # Send Truncated message
+ self.assertRaises(struct.error, doPing, msg[:-1])
+
+ # Test that the server recovers
+ self.assertEquals(0, doPing(msg))
+
+ # Send too much data
+ self.assertEquals(0, doPing(msg + "Hello"))
+
+ # Test that the server recovers
+ self.assertEquals(0, doPing(msg))
+
diff --git a/tests/run_tests_local.sh.in b/tests/run_tests_local.sh.in
index fc4ac37..8f668f9 100644
--- a/tests/run_tests_local.sh.in
+++ b/tests/run_tests_local.sh.in
@@ -1,2 +1,2 @@
#!/bin/sh
-PYTHONDONTWRITEBYTECODE=1 LC_ALL=C PYTHONPATH="@builddir@/vdsm:@top_srcdir@/vdsm:@top_srcdir@/vdsm_cli:$PYTHONPATH" @PYTHON@ @top_srcdir@/tests/testrunner.py --local-modules $@
+PYTHONDONTWRITEBYTECODE=1 LC_ALL=C PYTHONPATH="@builddir@/vdsm:@top_srcdir@/vdsm:@top_srcdir@/vdsm_cli:@top_srcdir@/vdsm_api:$PYTHONPATH" @PYTHON@ @top_srcdir@/tests/testrunner.py --local-modules $@
diff --git a/vdsm.spec.in b/vdsm.spec.in
index dce14a9..8e7fa6c 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -154,6 +154,15 @@
%description rest
A REST interface for interacting with vdsmd.
+%package jsonrpc
+Summary: VDSM API Server
+BuildArch: noarch
+
+Requires: %{name}-python = %{version}-%{release}
+
+%description jsonrpc
+A Json-based RPC interface that serves as the protocol for libvdsm.
+
%package bootstrap
Summary: VDSM bootstrapping package
BuildArch: noarch
@@ -912,6 +921,12 @@
%{_datadir}/%{vdsm_name}/rest/templates/api.xsd
%{_datadir}/%{vdsm_name}/rest/templates/rsdl.xml
+%files jsonrpc
+%{_datadir}/%{vdsm_name}/BindingJsonRpc.py*
+%{_datadir}/%{vdsm_name}/Bridge.py*
+%{_datadir}/%{vdsm_name}/vdsmapi.py*
+%{_datadir}/%{vdsm_name}/vdsmapi-schema.json
+
%files bootstrap
%defattr(-, root, root, -)
%doc COPYING
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index e9ca7c9..cf8468c 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -158,6 +158,15 @@
self.bindings['rest'] = BindingREST(self, self.log, ip, rest_port,
templatePath)
+ def _loadBindingJsonRpc(self):
+ from BindingJsonRpc import BindingJsonRpc
+ from Bridge import DynamicBridge
+ schema = os.path.join(constants.P_VDSM, 'vdsmapi-schema.json')
+ ip = self._getServerIP(config.get('addresses', 'management_ip'))
+ port = config.getint('addresses', 'json_port')
+ self.bindings['json'] = BindingJsonRpc(DynamicBridge(schema),
+ ip, port)
+
def _prepareBindings(self):
self.bindings = {}
if config.getboolean('vars', 'xmlrpc_enable'):
@@ -172,6 +181,12 @@
except ImportError:
self.log.warn('Unable to load the rest server module. '
'Please make sure it is installed.')
+ if config.getboolean('vars', 'jsonrpc_enable'):
+ try:
+ self._loadBindingJsonRpc()
+ except ImportError:
+ self.log.warn('Unable to load the json rpc server module. '
+ 'Please make sure it is installed.')
def _prepareMOM(self):
try:
diff --git a/vdsm/config.py.in b/vdsm/config.py.in
index df85e7e..51a7ad6 100644
--- a/vdsm/config.py.in
+++ b/vdsm/config.py.in
@@ -130,6 +130,8 @@
('rest_enable', 'true', 'Enable the REST server'),
+ ('jsonrpc_enable', 'true', 'Enable the JSON RPC server'),
+
('report_host_threads_as_cores', 'false',
'Count each cpu hyperthread as an individual core'),
]),
@@ -251,6 +253,10 @@
'Port on which the vdsmd REST server listens to network '
'clients.'),
+ ('json_port', '4044',
+ 'Port on which the vdsmd Json RPC server listens to network '
+ 'clients.'),
+
('management_ip', '', None),
('guests_gateway_ip', '', None),
diff --git a/vdsm_api/BindingJsonRpc.py b/vdsm_api/BindingJsonRpc.py
new file mode 100644
index 0000000..9ac8b5d
--- /dev/null
+++ b/vdsm_api/BindingJsonRpc.py
@@ -0,0 +1,99 @@
+# VDSM JsonRPC Server
+# Copyright (C) 2012 Adam Litke, IBM Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import threading
+import SocketServer
+import json
+import logging
+
+import struct
+
+_Size = struct.Struct("!Q")
+
+__bridge__ = None
+
+class BindingJsonRpc:
+ def __init__(self, bridge, ip, port):
+ self.bridge = bridge
+ self.serverPort = port
+ self.serverIP = ip
+ self.log = logging.getLogger('BindingJsonRpc')
+ self._createServer()
+
+ def _createServer(self):
+ global __bridge__
+ __bridge__ = self.bridge
+ ip = self.serverIP or '0.0.0.0'
+ self.server = JsonRpcServer((ip, self.serverPort), JsonRpcTCPHandler)
+
+ def start(self):
+ def threaded_start():
+ self.server.serve_forever()
+ t = threading.Thread(target=threaded_start,
+ name='JsonRpc')
+ t.setDaemon(True)
+ t.start()
+
+ def prepareForShutdown(self):
+ self.server.shutdown()
+
+
+class JsonRpcServer(SocketServer.TCPServer):
+ def __init__(self, addrInfo, handler):
+ self.allow_reuse_address = True
+ SocketServer.TCPServer.__init__(self, addrInfo, handler)
+
+
+class JsonRpcTCPHandler(SocketServer.StreamRequestHandler):
+ """
+ The RequestHandler class for our server.
+
+ It is instantiated once per connection to the server, and must
+ override the handle() method to implement communication to the
+ client.
+ """
+
+ def handle(self):
+ bridge = __bridge__
+ log = logging.getLogger('JsonRpcTCPHandler')
+ while True:
+ # self.request is the TCP socket connected to the client
+ try:
+ data = self.request.recv(_Size.size)
+ if len(data) == 0:
+ log.debug("Connection closed")
+ return
+ msgLen = _Size.unpack(data)[0]
+ msg = json.loads(self.request.recv(msgLen))
+ except:
+ log.warn("Unexpected exception", exc_info=True)
+ return
+ log.debug('--> %s', msg)
+
+ try:
+ ret = bridge._dispatch(msg['methodName'], msg.get('args', {}))
+ except Exception:
+ log.error("Dispatch error", exc_info=True)
+ continue
+ ret['id'] = msg['id']
+ msg = json.dumps(ret)
+ msg = msg.encode('utf-8')
+ msize = _Size.pack(len(msg))
+ resp = msize + msg
+ log.debug('<-- %s', msg)
+
+ self.wfile.write(resp)
+ self.wfile.flush()
+
diff --git a/vdsm_api/Bridge.py b/vdsm_api/Bridge.py
new file mode 100644
index 0000000..7402e08
--- /dev/null
+++ b/vdsm_api/Bridge.py
@@ -0,0 +1,332 @@
+# VDSM API Connector
+# Copyright (C) 2012 Adam Litke, IBM Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from functools import partial
+import vdsmapi
+import logging
+import types
+import API
+
+class VdsmError(Exception):
+ def __init__(self, code, message):
+ self.code = code
+ self.message = message
+
+class MethodBridge(object):
+
+ def _dispatch(self, name, argobj):
+ method = name.replace('.', '_')
+ result = None
+ error = {'code': 0, 'message': 'Success'}
+ try:
+ fn = getattr(self, method)
+ except AttributeError:
+ error = {'code': 4,
+ 'message': "Operation '%s' not supported" % name}
+ return {'result': result, 'error': error}
+ try:
+ result = fn(argobj)
+ except VdsmError, e:
+ error = {'code': e.code, 'message': e.message}
+ except Exception, e:
+ error = {'code': 5, 'message': 'Internal error: %s' % e}
+ return {'result': result, 'error': error}
+
+ def getArgs(self, argobj, arglist):
+ ret = ()
+ for arg in arglist:
+ if arg in argobj:
+ ret += (argobj[arg],)
+ return ret
+
+ def getResult(self, response, member=None):
+ if member is None:
+ return None
+ try:
+ return response[member]
+ except KeyError:
+ raise VdsmError(5, "Response is missing '%s' member" % member)
+
+class DynamicBridge(MethodBridge):
+ def __init__(self, schema):
+ self.parseSchema(schema)
+
+
+ def parseSchema(self, schema):
+ self.commands = {}
+ self.classes = {}
+ self.types = {}
+ with open(schema) as f:
+ symbols = vdsmapi.parse_schema(f)
+ for s in symbols:
+ if 'command' in s:
+ key = "%s_%s" % (s['command']['class'],
+ s['command']['name'])
+ self.commands[key] = s
+ elif 'class' in s:
+ cls = s['class']
+ self.classes[cls] = s
+ elif 'type' in s:
+ t = s['type']
+ self.types[t] = s
+
+
+ def __getattr__(self, attr):
+ if attr in self.commands:
+ cls, name = attr.split('_')
+ return partial(self.dynamicMethod, cls, name)
+ else:
+ raise AttributeError
+
+
+ def getArgList(self, cmd):
+ return self.commands[cmd].get('data', {}).keys()
+
+
+ def getObjargList(self, cls):
+ return self.classes[cls]['data'].keys()
+
+ def getApiClass(self, cls):
+ name_map = { 'Host': 'Global' }
+ try:
+ cls = name_map[cls]
+ except KeyError:
+ pass
+ return getattr(API, cls)
+
+ def typeFixup(self, sym_name, sym_type, obj):
+ logging.info("typeFixup: '%s': '%s'" % (sym_name, sym_type))
+ isList = False
+ if type(sym_type) is list:
+ sym_type = sym_type[0]
+ isList = True
+ if sym_name[0] == '*':
+ sym_name = sym_name[1:]
+
+ try:
+ symbol = self.types[sym_type]
+ except KeyError:
+ return
+
+ if isList:
+ itemList = obj
+ else:
+ itemList = [obj]
+
+ for item in itemList:
+ if sym_type in typefixups:
+ logging.error("Fixing up type %s", sym_type)
+ typefixups[sym_type](item)
+ for (k, v) in symbol.get('data', {}).items():
+ if k[0] == '*':
+ k = k[1:]
+ if k in item:
+ self.typeFixup(k, v, item[k])
+
+
+ def fixupArgs(self, cmd, args):
+ argInfo = zip(self.commands[cmd].get('data', {}).items(), args)
+ for typeInfo, val in argInfo:
+ argName, argType = typeInfo
+ if argType not in self.types:
+ continue
+ self.typeFixup(argName, argType, val)
+
+ def fixupRet(self, cmd, result):
+ retType = self.commands[cmd].get('returns', None)
+ if retType is not None:
+ self.typeFixup('return', retType, result)
+ return result
+
+ def dynamicMethod(self, cls, name, argobj):
+ cmd = '%s_%s' % (cls, name)
+ ctorArgObj = argobj.get('__obj__', {})
+ ctorargs = self.getArgs(ctorArgObj, self.getObjargList(cls))
+ args = self.getArgs(argobj, self.getArgList(cmd))
+ apiobj = self.getApiClass(cls)
+ api = apiobj(*ctorargs)
+
+ self.fixupArgs(cmd, args)
+
+ # Call the override function (if given). Otherwise, just call directly
+ fn = command_info.get(cmd, {}).get('call')
+ if fn:
+ result = fn(api, argobj)
+ else:
+ fn = getattr(api, name)
+ result = fn(*args)
+
+ if result['status']['code']:
+ code = result['status']['code']
+ msg = result['status']['message']
+ return {'code': code, 'message': msg}
+
+ retfield = command_info.get(cmd, {}).get('ret')
+ if type(retfield) == types.FunctionType:
+ ret = retfield(result)
+ else:
+ ret = self.getResult(result, retfield)
+ return self.fixupRet(cmd, ret)
+
+
+def Host_getStorageRepoStats_Ret(ret):
+ """
+ The returned dictionary doesn't separate the stats from the status code
+ so we need to rebuild the result.
+ """
+ del ret['status']
+ return ret
+
+
+def Host_getVMList_Call(api, args):
+ """
+ This call is only interested in returning the VM UUIDs so pass False for
+ the first argument in order to suppress verbose results.
+ """
+ vmList = args.get('vmList', [])
+ return API.Global().getVMList(False, vmList)
+
+def Host_getVMList_Ret(ret):
+ """
+ Just return a list of VM UUIDs
+ """
+ return [v['vmId'] for v in ret['vmList']]
+
+
+def StoragePool_getInfo_Ret(ret):
+ """
+ The result contains two data structures which must be merged
+ """
+ return {'info': ret['info'], 'dominfo': ret['dominfo']}
+
+
+def VM_getInfo_Call(api, args):
+ """
+ The VM object has no getInfo method. We use the method from 'Global' and
+ pass arguments to get verbose information for only this one VM.
+ """
+ vmId = api._UUID
+ return API.Global().getVMList(True, [vmId])
+
+def VM_getInfo_Ret(ret):
+ """
+ The result will be a list with only one element.
+ """
+ return ret['vmList'][0]
+
+def VM_migrationCreate_Ret(ret):
+ """
+ The result contains two data structures which must be merged
+ """
+ return {'params': ret['params'], 'migrationPort': ret['migrationPort']}
+
+
+def Volume_getsize_Ret(ret):
+ """
+ Merge the two sizes into a single dictionary result.
+ """
+ return {'truesize': ret['truesize'], 'apparentsize': ret['apparentsize']}
+
+
+##
+# Possible ways to override a command:
+# - Supply a custom call function if the function name doesn't map directly to
+# a vdsm API.
+# - Specify the name of the field in the result that is the return value
+# - Specify a custom function to post-process the result into a return value
+##
+command_info = {
+ 'ConnectionRefs_acquire': {'ret': 'results'},
+ 'ConnectionRefs_release': {'ret': 'results'},
+ 'ConnectionRefs_statuses': {'ret': 'connectionslist'},
+ 'Host_fenceNode': {'ret': 'power'},
+ 'Host_getAllTasksInfo': {'ret': 'allTasksInfo'},
+ 'Host_getAllTasksStatuses': {'ret': 'allTasksStatus'},
+ 'Host_getCapabilities': {'ret': 'info'},
+ 'Host_getConnectedStoragePools': {'ret': 'poollist'},
+ 'Host_getDeviceInfo': {'ret': 'info'},
+ 'Host_getDeviceList': {'ret': 'devList'},
+ 'Host_getDevicesVisibility': {'ret': 'visibility'},
+ 'Host_getLVMVolumeGroups': {'ret': 'vglist'},
+ 'Host_getStats': {'ret': 'info'},
+ 'Host_getStorageDomains': {'ret': 'domlist'},
+ 'Host_getStorageRepoStats': {'ret': Host_getStorageRepoStats_Ret},
+ 'Host_getVMList': {'call': Host_getVMList_Call, 'ret': Host_getVMList_Ret},
+ 'Image_delete': {'ret': 'uuid'},
+ 'Image_deleteVolumes': {'ret': 'uuid'},
+ 'Image_getVolumes': {'ret': 'uuidlist'},
+ 'Image_mergeSnapshots': {'ret': 'uuid'},
+ 'Image_move': {'ret': 'uuid'},
+ 'ISCSIConnection_discoverSendTargets': {'ret': 'fullTargets'},
+ 'LVMVolumeGroup_create': {'ret': 'uuid'},
+ 'LVMVolumeGroup_getInfo': {'ret': 'info'},
+ 'StorageDomain_getFileList': {'ret': 'files'},
+ 'StorageDomain_getImages': {'ret': 'imageslist'},
+ 'StorageDomain_getInfo': {'ret': 'info'},
+ 'StorageDomain_getStats': {'ret': 'stats'},
+ 'StorageDomain_getVolumes': {'ret': 'uuidlist'},
+ 'StoragePool_connectStorageServer': {'ret': 'statuslist'},
+ 'StoragePool_disconnectStorageServer': {'ret': 'statuslist'},
+ 'StoragePool_fence': {'ret': 'spm_st'},
+ 'StoragePool_getBackedUpVmsInfo': {'ret': 'vmlist'},
+ 'StoragePool_getBackedUpVmsList': {'ret': 'vmlist'},
+ 'StoragePool_getDomainsContainingImage': {'ret': 'domainslist'},
+ 'StoragePool_getFloppyList': {'ret': 'isolist'},
+ 'StoragePool_getInfo': {'ret': StoragePool_getInfo_Ret},
+ 'StoragePool_getIsoList': {'ret': 'isolist'},
+ 'StoragePool_getSpmStatus': {'ret': 'spm_st'},
+ 'StoragePool_spmStart': {'ret': 'uuid'},
+ 'StoragePool_upgrade': {'ret': 'upgradeStatus'},
+ 'StoragePool_validateStorageServerConnection': {'ret': 'statuslist'},
+ 'Task_getInfo': {'ret': 'TaskInfo'},
+ 'Task_getStatus': {'ret': 'taskStatus'},
+ 'VM_changeCD': {'ret': 'vmList'},
+ 'VM_changeFloppy': {'ret': 'vmList'},
+ 'VM_create': {'ret': 'vmList'},
+ 'VM_getInfo': {'call': VM_getInfo_Call, 'ret': VM_getInfo_Ret},
+ 'VM_getStats': {'ret': 'statsList'},
+ 'VM_hotplugDisk': {'ret': 'vmList'},
+ 'VM_hotplugNic': {'ret': 'vmList'},
+ 'VM_hotUnplugDisk': {'ret': 'vmList'},
+ 'VM_hotUnplugNic': {'ret': 'vmList'},
+ 'VM_mergeStatus': {'ret': 'mergeStatus'},
+ 'VM_migrationCreate': {'ret': VM_migrationCreate_Ret},
+ 'Volume_copy': {'ret': 'uuid'},
+ 'Volume_create': {'ret': 'uuid'},
+ 'Volume_delete': {'ret': 'uuid'},
+ 'Volume_getInfo': {'ret': 'info'},
+ 'Volume_getPath': {'ret': 'path'},
+ 'Volume_getSize': {'ret': Volume_getsize_Ret},
+ 'Host_getAllTasks': {'ret': 'TasksDetails'},
+}
+
+
+def fieldClone(oldName, newName, obj):
+ logging.warning("fieldClone: %s -> %s", oldName, newName)
+ if oldName in obj:
+ obj[newName] = obj[oldName]
+ elif newName in obj:
+ obj[oldName] = obj[newName]
+
+typefixups = {
+ 'VmDevice': partial(fieldClone, 'type', 'deviceType'),
+ 'BlockDevicePathInfo': partial(fieldClone, 'type', 'deviceType'),
+ 'VolumeGroupInfo': partial(fieldClone, 'type', 'deviceType'),
+ 'VmDeviceAddress': partial(fieldClone, 'type', 'addressType'),
+ 'IscsiCredentials': partial(fieldClone, 'type', 'authType'),
+ 'ConnectionRefArgs': partial(fieldClone, 'type', 'connType'),
+ 'VolumeInfo': partial(fieldClone, 'type', 'allocType'),
+}
diff --git a/vdsm_api/Makefile.am b/vdsm_api/Makefile.am
new file mode 100644
index 0000000..655586f
--- /dev/null
+++ b/vdsm_api/Makefile.am
@@ -0,0 +1,13 @@
+EXTRA_DIST = \
+ vdsmapi-schema.json \
+ $(NULL)
+
+dist_vdsm_PYTHON = \
+ BindingJsonRpc.py \
+ Bridge.py \
+ vdsmapi.py \
+ $(NULL)
+
+dist_vdsm_DATA = \
+ vdsmapi-schema.json \
+ $(NULL)
--
To view, visit http://gerrit.ovirt.org/8614
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idae0faa80ffc6a5af002a8a7151aa40dc9a6673d
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Hercinger Viktor has uploaded a new change for review.
Change subject: netinfo: added configuration to show dummy NIC's too
......................................................................
netinfo: added configuration to show dummy NIC's too
With the vars.fake_nics configuration a list of comma-separated
interfaces can be specified. If a dummy interface matches the
fnmatch pattern, it will be included in the NIC list.
Change-Id: Ica0ad974e6dd0d144a6bb0904fdcd6bbce99ff9f
Signed-off-by: Hercinger Viktor <hercinger.viktor(a)gmail.com>
---
M tests/netinfoTests.py
M vdsm/netinfo.py
2 files changed, 18 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/17/8917/1
diff --git a/tests/netinfoTests.py b/tests/netinfoTests.py
index f5a4b95..a678fbc 100644
--- a/tests/netinfoTests.py
+++ b/tests/netinfoTests.py
@@ -23,6 +23,7 @@
from testrunner import VdsmTestCase as TestCaseBase
from vdsm import netinfo
+from vdsm import config
from monkeypatch import MonkeyPatch
# speeds defined in ethtool
@@ -66,3 +67,6 @@
# just log a traceback. If it raises an exception the test will fail as
# it should.
netinfo.get()
+
+ def testMatchNicName(self):
+ self.assertTrue(netinfo.match_nic_name('test1', ['test0', 'test1']))
diff --git a/vdsm/netinfo.py b/vdsm/netinfo.py
index c3c5a6f..26ad247 100644
--- a/vdsm/netinfo.py
+++ b/vdsm/netinfo.py
@@ -19,6 +19,7 @@
#
import os
+import os.path
import errno
import glob
import ethtool
@@ -43,13 +44,22 @@
LIBVIRT_NET_PREFIX = 'vdsm-'
+def match_nic_name(nic, patterns):
+ return any(map(lambda p: fnmatch(nic, p), patterns))
+
def nics():
res = []
- for b in glob.glob('/sys/class/net/*/device'):
- nic = b.split('/')[-2]
- if not any(map(lambda p: fnmatch(nic, p),
- config.get('vars', 'hidden_nics').split(','))):
+ hidden_nics = config.get('vars', 'hidden_nics').split(',')
+ fake_nics = config.get('vars', 'fake_nics').split(',')
+
+ for b in glob.glob('/sys/class/net/*'):
+ nic = b.split('/')[-1]
+ if not os.path.exists(os.path.join(b, 'device')):
+ if match_nic_name(nic, fake_nics):
+ res.append(nic)
+ elif not match_nic_name(nic, hidden_nics):
res.append(nic)
+
return res
--
To view, visit http://gerrit.ovirt.org/8917
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ica0ad974e6dd0d144a6bb0904fdcd6bbce99ff9f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Hercinger Viktor <hercinger.viktor(a)gmail.com>
Dan Kenigsberg has uploaded a new change for review.
Change subject: storage/threadPool: fix copyright notice
......................................................................
storage/threadPool: fix copyright notice
Change-Id: Ib6a06dc60f53f12793a93bb71cd3d5bfec4cc0d1
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm/storage/threadPool.py
1 file changed, 5 insertions(+), 17 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/19/9119/1
diff --git a/vdsm/storage/threadPool.py b/vdsm/storage/threadPool.py
index 4cf4568..22633b7 100644
--- a/vdsm/storage/threadPool.py
+++ b/vdsm/storage/threadPool.py
@@ -1,21 +1,9 @@
#
-# Copyright 2011 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Refer to the README and COPYING files for full details of the license
+# Adapted by Red Hat from
+# http://code.activestate.com/recipes/203871-a-generic-programming-thread-poo…
+# Author: Tim Lesher
+# License: PSF License
+# http://wiki.python.org/moin/PythonSoftwareFoundationLicenseV2Easy
#
import threading
--
To view, visit http://gerrit.ovirt.org/9119
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib6a06dc60f53f12793a93bb71cd3d5bfec4cc0d1
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
Hello Federico Simoncelli,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/9129
to review the following change.
Change subject: libvirtvm: set volume the format in live snapshots
......................................................................
libvirtvm: set volume the format in live snapshots
When we update the drive objects (and configurations) at the end of
a live snapshot we should also update the format to be "cow" in order
to start requesting the drive extensions on block devices.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=874481
Change-Id: Ia5535cc8ad55441046e81aa329fac82a354592b9
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/libvirtvm.py
1 file changed, 1 insertion(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/29/9129/1
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index 86e39a3..ca31a43 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -1853,6 +1853,7 @@
newDrives[vmDevName] = tgetDrv.copy()
newDrives[vmDevName]["poolID"] = vmDrive.poolID
newDrives[vmDevName]["name"] = vmDevName
+ newDrives[vmDevName]["format"] = "cow"
try:
newDrives[vmDevName]["path"] = \
--
To view, visit http://gerrit.ovirt.org/9129
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia5535cc8ad55441046e81aa329fac82a354592b9
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce(a)redhat.com>
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Using only globalPool allow only 10 processes
......................................................................
Using only globalPool allow only 10 processes
For each domain we want to have process pool with limit slots of
processes, this way we optimize glob over mounted links.
This fix uses different pool for each domain, instead of the global one.
Change-Id: I9a4024b8d8be8b9cbbb4836987dfb94e3a11d7d3
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
Bug-Id: https://bugzilla.redhat.com/show_bug.cgi?id=853011
---
M vdsm/storage/fileSD.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/29/9029/1
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index a6a718f..f221eb0 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -479,7 +479,7 @@
def collectMetaFiles(possibleDomain):
try:
- metaFiles = oop.getGlobalProcPool().glob.glob(
+ metaFiles = oop.getProcessPool(possibleDomain).glob.glob(
os.path.join(possibleDomain,
constants.UUID_GLOB_PATTERN,
sd.DOMAIN_META_DATA))
--
To view, visit http://gerrit.ovirt.org/9029
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9a4024b8d8be8b9cbbb4836987dfb94e3a11d7d3
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
Adam Litke has uploaded a new change for review.
Change subject: schema: New type VmParameters
......................................................................
schema: New type VmParameters
Although the format of the data passed via VM.create is very similar to a
VmDefinition, some of the parameters don't make sense to pass in the context of
creating a new VM. Solve this by creating a new type for VM parameters.
Change-Id: I00d1b9aed55cbfc2210c1a4091bce17d45b90e67
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm_api/vdsmapi-schema.json
1 file changed, 48 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/39/7839/1
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index f6d3c77..b1dc60c 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -2346,6 +2346,53 @@
'vmId': 'UUID', 'vmName': 'str', 'vmType': 'VmType'}}
##
+# @VmDefinition:
+#
+# Full virtual machine status and properties.
+#
+# @acpiEnable: Indicates if ACPI is enabled inside the VM
+#
+# @custom: #opional A dictionary of custom, free-form properties
+#
+# @devices: #optional An array of VM devices requested
+#
+# @display: The type of display
+#
+# @kvmEnable: Indicates if KVM hardware acceleration is enabled
+#
+# @memSize: The amount of memory assigned to the VM in MB
+#
+# @nice: The host scheduling priority
+#
+# @smp: The number of CPUs presented to the VM
+#
+# @smpCoresPerSocket: #optional Indicates the number of CPU cores per socket
+#
+# @smpThreadsPerCore: #optional Indicates the number of CPU threads per core
+#
+# @timeOffset: The time difference from host to the VM in seconds
+#
+# @transparentHugePages: Indicates if the Transparent Huge Pages feature is
+# enabled for this virtual machine
+#
+# @vmId: The VM UUID
+#
+# @vmName: The VM name
+#
+# @vmType: The type of VM
+#
+# Since: 4.10.0
+##
+{'type': 'VmParameters',
+ 'data': {'acpiEnable': 'bool',
+ '*custom': 'StringMap', '*devices': ['VmDevice'],
+ 'display': 'VmDisplayType', 'kvmEnable': 'bool', 'memSize': 'uint',
+ 'nice': 'int', 'smp': 'uint', 'smpCoresPerSocket': 'uint',
+ 'smpThreadsPerCore': 'uint', 'timeOffset': 'uint',
+ 'transparentHugePages': 'bool', 'vmId': 'UUID', 'vmName': 'str',
+ 'vmType': 'VmType'}}
+
+##
# @VmFullStatus:
#
# A VmDefinition uses the same format as a VmFullStatus.
@@ -4278,7 +4325,7 @@
# Since: 4.10.0
##
{'command': {'class': 'VM', 'name': 'create'},
- 'data': {'vmParams': 'VmDefinition'},
+ 'data': {'vmParams': 'VmParameters'},
'returns': 'VmDefinition'}
##
--
To view, visit http://gerrit.ovirt.org/7839
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I00d1b9aed55cbfc2210c1a4091bce17d45b90e67
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Peter V. Saveliev has uploaded a new change for review.
Change subject: BZ#855924 -- fix 3.1 -> 3.0 migration again
......................................................................
BZ#855924 -- fix 3.1 -> 3.0 migration again
The issue was that fixing self._vm.conf is not enough -- we should
fix self._machineParams, that will work in all the cases.
Signed-off-by: Peter V. Saveliev <peet(a)redhat.com>
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=855924
Change-Id: I334cd39cad3eed30c2c3f1efa7085526454a44fb
---
M vdsm/vm.py
1 file changed, 4 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/36/9036/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 2229882..591ac1a 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -236,15 +236,15 @@
"""
# care only about "drives" list, since
# "devices" doesn't cause errors
- if 'drives' in self._vm.conf:
+ if 'drives' in self._machineParams:
for item in ("cdrom", "floppy"):
new_drives = []
- for drive in self._vm.conf['drives']:
+ for drive in self._machineParams['drives']:
if drive['device'] == item:
- self._vm.conf[item] = drive['path']
+ self._machineParams[item] = drive['path']
else:
new_drives.append(drive)
- self._vm.conf['drives'] = new_drives
+ self._machineParams['drives'] = new_drives
def run(self):
try:
--
To view, visit http://gerrit.ovirt.org/9036
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I334cd39cad3eed30c2c3f1efa7085526454a44fb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Peter V. Saveliev <peet(a)redhat.com>
Adam Litke has uploaded a new change for review.
Change subject: schema: Return objects rather than UUIDs
......................................................................
schema: Return objects rather than UUIDs
Rather than returning UUIDs and forcing the API user to instantiate their own
objects using those UUIDs, just return initialized objects. This patch just
changes the API schema. The specific implementation of this idea appears in the
patch that implements the code generator.
This is not exhaustive, but an example of the idea. The rest can be converted
over time.
Change-Id: I7fdfe69436d65ef8190d8a5f1d941e7a628c77c0
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm_api/vdsmapi-schema.json
1 file changed, 87 insertions(+), 71 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/40/7840/1
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index b1dc60c..7e8b9d3 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -939,12 +939,12 @@
# Get a list of all Storage Pools that are connected to this host.
#
# Returns:
-# A list of Storage Pool UUIDs
+# A list of Storage Pools
#
# Since: 4.10.0
##
{'command': {'class': 'Host', 'name': 'getConnectedStoragePools'},
- 'returns': ['UUID']}
+ 'returns': ['StoragePool']}
##
# @BlockDeviceType:
@@ -1561,15 +1561,15 @@
##
# @Host.getStorageDomains:
#
-# Get a list of known Storage Domain UUIDs.
+# Get a list of known Storage Domains.
#
-# @spUUID: #optional Limit to Domains belonging to this Storage Pool
+# @storagepoolID: #optional Limit to Domains belonging to this Storage Pool
#
-# @domainClass: #optional Limit to Domains of this @StorageDomainImageClass
+# @domainClass: #optional Limit to Domains of this @StorageDomainImageClass
#
-# @storageType: #optional Limit to Domains of this @StorageDomainType
+# @storageType: #optional Limit to Domains of this @StorageDomainType
#
-# @remotePath: #optional Limit to Domains having this remotePath
+# @remotePath: #optional Limit to Domains having this remotePath
#
# Returns:
# A list of known Storage Domains
@@ -1577,9 +1577,9 @@
# Since: 4.10.0
##
{'command': {'class': 'Host', 'name': 'getStorageDomains'},
- 'data': {'*spUUID': 'UUID', '*domainClass': 'StorageDomainImageClass',
+ 'data': {'*storagepoolID': 'UUID', '*domainClass': 'StorageDomainImageClass',
'*storageType': 'StorageDomainType', '*remotePath': 'str'},
- 'returns': ['UUID']}
+ 'returns': ['StorageDomain']}
##
# @Host.getStorageRepoStats:
@@ -2419,18 +2419,16 @@
#
# Get information about the current virtual machines.
#
-# @fullStatus: #optional Set to request complete VM information
-#
# @vmList: #optional Filter the results by a list of UUIDs
#
# Returns:
-# A list of VM definitions
+# A list of VMs
#
# Since: 4.10.0
##
{'command': {'class': 'Host', 'name': 'getVMList'},
- 'data': {'*fullStatus': 'bool', '*vmList': ['UUID']},
- 'returns': ['VmInfo']}
+ 'data': {'*vmList': ['UUID']},
+ 'returns': ['VM']}
##
# @Host.ping:
@@ -2810,18 +2808,19 @@
#
# Image API object.
#
-# @conn: A connected base API object
+# @conn: A connected base API object
#
-# @UUID: The UUID of the Image
+# @imageID: The UUID of the Image
#
-# @spUUID: The UUID of the Storage Pool associated with the Image
+# @storagepoolID: The UUID of the Storage Pool associated with the Image
#
-# @sdUUID: The UUID of the Storage Domain associated with the Image
+# @storagedomainID: The UUID of the Storage Domain associated with the Image
#
# Since: 4.10.0
##
{'class': 'Image',
- 'data': {'conn': 'Host', 'UUID': 'UUID', 'spUUID': 'UUID', 'sdUUID': 'UUID'}}
+ 'data': {'conn': 'Host', 'imageID': 'UUID', 'storagepoolID': 'UUID',
+ 'storagedomainID': 'UUID'}}
##
# @Image.delete:
@@ -2867,12 +2866,12 @@
# Get a list of Volumes associated with this Image.
#
# Returns:
-# A list of Image UUIDs
+# A list of Volumes
#
# Since: 4.10.0
##
{'command': {'class': 'Image', 'name': 'getVolumes'},
- 'returns': ['UUID']}
+ 'returns': ['Volume']}
##
# @Image.mergeSnapshots:
@@ -2938,13 +2937,15 @@
#
# LVMVolumeGroup API object.
#
-# @conn: A connected base API object
+# @conn: A connected base API object
#
-# @UUID: #optional Associate this object with an existing LVM Volume Group
+# @lvmvolumegroupID: #optional Associate this object with an existing LVM
+# Volume Group
#
# Since: 4.10.0
##
-{'class': 'LVMVolumeGroup', 'data': {'conn': 'Host', 'UUID': 'UUID'}}
+{'class': 'LVMVolumeGroup',
+ 'data': {'conn': 'Host', 'lvmvolumegroupID': 'UUID'}}
##
# @LVMVolumeGroup.create:
@@ -2997,16 +2998,17 @@
#
# StorageDomain API object.
#
-# @conn: A connected base API object
+# @conn: A connected base API object
#
-# @UUID: Associate this object with a new or existing Storage Domain
+# @storagedomainID: Associate this object with a new or existing Storage Domain
#
-# @spUUID: #optional The Storage Pool UUID if this Storage Domain is attached
+# @storagepoolID: #optional The Storage Pool UUID if this Storage Domain is
+# attached
#
# Since: 4.10.0
##
{'class': 'StorageDomain',
- 'data': {'conn': 'Host', 'UUID': 'UUID', '*spUUID': 'UUID'}}
+ 'data': {'conn': 'Host', 'storagedomainID': 'UUID', 'storagepoolID': 'UUID'}}
##
# @StorageDomain.activate:
@@ -3022,12 +3024,12 @@
#
# Attach a Storage Domain to a Storage Pool.
#
-# @spUUID: The Storage Pool to which the Storage Domain should be attached
+# @storagepoolID: The UUID of the pool to which this domain should be attached
#
# Since: 4.10.0
##
{'command': {'class': 'StorageDomain', 'name': 'attach'},
- 'data': {'spUUID': 'UUID'}}
+ 'data': {'storagepoolID': 'UUID'}}
##
# @StorageDomainCreateArgumentsBlock:
@@ -3209,12 +3211,12 @@
# Get a list of Images associated with this Storage Domain.
#
# Returns:
-# An array of Image UUIDs
+# An array of Imags
#
# Since: 4.10.0
##
{'command': {'class': 'StorageDomain', 'name': 'getImages'},
- 'returns': ['UUID']}
+ 'returns': ['Image']}
##
# @StorageDomainRole:
@@ -3316,16 +3318,16 @@
#
# Get a list of Volumes contained within a Storage Domain.
#
-# @imgUUID: Limit results to Volumes associated with a single Image
+# @imageID: Limit results to Volumes associated with a single Image
#
# Returns:
-# A list of Volume UUIDs
+# A list of Volumes
#
# Since: 4.10.0
##
{'command': {'class': 'StorageDomain', 'name': 'getVolumes'},
- 'data': {'imgUUID': 'UUID'},
- 'returns': ['UUID']}
+ 'data': {'imageID': 'UUID'},
+ 'returns': ['Volume']}
##
# @StorageDomain.setDescription:
@@ -3357,21 +3359,21 @@
#
# Upload a Volume into a Storage Domain from a remote location.
#
-# @imgUUID: The UUID of the image that is associated with the Volume
+# @imageID: The UUID of the image that is associated with the Volume
#
-# @volUUID: The UUID of an existing Volume where the data will be uploaded
+# @volumeID: The UUID of an existing Volume where the data will be uploaded
#
-# @srcPath: The remote location of the Volume data. Must be in a format that
-# can be understood by the command indicated in @method.
+# @srcPath: The remote location of the Volume data. Must be in a format that
+# can be understood by the command indicated in @method.
#
-# @size: The size of the volume data in blocks
+# @size: The size of the volume data in blocks
#
-# @method: The method (command) to use to upload the data
+# @method: The method (command) to use to upload the data
#
# Since: 4.10.0
##
{'command': {'class': 'StorageDomain', 'name': 'uploadVolume'},
- 'data': {'imgUUID': 'UUID', 'volUUID': 'UUID', 'srcPath': 'str',
+ 'data': {'imageID': 'UUID', 'volumeID': 'UUID', 'srcPath': 'str',
'size': 'int', 'method': 'UploadVolumeMethod'}}
##
@@ -3389,13 +3391,13 @@
#
# StoragePool API object.
#
-# @conn: A connected base API object
+# @conn: A connected base API object
#
-# @UUID: Associate this object with a new or existing Storage Pool
+# @storagepoolID: Associate this object with a new or existing Storage Pool
#
# Since: 4.10.0
##
-{'class': 'StoragePool', 'data': {'conn': 'Host', 'UUID': 'UUID'}}
+{'class': 'StoragePool', 'data': {'conn': 'Host', 'storagepoolID': 'UUID'}}
##
# @StoragePool.connect:
@@ -3600,7 +3602,7 @@
#
# Get information about backed-up virtual machines from a Backup Storage Domain.
#
-# @sdUUID: The UUID of the Backup Storage Domain to check
+# @storagedomainID: The UUID of the Backup Storage Domain to check
#
# @vmList: Limit results to a list of VM UUIDs
#
@@ -3613,7 +3615,7 @@
# previously injected it into the Backup Storage Domain.
##
{'command': {'class': 'StoragePool', 'name': 'getBackedUpVmsInfo'},
- 'data': {'sdUUID': 'UUID', 'vmList': ['UUID']},
+ 'data': {'storagedomainID': 'UUID', 'vmList': ['UUID']},
'returns': 'OVFMap'}
##
@@ -3621,7 +3623,7 @@
#
# Get a list of backed up virtual machines from a Backup Storage Domain.
#
-# @sdUUID: The UUID of the Backup Storage Domain to check
+# @storagedomainID: The UUID of the Backup Storage Domain to check
#
# Returns:
# A list of VM UUIDs
@@ -3629,7 +3631,7 @@
# Since: 4.10.0
##
{'command': {'class': 'StoragePool', 'name': 'getBackedUpVmsList'},
- 'data': {'sdUUID': 'UUID'},
+ 'data': {'storagedomainID': 'UUID'},
'returns': ['UUID']}
##
@@ -3650,18 +3652,18 @@
#
# Get a list of Storage Domains that contain an Image.
#
-# @imgUUID: The UUID of the Image to search for
+# @imageID: The UUID of the Image to search for
#
# @onlyDataDomains: #optional Only include Data Storage Domains
#
# Returns:
-# A list of Storage Domain UUIDs that contain the Image
+# A list of Storage Domains that contain the Image
#
# Since: 4.10.0
##
{'command': {'class': 'StoragePool', 'name': 'getDomainsContainingImage'},
- 'data': {'imgUUID': 'UUID', '*onlyDataDomains': 'bool'},
- 'returns': ['UUID']}
+ 'data': {'imageID': 'UUID', '*onlyDataDomains': 'bool'},
+ 'returns': ['StorageDomain']}
##
# @StoragePool.getIsoList:
@@ -4065,26 +4067,26 @@
#
# @vmList: A list of virtual machine definitions to store
#
-# @sdUUID: The Storage Domain to use for storing the VM definitions
+# @storagedomainID: The Storage Domain to use for storing the VM definitions
#
# Since: 4.10.0
##
{'command': {'class': 'StoragePool', 'name': 'updateVMs'},
- 'data': {'vmList': ['UpdateVmDefinition'], 'sdUUID': 'UUID'}}
+ 'data': {'vmList': ['UpdateVmDefinition'], 'storagedomainID': 'UUID'}}
##
# @StoragePool.removeVM:
#
# Remove a previously saved virtual machine definition.
#
-# @vmUUID: Remove the saved definition of the VM with this UUID
+# @vmUUID: Remove the saved definition of the VM with this UUID
#
-# @sdUUID: The Storage Domain where the VM is stored
+# @storagedomainID: The Storage Domain where the VM is stored
#
# Since: 4.10.0
##
{'command': {'class': 'StoragePool', 'name': 'removeVM'},
- 'data': {'vmUUID': 'UUID', 'sdUUID': 'UUID'}}
+ 'data': {'vmUUID': 'UUID', 'storagedomainID': 'UUID'}}
## Category: @Task #############################################################
##
@@ -4092,13 +4094,13 @@
#
# Task API object.
#
-# @conn: A connected base API object
+# @conn: A connected base API object
#
-# @UUID: Associate this object with an existing Task
+# @taskID: Associate this object with an existing Task
#
# Since: 4.10.0
##
-{'class': 'Task', 'data': {'conn': 'Host', 'UUID': 'UUID'}}
+{'class': 'Task', 'data': {'conn': 'Host', 'taskID': 'UUID'}}
##
# @Task.clear:
@@ -4161,11 +4163,11 @@
#
# @conn: A connected base API object
#
-# @UUID: Associate this object with an existing VM
+# @vmID: Associate this object with an existing VM
#
# Since: 4.10.0
##
-{'class': 'VM', 'data': {'conn': 'Host', 'UUID': 'UUID'}}
+{'class': 'VM', 'data': {'conn': 'Host', 'vmID': 'UUID'}}
##
# @DriveSpecVolume:
@@ -4387,6 +4389,20 @@
# Since: 4.10.0
##
{'command': {'class': 'VM', 'name': 'destroy'}}
+
+##
+# @VM.getInfo:
+#
+# Get detailed information about a VM.
+#
+# Returns:
+# VM information
+#
+# Since: 4.10.0
+##
+{'command': {'class': 'VM', 'name': 'getInfo'},
+ 'returns': 'VmFullStatus'}
+
##
# @VM.getMigrationStatus:
@@ -5179,21 +5195,21 @@
#
# Volume API object.
#
-# @conn: A connected base API object
+# @conn: A connected base API object
#
-# @UUID: The UUID of the Volume
+# @volumeID: The UUID of the Volume
#
-# @spUUID: The Storage Pool associated with @UUID
+# @storagepoolID: The Storage Pool associated with @UUID
#
-# @sdUUID: The Storage Domain associated with @UUID
+# @storagedomainID: The Storage Domain associated with @UUID
#
-# @imgUUID: The Image associated with @UUID
+# @imageID: The Image associated with @UUID
#
# Since: 4.10.0
##
{'class': 'Volume',
- 'data': {'conn': 'Host', 'UUID': 'UUID', 'spUUID': 'UUID', 'sdUUID': 'UUID',
- 'imgUUID': 'UUID'}}
+ 'data': {'conn': 'Host', 'volumeID': 'UUID', 'storagepoolID': 'UUID',
+ 'storagedomainID': 'UUID', 'imageID': 'UUID'}}
##
# @VolumeRole:
--
To view, visit http://gerrit.ovirt.org/7840
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7fdfe69436d65ef8190d8a5f1d941e7a628c77c0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Adam Litke has uploaded a new change for review.
Change subject: schema: Remove VmFullStatus
......................................................................
schema: Remove VmFullStatus
The VmFullStatus alias is a meaningless indirection that simply causes confusion
to API users. In all cases, its use just means VmDefinition so use that type
instead.
Change-Id: Id16979a105521e3c059ba27029493b71158f8815
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
M vdsm_api/vdsmapi-schema.json
1 file changed, 2 insertions(+), 11 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/13/8613/1
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 5d4e10f..3f8f0a0 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -2394,15 +2394,6 @@
'vmType': 'VmType'}}
##
-# @VmFullStatus:
-#
-# A VmFullStatus uses the same format as a VmDefinition.
-#
-# Since: 4.10.0
-##
-{'alias': 'VmFullStatus', 'data': 'VmDefinition'}
-
-##
# @VmInfo:
#
# A discriminated record of VM status information.
@@ -2413,7 +2404,7 @@
##
{'type': 'VmInfo',
'data': {},
- 'union': ['VmFullStatus', 'VmShortStatus']}
+ 'union': ['VmDefinition', 'VmShortStatus']}
##
# @Host.getVMList:
@@ -4910,7 +4901,7 @@
# Since: 4.10.0
##
{'type': 'MigrationCreateState',
- 'data': {'migrationPort': 'int', 'params': 'VmFullStatus'}}
+ 'data': {'migrationPort': 'int', 'params': 'VmDefinition'}}
##
# @VM.migrationCreate:
--
To view, visit http://gerrit.ovirt.org/8613
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id16979a105521e3c059ba27029493b71158f8815
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl(a)us.ibm.com>
Zhou Zheng Sheng has uploaded a new change for review.
Change subject: fix REMOVED_IMAGE_PREFIX not defined error
......................................................................
fix REMOVED_IMAGE_PREFIX not defined error
Recently http://gerrit.ovirt.org/#/c/8506 is merged, it moves
REMOVED_IMAGE_PREFIX = "_remove_me_" from vdsm/storage/image.py to
vdsm/storage/sd.py. So all occurrence of REMOVED_IMAGE_PREFIX in
image.py must be changed to sd.REMOVED_IMAGE_PREFIX, otherwise
pyflakes will say REMOVED_IMAGE_PREFIX not defined.
Change-Id: Ifc6ec49ff20c7f8a18ae14fe205570dfc6ce7634
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
M vdsm/storage/image.py
1 file changed, 2 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/98/9098/1
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index 6ae5908..4cd9785 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -234,7 +234,7 @@
# Otherwise move it out of the way
newImgUUID = self.deletedVolumeName(imgUUID)
self.log.info("Rename image %s -> %s", imgUUID, newImgUUID)
- if not imgUUID.startswith(REMOVED_IMAGE_PREFIX):
+ if not imgUUID.startswith(sd.REMOVED_IMAGE_PREFIX):
removedImage = os.path.join(os.path.dirname(imageDir), newImgUUID)
os.rename(imageDir, removedImage)
else:
@@ -242,7 +242,7 @@
volumes = [volclass(self.repoPath, sdUUID, newImgUUID, volUUID) for volUUID in uuidlist]
for vol in volumes:
- if not vol.volUUID.startswith(REMOVED_IMAGE_PREFIX):
+ if not vol.volUUID.startswith(sd.REMOVED_IMAGE_PREFIX):
vol.rename(self.deletedVolumeName(vol.volUUID), recovery=False)
else:
self.log.warning("Volume %s of image %s already renamed", vol.volUUID, imgUUID)
--
To view, visit http://gerrit.ovirt.org/9098
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifc6ec49ff20c7f8a18ae14fe205570dfc6ce7634
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
On Tue, Nov 06, 2012 at 12:41:42PM -0500, Jenkins oVirt Server wrote:
>
> BUILD FAILURE
> Build URL: http://jenkins.ovirt.org/job/vdsm_unit_tests/1502/
> Project: vdsm_unit_tests
> Date of build: Tue, 06 Nov 2012 12:41:22 -0500
> Build duration: 20 sec
Eyal, please take a look at this machine: it seems that
/home/jenkins/workspace/vdsm_unit_tests/ has some trash remainder, an
old vdsm/pthread.pyc. Would you make sure that the directory is clean
before checking out from git?
Dan.