From f4afea177b12efaea738fa27fb238a3076ae2fd3 Mon Sep 17 00:00:00 2001 From: OpenStack Project Creator Date: Tue, 27 Oct 2015 12:52:54 +0000 Subject: [PATCH] Implement: Fuel install QEMU Todo lists: 1. update dependencies.txt after RPM/debian packages are uploaded to official site Change-Id: I05515b20f1e368cebc53a29762ca646af88591ac Closes-Bug:#1507878 Signed-off-by: lingyu1 --- LICENSE | 202 ++++++++++++++++++ README.md | 146 +++++++++++++ .../puppet/manifests/qemu-install.pp | 24 +++ environment_config.yaml | 7 + figures/ovs-repo.PNG | Bin 0 -> 14329 bytes figures/plugin.PNG | Bin 0 -> 5042 bytes metadata.yaml | 35 +++ pre_build_hook | 41 ++++ qemu_package/centos/dependencies.txt | 1 + qemu_package/ubuntu/dependencies.txt | 5 + repositories/centos/.gitkeep | 0 repositories/ubuntu/.gitkeep | 0 tasks.yaml | 8 + 13 files changed, 469 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 deployment_scripts/puppet/manifests/qemu-install.pp create mode 100644 environment_config.yaml create mode 100644 figures/ovs-repo.PNG create mode 100644 figures/plugin.PNG create mode 100644 metadata.yaml create mode 100755 pre_build_hook create mode 100644 qemu_package/centos/dependencies.txt create mode 100644 qemu_package/ubuntu/dependencies.txt create mode 100644 repositories/centos/.gitkeep create mode 100644 repositories/ubuntu/.gitkeep create mode 100644 tasks.yaml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e06d208 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..cec0841 --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ +Qemu Plugin for Fuel +================================ + +Qemu plugin +----------------------- + +Overview +-------- + +New fuel plugin fuel-plugin-qemu is developed to deploy QEMU >2.2 in Fuel@OPNFV, which is requested by OVS with DPDK. + +Requirements +------------ + +| Requirement | Version/Comment | +|----------------------------------|-----------------| +| Mirantis OpenStack compatibility | 6.1 | + +Recommendations +--------------- + +None. + +Limitations +----------- + +None. + +Installation Guide +================== + +Qemu plugin installation +---------------------------------------- + +1. Clone the fuel-plugin-qemu repo from stackforge: + + git clone https://github.com/stackforge/fuel-plugin-qemu + +2. Install the Fuel Plugin Builder: + + pip install fuel-plugin-builder + +3. Install the [fpm gem](https://github.com/jordansissel/fpm): + + gem install fpm + +4. Build Qemu Fuel plugin: + + fpb --build fuel-plugin-qemu/ + +5. The *fuel-plugin-qemu-[x.x.x].rpm* plugin package will be created in the plugin folder. + +6. Move this file to the Fuel Master node with secure copy (scp): + + scp fuel-plugin-qemu-[x.x.x].rpm root@:/tmp + +7. While logged in Fuel Master install the Qemu plugin: + + fuel plugins --install fuel-plugin-qemu-[x.x.x].rpm + +8. Check if the plugin was installed successfully: + + fuel plugins + + id | name | version | package_version + ---|------------------|---------|---------------- + 1 | fuel-plugin-qemu | 0.5.0 | 2.0.0 + +9. Plugin is ready to use and can be enabled on the Settings tab of the Fuel web UI. + + +User Guide +========== + +Qemu plugin configuration +--------------------------------------------- + +1. Create a new environment with the Fuel UI wizard. +2. Click on the Settings tab of the Fuel web UI. +3. Scroll down the page, select the plugin checkbox. In case of centos, modify the priority of the mos repo. + + +Build options +------------- + +It is possible to modify process of building plugin by setting environment variables. Look into [pre_build_hook file](pre_build_hook) for more details. + +Dependencies +------------ + +If you plan to use plugin in environment without internet access or/and CentOS environment modify build command: + + INCLUDE_DEPENDENCIES=true fpb --build fuel-plugin-qemu/ + +Pre build script will try download required dependencies so it become part of the compiled plugin. + +Note: List of packages for [ubuntu](qemu_package/ubuntu/dependencies.txt) and [centos](qemu_package/centos/dependencies.txt) may need to be modified if packages in centos or ubuntu repositories will change. + +Testing +------- + +None. + +Known issues +------------ + +None. + +Release Notes +------------- + +**0.5.0** + +* Initial release of the plugin. This is a beta version. + + +Development +=========== + +The *OpenStack Development Mailing List* is the preferred way to communicate, +emails should be sent to `openstack-dev@lists.openstack.org` with the subject +prefixed by `[fuel][plugins][qemu]`. + +Reporting Bugs +-------------- + +Bugs should be filled on the [Launchpad fuel-plugins project]( +https://bugs.launchpad.net/fuel-plugins) (not GitHub) with the tag `qemu`. + + +Contributing +------------ + +If you would like to contribute to the development of this Fuel plugin you must +follow the [OpenStack development workflow]( +http://docs.openstack.org/infra/manual/developers.html#development-workflow). + +Patch reviews take place on the [OpenStack gerrit]( +https://review.openstack.org/#/q/status:open+project:stackforge/fuel-plugin-qemu,n,z) +system. + +Contributors +------------ + +* ling.y.yu@intel.com,ruijing.guo@intel.com + diff --git a/deployment_scripts/puppet/manifests/qemu-install.pp b/deployment_scripts/puppet/manifests/qemu-install.pp new file mode 100644 index 0000000..472acea --- /dev/null +++ b/deployment_scripts/puppet/manifests/qemu-install.pp @@ -0,0 +1,24 @@ +$qemu_version = "1:2.4+dfsg-4ubuntu1" +if $operatingsystem == 'Ubuntu' { + package { 'qemu-block-extra': + ensure => "${qemu_version}", + } + package { 'qemu-utils': + ensure => "${qemu_version}", + require => Package['qemu-block-extra'], + } + package { 'qemu-system': + ensure => "${qemu_version}", + } + package { 'qemu-user': + ensure => "${qemu_version}", + } + package { 'qemu': + ensure => "${qemu_version}", + require => Package['qemu-utils','qemu-system','qemu-user'], + } +} elsif $operatingsystem == 'CentOS' { + package { 'qemu': + ensure => "2.4.0.1-1", + } +} diff --git a/environment_config.yaml b/environment_config.yaml new file mode 100644 index 0000000..4fa5260 --- /dev/null +++ b/environment_config.yaml @@ -0,0 +1,7 @@ +attributes: + fuel-plugin-qemu_text: + value: '2.4' + label: 'Version' + description: 'Description for version' + weight: 25 + type: "text" diff --git a/figures/ovs-repo.PNG b/figures/ovs-repo.PNG new file mode 100644 index 0000000000000000000000000000000000000000..5e5cebc9fb039192c9eeb531b9334bfd3bb188cc GIT binary patch literal 14329 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 literal 0 HcmV?d00001 diff --git a/figures/plugin.PNG b/figures/plugin.PNG new file mode 100644 index 0000000000000000000000000000000000000000..ac807be919cc46aee0fbd077d488171237b420a5 GIT binary patch literal 5042 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