diff --git a/docs/publican-cloudstack/LICENSE b/docs/publican-cloudstack/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/docs/publican-cloudstack/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/docs/publican-cloudstack/NOTICE b/docs/publican-cloudstack/NOTICE new file mode 100644 index 00000000000..c7720bf1819 --- /dev/null +++ b/docs/publican-cloudstack/NOTICE @@ -0,0 +1,5 @@ +Apache CloudStack +Copyright 2012 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/docs/publican-cloudstack/README b/docs/publican-cloudstack/README new file mode 100644 index 00000000000..5b1c753beba --- /dev/null +++ b/docs/publican-cloudstack/README @@ -0,0 +1,8 @@ +This is the documentation brand for CloudStack Project +This brand is needed for building CloudStack documentation. + +To learn more about CloudStack visit: +http://cloudstack.org + +To learn more about Publican visit: +https://fedorahosted.org/publican/ diff --git a/docs/publican-cloudstack/en-US/Feedback.xml b/docs/publican-cloudstack/en-US/Feedback.xml new file mode 100644 index 00000000000..5236b0f8309 --- /dev/null +++ b/docs/publican-cloudstack/en-US/Feedback.xml @@ -0,0 +1,27 @@ + + +
+ We Need Feedback! + + feedback1 + contact information for this brand + + + + If you find a typographical error in this manual, or if you + have thought of a way to make this manual better, we would + love to hear from you! Please submit a bug: + http://bugs.cloudstack.org + against the component Doc + + + If you have a suggestion for improving the documentation, try to be as + specific as possible when describing it. If you have found an error, + please include the section number and some of the surrounding text + so we can find it easily. + + +
+ + diff --git a/docs/publican-cloudstack/en-US/Legal_Notice.xml b/docs/publican-cloudstack/en-US/Legal_Notice.xml new file mode 100644 index 00000000000..1dd72812908 --- /dev/null +++ b/docs/publican-cloudstack/en-US/Legal_Notice.xml @@ -0,0 +1,39 @@ + + + + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. + + + + Apache CloudStack is an effort undergoing incubation at The Apache Software Foundation (ASF). + + + Incubation is required of all newly accepted projects until a further review + indicates that the infrastructure, communications, and decision making + process have stabilized in a manner consistent with other successful ASF + projects. While incubation status is not necessarily a reflection of the + completeness or stability of the code, it does indicate that the project + has yet to be fully endorsed by the ASF. + + + + diff --git a/docs/publican-cloudstack/en-US/css/overrides.css b/docs/publican-cloudstack/en-US/css/overrides.css new file mode 100644 index 00000000000..ebd9730b690 --- /dev/null +++ b/docs/publican-cloudstack/en-US/css/overrides.css @@ -0,0 +1,57 @@ +a:link { + color:#0066cc; +} + +a:visited { + color:#6699cc; +} + +h1 { + color:#3c6eb4; +} + +.producttitle { + background: #3c6eb4 url(../images/h1-bg.png) top left repeat; +} + +.section h1.title { + color:#3c6eb4; +} + + +h2,h3,h4,h5,h6 { + color:#3c6eb4 +} + +table { + border:1px solid #3c6eb4; +} + +table th { + background-color:#3c6eb4; +} + +table tr.even td { + background-color:#f5f5f5; +} + +#title a { + height:54px; +} + +.term{ + color:#a70000; +} + +.revhistory table th { + color:#3c6eb4; +} + +.edition { + color: #3c6eb4; +} + +span.remark{ + background-color: #ffff00; +} + diff --git a/docs/publican-cloudstack/en-US/images/.directory b/docs/publican-cloudstack/en-US/images/.directory new file mode 100644 index 00000000000..44ce2756e62 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/.directory @@ -0,0 +1,4 @@ +[Dolphin] +ShowPreview=true +Timestamp=2011,8,11,15,3,32 +Version=2 diff --git a/docs/publican-cloudstack/en-US/images/1.png b/docs/publican-cloudstack/en-US/images/1.png new file mode 100644 index 00000000000..098e7dfd698 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/1.png differ diff --git a/docs/publican-cloudstack/en-US/images/1.svg b/docs/publican-cloudstack/en-US/images/1.svg new file mode 100644 index 00000000000..a874e974c1c --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/1.svg @@ -0,0 +1,28 @@ + + + + + + 1 + diff --git a/docs/publican-cloudstack/en-US/images/10.png b/docs/publican-cloudstack/en-US/images/10.png new file mode 100644 index 00000000000..1d2ab13127b Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/10.png differ diff --git a/docs/publican-cloudstack/en-US/images/10.svg b/docs/publican-cloudstack/en-US/images/10.svg new file mode 100644 index 00000000000..6892e0de9b5 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/10.svg @@ -0,0 +1,28 @@ + + + + + + 10 + diff --git a/docs/publican-cloudstack/en-US/images/11.png b/docs/publican-cloudstack/en-US/images/11.png new file mode 100644 index 00000000000..897afb30257 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/11.png differ diff --git a/docs/publican-cloudstack/en-US/images/11.svg b/docs/publican-cloudstack/en-US/images/11.svg new file mode 100644 index 00000000000..7f5c269cfc5 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/11.svg @@ -0,0 +1,28 @@ + + + + + + 11 + diff --git a/docs/publican-cloudstack/en-US/images/12.png b/docs/publican-cloudstack/en-US/images/12.png new file mode 100644 index 00000000000..b2aa1bddc4f Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/12.png differ diff --git a/docs/publican-cloudstack/en-US/images/12.svg b/docs/publican-cloudstack/en-US/images/12.svg new file mode 100644 index 00000000000..9bcf3cc586c --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/12.svg @@ -0,0 +1,28 @@ + + + + + + 12 + diff --git a/docs/publican-cloudstack/en-US/images/13.png b/docs/publican-cloudstack/en-US/images/13.png new file mode 100644 index 00000000000..c6e0022be06 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/13.png differ diff --git a/docs/publican-cloudstack/en-US/images/13.svg b/docs/publican-cloudstack/en-US/images/13.svg new file mode 100644 index 00000000000..796664551fa --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/13.svg @@ -0,0 +1,28 @@ + + + + + + 13 + diff --git a/docs/publican-cloudstack/en-US/images/14.png b/docs/publican-cloudstack/en-US/images/14.png new file mode 100644 index 00000000000..93833719cff Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/14.png differ diff --git a/docs/publican-cloudstack/en-US/images/14.svg b/docs/publican-cloudstack/en-US/images/14.svg new file mode 100644 index 00000000000..869be6ab2bb --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/14.svg @@ -0,0 +1,28 @@ + + + + + + 14 + diff --git a/docs/publican-cloudstack/en-US/images/15.png b/docs/publican-cloudstack/en-US/images/15.png new file mode 100644 index 00000000000..e50bcb95031 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/15.png differ diff --git a/docs/publican-cloudstack/en-US/images/15.svg b/docs/publican-cloudstack/en-US/images/15.svg new file mode 100644 index 00000000000..003f16c2e85 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/15.svg @@ -0,0 +1,28 @@ + + + + + + 15 + diff --git a/docs/publican-cloudstack/en-US/images/16.png b/docs/publican-cloudstack/en-US/images/16.png new file mode 100644 index 00000000000..ff3705d120a Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/16.png differ diff --git a/docs/publican-cloudstack/en-US/images/16.svg b/docs/publican-cloudstack/en-US/images/16.svg new file mode 100644 index 00000000000..ab4bee018bf --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/16.svg @@ -0,0 +1,28 @@ + + + + + + 16 + diff --git a/docs/publican-cloudstack/en-US/images/17.png b/docs/publican-cloudstack/en-US/images/17.png new file mode 100644 index 00000000000..594964530b0 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/17.png differ diff --git a/docs/publican-cloudstack/en-US/images/17.svg b/docs/publican-cloudstack/en-US/images/17.svg new file mode 100644 index 00000000000..ff29b7aa41b --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/17.svg @@ -0,0 +1,28 @@ + + + + + + 17 + diff --git a/docs/publican-cloudstack/en-US/images/18.png b/docs/publican-cloudstack/en-US/images/18.png new file mode 100644 index 00000000000..7e8dbb464e3 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/18.png differ diff --git a/docs/publican-cloudstack/en-US/images/18.svg b/docs/publican-cloudstack/en-US/images/18.svg new file mode 100644 index 00000000000..6225d8a91a5 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/18.svg @@ -0,0 +1,28 @@ + + + + + + 18 + diff --git a/docs/publican-cloudstack/en-US/images/19.png b/docs/publican-cloudstack/en-US/images/19.png new file mode 100644 index 00000000000..eb43c6fdca1 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/19.png differ diff --git a/docs/publican-cloudstack/en-US/images/19.svg b/docs/publican-cloudstack/en-US/images/19.svg new file mode 100644 index 00000000000..efd3c0eeb91 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/19.svg @@ -0,0 +1,28 @@ + + + + + + 19 + diff --git a/docs/publican-cloudstack/en-US/images/2.png b/docs/publican-cloudstack/en-US/images/2.png new file mode 100644 index 00000000000..e550c21cb11 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/2.png differ diff --git a/docs/publican-cloudstack/en-US/images/2.svg b/docs/publican-cloudstack/en-US/images/2.svg new file mode 100644 index 00000000000..27100aca9fa --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/2.svg @@ -0,0 +1,28 @@ + + + + + + 2 + diff --git a/docs/publican-cloudstack/en-US/images/20.png b/docs/publican-cloudstack/en-US/images/20.png new file mode 100644 index 00000000000..692badc3cd1 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/20.png differ diff --git a/docs/publican-cloudstack/en-US/images/20.svg b/docs/publican-cloudstack/en-US/images/20.svg new file mode 100644 index 00000000000..7d727359a3c --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/20.svg @@ -0,0 +1,28 @@ + + + + + + 20 + diff --git a/docs/publican-cloudstack/en-US/images/21.png b/docs/publican-cloudstack/en-US/images/21.png new file mode 100644 index 00000000000..231735e5aa9 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/21.png differ diff --git a/docs/publican-cloudstack/en-US/images/21.svg b/docs/publican-cloudstack/en-US/images/21.svg new file mode 100644 index 00000000000..babe3ad790b --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/21.svg @@ -0,0 +1,28 @@ + + + + + + 21 + diff --git a/docs/publican-cloudstack/en-US/images/22.png b/docs/publican-cloudstack/en-US/images/22.png new file mode 100644 index 00000000000..a77ea0faa5b Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/22.png differ diff --git a/docs/publican-cloudstack/en-US/images/22.svg b/docs/publican-cloudstack/en-US/images/22.svg new file mode 100644 index 00000000000..d7c7af500df --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/22.svg @@ -0,0 +1,28 @@ + + + + + + 22 + diff --git a/docs/publican-cloudstack/en-US/images/23.png b/docs/publican-cloudstack/en-US/images/23.png new file mode 100644 index 00000000000..1802579ef90 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/23.png differ diff --git a/docs/publican-cloudstack/en-US/images/23.svg b/docs/publican-cloudstack/en-US/images/23.svg new file mode 100644 index 00000000000..399deffb410 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/23.svg @@ -0,0 +1,28 @@ + + + + + + 23 + diff --git a/docs/publican-cloudstack/en-US/images/24.png b/docs/publican-cloudstack/en-US/images/24.png new file mode 100644 index 00000000000..16e96e7e68b Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/24.png differ diff --git a/docs/publican-cloudstack/en-US/images/24.svg b/docs/publican-cloudstack/en-US/images/24.svg new file mode 100644 index 00000000000..25a37e8dc81 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/24.svg @@ -0,0 +1,28 @@ + + + + + + 24 + diff --git a/docs/publican-cloudstack/en-US/images/25.png b/docs/publican-cloudstack/en-US/images/25.png new file mode 100644 index 00000000000..7bfac576852 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/25.png differ diff --git a/docs/publican-cloudstack/en-US/images/25.svg b/docs/publican-cloudstack/en-US/images/25.svg new file mode 100644 index 00000000000..adfb67af3e4 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/25.svg @@ -0,0 +1,28 @@ + + + + + + 25 + diff --git a/docs/publican-cloudstack/en-US/images/26.png b/docs/publican-cloudstack/en-US/images/26.png new file mode 100644 index 00000000000..08de0655857 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/26.png differ diff --git a/docs/publican-cloudstack/en-US/images/26.svg b/docs/publican-cloudstack/en-US/images/26.svg new file mode 100644 index 00000000000..6e8e5d62b8d --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/26.svg @@ -0,0 +1,28 @@ + + + + + + 26 + diff --git a/docs/publican-cloudstack/en-US/images/27.png b/docs/publican-cloudstack/en-US/images/27.png new file mode 100644 index 00000000000..ac73b8eebd5 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/27.png differ diff --git a/docs/publican-cloudstack/en-US/images/27.svg b/docs/publican-cloudstack/en-US/images/27.svg new file mode 100644 index 00000000000..299194e4483 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/27.svg @@ -0,0 +1,28 @@ + + + + + + 27 + diff --git a/docs/publican-cloudstack/en-US/images/28.png b/docs/publican-cloudstack/en-US/images/28.png new file mode 100644 index 00000000000..dddaea9e4f8 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/28.png differ diff --git a/docs/publican-cloudstack/en-US/images/28.svg b/docs/publican-cloudstack/en-US/images/28.svg new file mode 100644 index 00000000000..5df71b85554 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/28.svg @@ -0,0 +1,28 @@ + + + + + + 28 + diff --git a/docs/publican-cloudstack/en-US/images/29.png b/docs/publican-cloudstack/en-US/images/29.png new file mode 100644 index 00000000000..f901971df43 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/29.png differ diff --git a/docs/publican-cloudstack/en-US/images/29.svg b/docs/publican-cloudstack/en-US/images/29.svg new file mode 100644 index 00000000000..88aa692be43 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/29.svg @@ -0,0 +1,28 @@ + + + + + + 29 + diff --git a/docs/publican-cloudstack/en-US/images/3.png b/docs/publican-cloudstack/en-US/images/3.png new file mode 100644 index 00000000000..e78d18cb51d Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/3.png differ diff --git a/docs/publican-cloudstack/en-US/images/3.svg b/docs/publican-cloudstack/en-US/images/3.svg new file mode 100644 index 00000000000..7954fa5a0df --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/3.svg @@ -0,0 +1,28 @@ + + + + + + 3 + diff --git a/docs/publican-cloudstack/en-US/images/4.png b/docs/publican-cloudstack/en-US/images/4.png new file mode 100644 index 00000000000..525915d6690 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/4.png differ diff --git a/docs/publican-cloudstack/en-US/images/4.svg b/docs/publican-cloudstack/en-US/images/4.svg new file mode 100644 index 00000000000..c97f7658a53 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/4.svg @@ -0,0 +1,28 @@ + + + + + + 4 + diff --git a/docs/publican-cloudstack/en-US/images/5.png b/docs/publican-cloudstack/en-US/images/5.png new file mode 100644 index 00000000000..10ec8807650 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/5.png differ diff --git a/docs/publican-cloudstack/en-US/images/5.svg b/docs/publican-cloudstack/en-US/images/5.svg new file mode 100644 index 00000000000..64504469387 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/5.svg @@ -0,0 +1,28 @@ + + + + + + 5 + diff --git a/docs/publican-cloudstack/en-US/images/6.png b/docs/publican-cloudstack/en-US/images/6.png new file mode 100644 index 00000000000..60c626b3eda Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/6.png differ diff --git a/docs/publican-cloudstack/en-US/images/6.svg b/docs/publican-cloudstack/en-US/images/6.svg new file mode 100644 index 00000000000..45af47a1cdc --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/6.svg @@ -0,0 +1,28 @@ + + + + + + 6 + diff --git a/docs/publican-cloudstack/en-US/images/7.png b/docs/publican-cloudstack/en-US/images/7.png new file mode 100644 index 00000000000..7184e2c0d4c Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/7.png differ diff --git a/docs/publican-cloudstack/en-US/images/7.svg b/docs/publican-cloudstack/en-US/images/7.svg new file mode 100644 index 00000000000..2e9ffec9866 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/7.svg @@ -0,0 +1,28 @@ + + + + + + 7 + diff --git a/docs/publican-cloudstack/en-US/images/8.png b/docs/publican-cloudstack/en-US/images/8.png new file mode 100644 index 00000000000..d951846e9fb Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/8.png differ diff --git a/docs/publican-cloudstack/en-US/images/8.svg b/docs/publican-cloudstack/en-US/images/8.svg new file mode 100644 index 00000000000..340dbce58e3 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/8.svg @@ -0,0 +1,28 @@ + + + + + + 8 + diff --git a/docs/publican-cloudstack/en-US/images/9.png b/docs/publican-cloudstack/en-US/images/9.png new file mode 100644 index 00000000000..5aef6797585 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/9.png differ diff --git a/docs/publican-cloudstack/en-US/images/9.svg b/docs/publican-cloudstack/en-US/images/9.svg new file mode 100644 index 00000000000..3838627082f --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/9.svg @@ -0,0 +1,28 @@ + + + + + + 9 + diff --git a/docs/publican-cloudstack/en-US/images/dot.png b/docs/publican-cloudstack/en-US/images/dot.png new file mode 100644 index 00000000000..79908d10d4f Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/dot.png differ diff --git a/docs/publican-cloudstack/en-US/images/dot.svg b/docs/publican-cloudstack/en-US/images/dot.svg new file mode 100644 index 00000000000..eaeff2ea78b --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/dot.svg @@ -0,0 +1,21 @@ + + + + dot + diff --git a/docs/publican-cloudstack/en-US/images/dot2.png b/docs/publican-cloudstack/en-US/images/dot2.png new file mode 100644 index 00000000000..d9262efbf62 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/dot2.png differ diff --git a/docs/publican-cloudstack/en-US/images/dot2.svg b/docs/publican-cloudstack/en-US/images/dot2.svg new file mode 100644 index 00000000000..893f6893566 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/dot2.svg @@ -0,0 +1,21 @@ + + + + dot2 + diff --git a/docs/publican-cloudstack/en-US/images/h1-bg.png b/docs/publican-cloudstack/en-US/images/h1-bg.png new file mode 100644 index 00000000000..a2aad24b329 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/h1-bg.png differ diff --git a/docs/publican-cloudstack/en-US/images/h1-bg.svg b/docs/publican-cloudstack/en-US/images/h1-bg.svg new file mode 100644 index 00000000000..ebadc21d2d5 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/h1-bg.svg @@ -0,0 +1,21 @@ + + + + h1-bg + diff --git a/docs/publican-cloudstack/en-US/images/image_left.png b/docs/publican-cloudstack/en-US/images/image_left.png new file mode 100644 index 00000000000..007f7b3578c Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/image_left.png differ diff --git a/docs/publican-cloudstack/en-US/images/image_left.svg b/docs/publican-cloudstack/en-US/images/image_left.svg new file mode 100644 index 00000000000..99ce61cfc12 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/image_left.svg @@ -0,0 +1,331 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/publican-cloudstack/en-US/images/image_right.png b/docs/publican-cloudstack/en-US/images/image_right.png new file mode 100644 index 00000000000..5b67443c2cc Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/image_right.png differ diff --git a/docs/publican-cloudstack/en-US/images/image_right.svg b/docs/publican-cloudstack/en-US/images/image_right.svg new file mode 100644 index 00000000000..7c9e01f99f1 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/image_right.svg @@ -0,0 +1,21 @@ + + + + image_right + diff --git a/docs/publican-cloudstack/en-US/images/important.png b/docs/publican-cloudstack/en-US/images/important.png new file mode 100644 index 00000000000..969562b7bc7 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/important.png differ diff --git a/docs/publican-cloudstack/en-US/images/important.svg b/docs/publican-cloudstack/en-US/images/important.svg new file mode 100644 index 00000000000..064c783b538 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/important.svg @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/docs/publican-cloudstack/en-US/images/note.png b/docs/publican-cloudstack/en-US/images/note.png new file mode 100644 index 00000000000..d04775d9905 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/note.png differ diff --git a/docs/publican-cloudstack/en-US/images/note.svg b/docs/publican-cloudstack/en-US/images/note.svg new file mode 100644 index 00000000000..abe5a602468 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/note.svg @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/docs/publican-cloudstack/en-US/images/stock-go-back.png b/docs/publican-cloudstack/en-US/images/stock-go-back.png new file mode 100644 index 00000000000..00850b21b23 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/stock-go-back.png differ diff --git a/docs/publican-cloudstack/en-US/images/stock-go-back.svg b/docs/publican-cloudstack/en-US/images/stock-go-back.svg new file mode 100644 index 00000000000..b3b908143f6 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/stock-go-back.svg @@ -0,0 +1,21 @@ + + + + stock-go-back + diff --git a/docs/publican-cloudstack/en-US/images/stock-go-forward.png b/docs/publican-cloudstack/en-US/images/stock-go-forward.png new file mode 100644 index 00000000000..cc2797a4686 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/stock-go-forward.png differ diff --git a/docs/publican-cloudstack/en-US/images/stock-go-forward.svg b/docs/publican-cloudstack/en-US/images/stock-go-forward.svg new file mode 100644 index 00000000000..7ee607b48f9 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/stock-go-forward.svg @@ -0,0 +1,21 @@ + + + + stock-go-forward + diff --git a/docs/publican-cloudstack/en-US/images/stock-go-up.png b/docs/publican-cloudstack/en-US/images/stock-go-up.png new file mode 100644 index 00000000000..1ebf2799c35 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/stock-go-up.png differ diff --git a/docs/publican-cloudstack/en-US/images/stock-go-up.svg b/docs/publican-cloudstack/en-US/images/stock-go-up.svg new file mode 100644 index 00000000000..a7c2af2f15a --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/stock-go-up.svg @@ -0,0 +1,21 @@ + + + + stock-go-up + diff --git a/docs/publican-cloudstack/en-US/images/stock-home.png b/docs/publican-cloudstack/en-US/images/stock-home.png new file mode 100644 index 00000000000..3f0c1906343 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/stock-home.png differ diff --git a/docs/publican-cloudstack/en-US/images/stock-home.svg b/docs/publican-cloudstack/en-US/images/stock-home.svg new file mode 100644 index 00000000000..d06a54480e9 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/stock-home.svg @@ -0,0 +1,21 @@ + + + + stock-home + diff --git a/docs/publican-cloudstack/en-US/images/title_logo.png b/docs/publican-cloudstack/en-US/images/title_logo.png new file mode 100644 index 00000000000..f0b1d20c677 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/title_logo.png differ diff --git a/docs/publican-cloudstack/en-US/images/title_logo.svg b/docs/publican-cloudstack/en-US/images/title_logo.svg new file mode 100644 index 00000000000..e8b3eca8d82 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/title_logo.svg @@ -0,0 +1,335 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +open source cloud computing + + + + + \ No newline at end of file diff --git a/docs/publican-cloudstack/en-US/images/warning.png b/docs/publican-cloudstack/en-US/images/warning.png new file mode 100644 index 00000000000..94b69d1ff1f Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/warning.png differ diff --git a/docs/publican-cloudstack/en-US/images/warning.svg b/docs/publican-cloudstack/en-US/images/warning.svg new file mode 100644 index 00000000000..4231e5ac041 --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/warning.svg @@ -0,0 +1,130 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/publican-cloudstack/en-US/images/watermark-draft.png b/docs/publican-cloudstack/en-US/images/watermark-draft.png new file mode 100644 index 00000000000..0ead5af8bb8 Binary files /dev/null and b/docs/publican-cloudstack/en-US/images/watermark-draft.png differ diff --git a/docs/publican-cloudstack/en-US/images/watermark-draft.svg b/docs/publican-cloudstack/en-US/images/watermark-draft.svg new file mode 100644 index 00000000000..4ecbf37fecf --- /dev/null +++ b/docs/publican-cloudstack/en-US/images/watermark-draft.svg @@ -0,0 +1,21 @@ + + + + watermark-draft + diff --git a/docs/publican-cloudstack/publican-cloudstack.spec b/docs/publican-cloudstack/publican-cloudstack.spec new file mode 100644 index 00000000000..f1f3c7d8780 --- /dev/null +++ b/docs/publican-cloudstack/publican-cloudstack.spec @@ -0,0 +1,46 @@ +%define brand cloudstack + +Name: publican-cloudstack +Summary: Common documentation files for %{brand} +Version: 0.2 +Release: 1%{?dist} +License: ASLv2 +Group: Applications/Text +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Buildarch: noarch +Source: %{name}-%{version}.tgz +Requires: publican >= 1.99 +BuildRequires: publican >= 1.99 +URL: http://cloudstack.org + +%description +This package provides common files and templates needed to build documentation +for %{brand} with publican. + +%prep +%setup -qn %{name} + +%build +publican build --formats=xml --langs=en-US --publish + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p -m755 $RPM_BUILD_ROOT%{_datadir}/publican/Common_Content +publican install_brand --path=$RPM_BUILD_ROOT%{_datadir}/publican/Common_Content + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc README +%doc LICENSE +%doc NOTICE +%{_datadir}/publican/Common_Content/%{brand} + +%changelog +* Tue Jun 26 2012 David Nalley 0.2-1 +- updated for ASF move +* Sat Aug 11 2011 David Nalley 0.1-1 +- Created Brand + diff --git a/docs/runbook/en-US/Author_Group.xml b/docs/runbook/en-US/Author_Group.xml new file mode 100644 index 00000000000..6fbece36fb6 --- /dev/null +++ b/docs/runbook/en-US/Author_Group.xml @@ -0,0 +1,12 @@ + + +%BOOK_ENTITIES; +]> + + + Apache + CloudStack + + + diff --git a/docs/runbook/en-US/Book_Info.xml b/docs/runbook/en-US/Book_Info.xml new file mode 100644 index 00000000000..4d622d563b0 --- /dev/null +++ b/docs/runbook/en-US/Book_Info.xml @@ -0,0 +1,32 @@ + + +%BOOK_ENTITIES; +]> + + Runbook + Prescriptive instructions for deploying Apache CloudStack + Apache CloudStack + 3.0.2 + 0 + 0 + + + These runbooks are designed to provide a strict environment to guarantee + a higher degree of success in initial deployments of Apache CloudStack. + All of the elements of the environment will be provided to you. + Apache CloudStack is capable of much more complex configurations, + but they are beyond the scope of this document. + + + + + + + + + + + + + diff --git a/docs/runbook/en-US/Chapter.xml b/docs/runbook/en-US/Chapter.xml new file mode 100644 index 00000000000..79579aa16e5 --- /dev/null +++ b/docs/runbook/en-US/Chapter.xml @@ -0,0 +1,33 @@ + + +%BOOK_ENTITIES; +]> + + Test Chapter + + This is a test paragraph + +
+ Test Section 1 + + This is a test paragraph in a section + +
+ +
+ Test Section 2 + + This is a test paragraph in Section 2 + + + + listitem text + + + + +
+ +
+ diff --git a/docs/runbook/en-US/Environment.xml b/docs/runbook/en-US/Environment.xml new file mode 100644 index 00000000000..1d6590598d7 --- /dev/null +++ b/docs/runbook/en-US/Environment.xml @@ -0,0 +1,224 @@ + + +%BOOK_ENTITIES; +]> + + Environment + + Before you begin, you need to prepare the environment before you install CloudStack. + We will go over the steps to prepare now. + +
+ Operating System + + Using the CentOS 6.2 x86_64 minimal install ISO, you'll need to install CentOS + on your hardware. The defaults will generally be acceptable for this installation. + + + Once this installation is complete, you'll want to connect to your freshly + installed machine via SSH as the root user. Note that you should not allow root + logins in a production environment, so be sure to turn off remote logins once you + have finished the installation and configuration. + +
+ Configuring the network + + By default the network will not come up on your hardware and you + will need to configure it to work in your environment. Since we + specified that there will be no DHCP server in this environment + we will be manually configuring your network interface. We will + assume, for the purposes of this exercise, that eth0 is the only network + interface that will be connected and used. + + + Connecting via the console you should login as root. Check the + file /etc/sysconfig/network-scripts/ifcfg-eth0, + it will look like this by default: + +DEVICE="eth0" +HWADDR="52:54:00:B9:A6:C0" +NM_CONTROLLED="yes" +ONBOOT="no" + + + + Unfortunately, this configuration will not permit you to connect to the network, + and is also unsuitable for our purposes with CloudStack. We want to + configure that file so that it specifies the IP address, netmask, etc., as shown + in the following example: + + +DEVICE=eth0 +HWADDR=52:54:00:B9:A6:C0 +NM_CONTROLLED=no +ONBOOT=yes +BOOTPROTO=none +IPADDR=172.16.10.2 +NETMASK=255.255.255.0 +GATEWAY=172.16.10.1 + + + IP Addressing + Throughout this document we are assuming that you will + have a /24 network for your CloudStack implementation. This can be any + RFC 1918 network. However, we are assuming that you will match the + machine address that we are using. Thus we may use + 172.16.10.2 and because + you might be using the 192.168.55.0/24 network you would use + 192.168.55.2 + + + + Hardware Addresses + You should not use the hardware address (aka MAC address) from our example + for your configuration. It is network interface specific, so you should keep the + address already provided in the HWADDR directive. + + + Now that we have the configuration files properly set up, we need to run a + few commands to start up the network + # chkconfig network on + # service network start + This should bring the network up successfully, but we now need to enable name resolution. + To do that we will edit /etc/resolv.conf. These instructions will add + one of the nameservers from Google, though you are free to add a local nameserver if you wish. + Your /etc/resolv.conf should modified to look like: + + +nameserver 8.8.8.8 + + +
+
+ Hostname + + Cloudstack requires that the hostname be properly set. If you used the default + options in the installation, then your hostname is currently set to + localhost.localdomain. To test this we will run: + # hostname --fqdn + At this point it will likely return: + localhost + To rectify this situation - we'll set the hostname by editing the + /etc/hosts file so that it follows a similar format to this example: +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +172.16.10.2 srvr1.cloud.priv + + + After you've modified that file, go ahead and restart the network using: +# service network restart + Now recheck with the hostname --fqdn command and ensure that it returns + a FQDN response +
+
+ SELinux + At the moment, for CloudStack to work properly SELinux must be + set to permissive. We want to both configure this for future boots and modify it + in the current running system. + + To configure SELinux to be permissive in the running system we need to run + the following command: + # setenforce 0 + + To ensure that it remains in that state we need to configure the file + /etc/selinux/config to reflect the permissive state, + as shown in this example: + + +# This file controls the state of SELinux on the system. +# SELINUX= can take one of these three values: +# enforcing - SELinux security policy is enforced. +# permissive - SELinux prints warnings instead of enforcing. +# disabled - No SELinux policy is loaded. +SELINUX=permissive +# SELINUXTYPE= can take one of these two values: +# targeted - Targeted processes are protected, +# mls - Multi Level Security protection. +SELINUXTYPE=targeted + + +
+
+ NTP + NTP configuration is a necessity for keeping all of the clocks in your cloud + servers in sync. However, NTP is not installed by default. So we'll install and + and configure NTP at this stage. Installation is accomplished as follows: + + # yum install ntp + The actual default configuration is fine for our purposes, so we merely need to + enable it and set it to start on boot as follows: + # chkconfig ntpd on + # service ntpd start +
+
+
+ NFS + + Our configuration is going to use NFS for both primary and secondary + storage. We are going to go ahead and setup two NFS shares for those + purposes. We'll start out by installing + nfs-utils. + + # yum install nfs-utils + + We now need to configure NFS to serve up two different shares. This is handled comparatively easily + in the /etc/exports file. You should ensure that it has the following content: + + +/secondary *(rw,async,no_root_squash) +/primary *(rw,async,no_root_squash) + + + You will note that we specified two directories that don't exist (yet) on the system. + We'll go ahead and create those directories and set permissions appropriately on them with the following commands: + + +# mkdir /primary +# mkdir /secondary +# chmod 777 /primary +# chmod 777 /secondary + + CentOS 6.x releases use NFSv4 by default. NFSv4 requires that domain setting matches on all clients. + In our case, the domain is cloud.priv, so ensure that the domain setting in /etc/idmapd.conf + is uncommented and set as follows: + Domain = cloud.priv + Now you'll need uncomment the configuration values in the file /etc/sysconfig/nfs + +LOCKD_TCPPORT=32803 +LOCKD_UDPPORT=32769 +MOUNTD_PORT=892 +RQUOTAD_PORT=875 +STATD_PORT=662 +STATD_OUTGOING_PORT=2020 + + Now we need to configure the firewall to permit incoming NFS connections. + Edit the file /etc/sysconfig/nfs + + +-A INPUT -m state --state NEW -p udp --dport 111 -j ACCEPT +-A INPUT -m state --state NEW -p tcp --dport 111 -j ACCEPT +-A INPUT -m state --state NEW -p tcp --dport 2049 -j ACCEPT +-A INPUT -m state --state NEW -p tcp --dport 32803 -j ACCEPT +-A INPUT -m state --state NEW -p udp --dport 32769 -j ACCEPT +-A INPUT -m state --state NEW -p tcp --dport 892 -j ACCEPT +-A INPUT -m state --state NEW -p udp --dport 892 -j ACCEPT +-A INPUT -m state --state NEW -p tcp --dport 875 -j ACCEPT +-A INPUT -m state --state NEW -p udp --dport 875 -j ACCEPT +-A INPUT -m state --state NEW -p tcp --dport 662 -j ACCEPT +-A INPUT -m state --state NEW -p udp --dport 662 -j ACCEPT + + Now you can restart the iptables service with the following command: + + # service iptables restart + We now need to configure nfs service to start on boot and actually start it on the host by + executing the following commands: + + # service rpcbind start + # service nfs start + # chkconfig rpcbind on + # chkconfig nfs on + +
+ + +
diff --git a/docs/runbook/en-US/Management.xml b/docs/runbook/en-US/Management.xml new file mode 100644 index 00000000000..2d915e4a585 --- /dev/null +++ b/docs/runbook/en-US/Management.xml @@ -0,0 +1,107 @@ + + +%BOOK_ENTITIES; +]> + + Installation of the management server + + Now it is time to start installing CloudStack's management server + and some of the related components. + +
+ Database Installation and Configuration + + We'll start out by installing MySQL and configuring + some options to ensure CloudStack runs well. + + + To install MySQL run the following command: + # yum -y install mysql-server + + With MySQL installed we need to make + a few configuration changes to /etc/my.cnf. + Specifically we need to add the following options to the [mysqld] section: + +innodb_rollback_on_timeout=1 +innodb_lock_wait_timeout=600 +max_connections=350 +log-bin=mysql-bin +binlog-format = 'ROW' + + + + Now that MySQL is properly configured we can + start it and configure it to start on boot as follows: + + # service mysqld start + # chkconfig mysqld on + + + +
+ +
+ Extraction + + The next step is to extract the contents of the CloudStack tarball + (mentioned in ) you + downloaded previously. To extract the contents of this tarball use + the following command: + + + # tar -xzvf CloudStack-oss-3.0.2-1-rhel6.2.tar.gz + + For the next few sections you'll need to cd into the first level that was just created. + +
+
+ Installation + Now that you are in the directory created by extracting the tarball, it's now time to install. We'll run + ./install.sh and choose option . This will install the management server + and necessary dependencies. + + With the application itself installed we can now setup the database, we'll do that with the following command + and options: + + + # cloud-setup-databases cloud:password@localhost --deploy-as=root + + When this process is finished, you should see a message like "CloudStack has successfully initialized the database." + + Now that the database has been created, we can take the final step in setting up the management server by issuing the following command: + + # cloud-setup-mangament + +
+
+ System Template Setup + CloudStack uses a number of system VMs to provide functionality for + accessing the console of virtual machines, providing various networking + services, and managing various aspects of storage. This step will + acquire those system images ready for deployment when we bootstrap + your cloud. + + + The place we are going to download these images to is the secondary + storage share that we setup earlier, so we'll need to mount that share + with the mount command run on the management server: + + + # mount -t nfs 172.16.10.2/secondary /mnt/secondary + + + Now we need to download the system VM template and deploy that to the + share we just mounted. The management server includes a script to properly + manipulate the system VMs images. + + + # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -F + + + That concludes our setup of the management server. We still need to + configure CloudStack, but we will do that after we get our hypervisor + set up. + +
+
diff --git a/docs/runbook/en-US/Overview.xml b/docs/runbook/en-US/Overview.xml new file mode 100644 index 00000000000..b0bca9d6986 --- /dev/null +++ b/docs/runbook/en-US/Overview.xml @@ -0,0 +1,67 @@ + + +%BOOK_ENTITIES; +]> + + Overview + + Infrastructure-as-a-Service (IaaS) clouds can be a complex thing to build, + and by definition they have a plethora of options, which often lead to confusion + for even experienced admins who are newcomers to building cloud platforms. + The goal for this runbook is to provide a straightforward set of instructions + to get you up and running with CloudStack with a minimum amount of trouble. + +
+ What exactly are we building? + + This runbook will focus on building a CloudStack cloud using KVM with + CentOS 6.2 with NFS storage utilizing Layer-3 for network isolation + (aka Security Groups). + + + KVM, or Kernel-based Virtual Machine is a virtualization technology + for the Linux kernel. KVM supports native virtualization atop + processors with hardware virtualization extensions. + + + Security Groups act as distributed firewalls that control access + to a group of virtual machines. + +
+ +
+ Prerequisites + + To complete this runbook you'll need the following items: + + + + At least one computer which supports hardware virtualization. + + + + + The CentOS 6.2 x86_64 minimal installation CD available from here: + + + + + + + A /24 network with the gateway being at xxx.xxx.xxx.1, no DHCP should be on this network and + none of the computers running CloudStack may have a dynamic address. + + + + + Copy of CloudStack 3.0.2 for Red Hat Enterprise Linux (RHEL) and CentOS 6.2 available here: + + + + + + +
+ +
diff --git a/docs/runbook/en-US/Preface.xml b/docs/runbook/en-US/Preface.xml new file mode 100644 index 00000000000..ff399fa9be8 --- /dev/null +++ b/docs/runbook/en-US/Preface.xml @@ -0,0 +1,13 @@ + + +%BOOK_ENTITIES; +]> + + Preface + + + + + + diff --git a/docs/runbook/en-US/Revision_History.xml b/docs/runbook/en-US/Revision_History.xml new file mode 100644 index 00000000000..263cd93b7e0 --- /dev/null +++ b/docs/runbook/en-US/Revision_History.xml @@ -0,0 +1,22 @@ + + +%BOOK_ENTITIES; +]> + + Revision History + + + + 0-0 + Mon Jun 25 2012 + + + Initial creation of book by publican + + + + + + + diff --git a/docs/runbook/en-US/Runbook.ent b/docs/runbook/en-US/Runbook.ent new file mode 100644 index 00000000000..535d45aac3c --- /dev/null +++ b/docs/runbook/en-US/Runbook.ent @@ -0,0 +1,4 @@ + + + + diff --git a/docs/runbook/en-US/Runbook.xml b/docs/runbook/en-US/Runbook.xml new file mode 100644 index 00000000000..f700a175595 --- /dev/null +++ b/docs/runbook/en-US/Runbook.xml @@ -0,0 +1,17 @@ + + +%BOOK_ENTITIES; +]> + + + + + + + + + + + + diff --git a/docs/runbook/en-US/config.xml b/docs/runbook/en-US/config.xml new file mode 100644 index 00000000000..29a04f5d8e7 --- /dev/null +++ b/docs/runbook/en-US/config.xml @@ -0,0 +1,159 @@ + + +%BOOK_ENTITIES; +]> + + Configuration + + As we noted before we will be using security groups to provide isolation + and by default that implies that we'll be using a flat layer-2 network. + It also means that the simplicity of our setup means that we can use the + quick installer. + +
+ UI Access + + To get access to CloudStack's web interface, merely point your + browser to http://172.16.10.2:8080/client + The default username is 'admin', and the default password is 'password'. + You should see a splash screen that allows you to choose several options + for setting up CloudStack. You should choose the + option. + + + You should now see a prompt requiring you to change the password for + the admin user. Please do so. + +
+
+ Setting up a Zone + + A zone is the largest organization entity in CloudStack - and we'll be creating one, this + should be the screen that you see in front of you now. And for us there are 5 pieces of + information that we need. + + + Name - we will set this to the ever-descriptive 'Zone1' for our cloud. + + + Public DNS 1 - we will set this to '8.8.8.8' for our cloud. + + + Public DNS 2 - we will set this to '8.8.4.4' for our cloud. + + + Internal DNS1 - we will also set this to '8.8.8.8' for our cloud. + + + Internal DNS2 - we will also set this to '8.8.8.4' for our cloud. + + + + + Notes about DNS settings + + CloudStack distinguishes between internal and public DNS. Internal + DNS is assumed to be capable of resolving internal-only + hostnames, such as your NFS server’s DNS name. Public DNS is + provided to the guest VMs to resolve public IP addresses. You can + enter the same DNS server for both types, but if you do so, you + must make sure that both internal and public IP addresses can + route to the DNS server. In our specific case we will not use any + names for resources internally, and we have indeed them set to look + to the same external resource so as to not add a namerserver setup + to our list of requirements. + + +
+
+ Pod Configuration + Now that we've added a Zone, the next step that comes up is a prompt + for information regading a pod. Which is looking for 4 items. + + + Name - We'll use Pod1 for our cloud. + + + Gateway - We'll use 172.16.10.1 as our gateway + + + Netmask - We'll use 255.255.255.0 + + + Start/end reserved system IPs - we will use 172.16.10.10-172.16.10.20 + + + Guest gateway - We'll use 172.16.10.1 + + + Guest netmask - We'll use 255.255.255.0 + + + Guest start/end IP - We'll use 172.16.10.30-172.16.10.200 + + + +
+
+ Cluster + Now that we've added a Zone, we need only add a few more items for configuring the cluster. + + + Name - We'll use Cluster1 + + + Hypervisor - If this is the first cluster, you may have already been prompted for which hypervisor you were going to use, in which case this will + be a read-only field. Otherwise choose KVM + + + + + You should be prompted to add the first host to your cluster at this point. Only a few bits of information are needed. + + + Hostname - we'll use the IP address 172.16.10.2 since we didn't set up a DNS server. + + + Username - we'll use 'root' + + + Password - enter the operating system password for the root user + + + Host tags - This is an optional field and we will leave it blank + + + +
+ Primary Storage + With you cluster now setup - you should be prompted for primary storage information. Choose NFS as the storage type and then enter the following values in the fields: + + + Server - We'll be using the IP address 172.16.10.2 + + + Path - Well define /primary as the path we are using + + + +
+
+ Secondary Storage + If this is a new zone, you'll be prompted for secondary storage information - populate it as follows: + + + NFS server - We'll use the IP address 172.16.10.2 + + + Path - We'll use /secondary + + + + Now, click Launch and your cloud should begin setup - it may take several minutes depending on your internet connection speed for setup to finalize. +
+
+ + +
+ diff --git a/docs/runbook/en-US/images/icon.svg b/docs/runbook/en-US/images/icon.svg new file mode 100644 index 00000000000..b2f16d0f61d --- /dev/null +++ b/docs/runbook/en-US/images/icon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/docs/runbook/en-US/kvm.xml b/docs/runbook/en-US/kvm.xml new file mode 100644 index 00000000000..61802a4df4d --- /dev/null +++ b/docs/runbook/en-US/kvm.xml @@ -0,0 +1,83 @@ + + +%BOOK_ENTITIES; +]> + + KVM Setup and installation + + KVM is the hypervisor we'll be using - we will recover the initial setup + which has already been done on the hypervisor host and cover installation + of the agent software, you can use the same steps to add additional KVM + nodes to your CloudStack environment. + +
+ Prerequisites + + We explicitly are using the management server as a compute node as well, + which means that we have already performed many of the prerequisite steps + when setting up the management server, but we will list them here for + clarity. Those steps are: + + + + + + + + + + + + + + + + + + + + + + + + + You shouldn't need to do that for the management server, of course, but + any additional hosts will need for you to complete the above steps. + +
+ +
+ Installation + + You'll need to ensure that you are in the directory that was created when + we extracted the the tarball. + + + + You'll be running ./install.sh again and this time + choosing which will install the software necessary for + managing a KVM node. + +
+
+ KVM Configuration + + KVM configuration is relatively simple at only a single item. We need to + edit the QEMU VNC configuration. This is done by editing + /etc/libvirt/qemu.conf and ensuring the following + line is present and uncommented. + vnc_listen=0.0.0.0 + + + You can now just restart the libvirt daemon by issuing the following command: + # service libvirt restart + + + That concludes our installation and configuration of KVM, and we'll now move to using the CloudStack UI + for the actual configuration of our cloud. + +
+ +
+ diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index 76c4e2109bb..eb10e167732 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package com.cloud.hypervisor.vmware.mo; +package com.cloud.hypervisor.vmware.mo; import java.util.ArrayList; import java.util.List; @@ -37,64 +37,64 @@ import com.vmware.vim25.TraversalSpec; import com.vmware.vim25.VirtualDeviceBackingInfo; import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; - -public class DatacenterMO extends BaseMO { - - public DatacenterMO(VmwareContext context, ManagedObjectReference morDc) { - super(context, morDc); - } - - public DatacenterMO(VmwareContext context, String morType, String morValue) { - super(context, morType, morValue); - } - - public DatacenterMO(VmwareContext context, String dcName) throws Exception { - super(context, null); - - _mor = _context.getServiceUtil().getDecendentMoRef(_context.getRootFolder(), "Datacenter", dcName); - assert(_mor != null); - } - - public String getName() throws Exception { - return (String)_context.getServiceUtil().getDynamicProperty(_mor, "name"); - } - - public void registerTemplate(ManagedObjectReference morHost, String datastoreName, - String templateName, String templateFileName) throws Exception { - - ServiceUtil serviceUtil = _context.getServiceUtil(); - - ManagedObjectReference morFolder = (ManagedObjectReference)serviceUtil.getDynamicProperty( - _mor, "vmFolder"); - assert(morFolder != null); - - ManagedObjectReference morTask = _context.getService().registerVM_Task( - morFolder, - String.format("[%s] %s/%s", datastoreName, templateName, templateFileName), - templateName, true, - null, morHost); - - String result = serviceUtil.waitForTask(morTask); - if (!result.equalsIgnoreCase("Sucess")) { - throw new Exception("Unable to register template due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } else { - _context.waitForTaskProgressDone(morTask); - } - } - - public VirtualMachineMO findVm(String vmName) throws Exception { - ObjectContent[] ocs = getVmPropertiesOnDatacenterVmFolder(new String[] { "name" }); - if(ocs != null && ocs.length > 0) { - for(ObjectContent oc : ocs) { - DynamicProperty[] props = oc.getPropSet(); - if(props != null) { - for(DynamicProperty prop : props) { - if(prop.getVal().toString().equals(vmName)) - return new VirtualMachineMO(_context, oc.getObj()); - } - } - } - } + +public class DatacenterMO extends BaseMO { + + public DatacenterMO(VmwareContext context, ManagedObjectReference morDc) { + super(context, morDc); + } + + public DatacenterMO(VmwareContext context, String morType, String morValue) { + super(context, morType, morValue); + } + + public DatacenterMO(VmwareContext context, String dcName) throws Exception { + super(context, null); + + _mor = _context.getServiceUtil().getDecendentMoRef(_context.getRootFolder(), "Datacenter", dcName); + assert(_mor != null); + } + + public String getName() throws Exception { + return (String)_context.getServiceUtil().getDynamicProperty(_mor, "name"); + } + + public void registerTemplate(ManagedObjectReference morHost, String datastoreName, + String templateName, String templateFileName) throws Exception { + + ServiceUtil serviceUtil = _context.getServiceUtil(); + + ManagedObjectReference morFolder = (ManagedObjectReference)serviceUtil.getDynamicProperty( + _mor, "vmFolder"); + assert(morFolder != null); + + ManagedObjectReference morTask = _context.getService().registerVM_Task( + morFolder, + String.format("[%s] %s/%s", datastoreName, templateName, templateFileName), + templateName, true, + null, morHost); + + String result = serviceUtil.waitForTask(morTask); + if (!result.equalsIgnoreCase("Sucess")) { + throw new Exception("Unable to register template due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + } else { + _context.waitForTaskProgressDone(morTask); + } + } + + public VirtualMachineMO findVm(String vmName) throws Exception { + ObjectContent[] ocs = getVmPropertiesOnDatacenterVmFolder(new String[] { "name" }); + if(ocs != null && ocs.length > 0) { + for(ObjectContent oc : ocs) { + DynamicProperty[] props = oc.getPropSet(); + if(props != null) { + for(DynamicProperty prop : props) { + if(prop.getVal().toString().equals(vmName)) + return new VirtualMachineMO(_context, oc.getObj()); + } + } + } + } return null; } @@ -132,183 +132,183 @@ public class DatacenterMO extends BaseMO { } return list; } - - public List> getAllVmsOnDatacenter() throws Exception { - List> vms = new ArrayList>(); - - ObjectContent[] ocs = getVmPropertiesOnDatacenterVmFolder(new String[] { "name" }); - if(ocs != null) { - for(ObjectContent oc : ocs) { - String vmName = oc.getPropSet(0).getVal().toString(); - vms.add(new Pair(oc.getObj(), vmName)); - } - } - - return vms; - } - - public ManagedObjectReference findDatastore(String name) throws Exception { - assert(name != null); - - ObjectContent[] ocs = getDatastorePropertiesOnDatacenter(new String[] { "name" }); - if(ocs != null) { - for(ObjectContent oc : ocs) { - if(oc.getPropSet(0).getVal().toString().equals(name)) { - return oc.getObj(); - } - } - } - return null; - } - - public ManagedObjectReference findHost(String name) throws Exception { - ObjectContent[] ocs= getHostPropertiesOnDatacenterHostFolder(new String[] { "name" }); - - if(ocs != null) { - for(ObjectContent oc : ocs) { - if(oc.getPropSet(0).getVal().toString().equals(name)) { - return oc.getObj(); - } - } - } - return null; - } - - public ManagedObjectReference getVmFolder() throws Exception { - return (ManagedObjectReference)_context.getServiceUtil().getDynamicProperty(_mor, "vmFolder"); - } - - public ObjectContent[] getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws Exception { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("HostSystem"); - pSpec.setPathSet(propertyPaths); - - TraversalSpec computeResource2HostTraversal = new TraversalSpec(); - computeResource2HostTraversal.setType("ComputeResource"); - computeResource2HostTraversal.setPath("host"); - computeResource2HostTraversal.setName("computeResource2HostTraversal"); - - SelectionSpec recurseFolders = new SelectionSpec(); - recurseFolders.setName("folder2childEntity"); - - TraversalSpec folder2childEntity = new TraversalSpec(); - folder2childEntity.setType("Folder"); - folder2childEntity.setPath("childEntity"); - folder2childEntity.setName(recurseFolders.getName()); - folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders, computeResource2HostTraversal }); - - TraversalSpec dc2HostFolderTraversal = new TraversalSpec(); - dc2HostFolderTraversal.setType("Datacenter"); - dc2HostFolderTraversal.setPath("hostFolder"); - dc2HostFolderTraversal.setName("dc2HostFolderTraversal"); - dc2HostFolderTraversal.setSelectSet(new SelectionSpec[] { folder2childEntity } ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(_mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { dc2HostFolderTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - return _context.getService().retrieveProperties( - _context.getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - } - - public ObjectContent[] getDatastorePropertiesOnDatacenter(String[] propertyPaths) throws Exception { - - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("Datastore"); - pSpec.setPathSet(propertyPaths); - - TraversalSpec dc2DatastoreTraversal = new TraversalSpec(); - dc2DatastoreTraversal.setType("Datacenter"); - dc2DatastoreTraversal.setPath("datastore"); - dc2DatastoreTraversal.setName("dc2DatastoreTraversal"); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(_mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { dc2DatastoreTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - return _context.getService().retrieveProperties( - _context.getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - } - - public ObjectContent[] getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("VirtualMachine"); - pSpec.setPathSet(propertyPaths); - - TraversalSpec dc2VmFolderTraversal = new TraversalSpec(); - dc2VmFolderTraversal.setType("Datacenter"); - dc2VmFolderTraversal.setPath("vmFolder"); - dc2VmFolderTraversal.setName("dc2VmFolderTraversal"); - - SelectionSpec recurseFolders = new SelectionSpec(); - recurseFolders.setName("folder2childEntity"); - - TraversalSpec folder2childEntity = new TraversalSpec(); - folder2childEntity.setType("Folder"); - folder2childEntity.setPath("childEntity"); - folder2childEntity.setName(recurseFolders.getName()); - folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders }); - dc2VmFolderTraversal.setSelectSet(new SelectionSpec[] { folder2childEntity } ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(_mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { dc2VmFolderTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - return _context.getService().retrieveProperties( - _context.getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - } - - public static Pair getOwnerDatacenter(VmwareContext context, - ManagedObjectReference morEntity) throws Exception { - - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("Datacenter"); - pSpec.setPathSet(new String[] { "name" }); - - TraversalSpec entityParentTraversal = new TraversalSpec(); - entityParentTraversal.setType("ManagedEntity"); - entityParentTraversal.setPath("parent"); - entityParentTraversal.setName("entityParentTraversal"); - entityParentTraversal.setSelectSet(new SelectionSpec[] { new SelectionSpec(null, null, "entityParentTraversal") }); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(morEntity); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { entityParentTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = context.getService().retrieveProperties( - context.getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - assert(ocs != null); - assert(ocs[0].getObj() != null); - assert(ocs[0].getPropSet(0) != null); - assert(ocs[0].getPropSet(0).getVal() != null); - - String dcName = ocs[0].getPropSet(0).getVal().toString(); - return new Pair(new DatacenterMO(context, ocs[0].getObj()), dcName); + + public List> getAllVmsOnDatacenter() throws Exception { + List> vms = new ArrayList>(); + + ObjectContent[] ocs = getVmPropertiesOnDatacenterVmFolder(new String[] { "name" }); + if(ocs != null) { + for(ObjectContent oc : ocs) { + String vmName = oc.getPropSet(0).getVal().toString(); + vms.add(new Pair(oc.getObj(), vmName)); + } + } + + return vms; + } + + public ManagedObjectReference findDatastore(String name) throws Exception { + assert(name != null); + + ObjectContent[] ocs = getDatastorePropertiesOnDatacenter(new String[] { "name" }); + if(ocs != null) { + for(ObjectContent oc : ocs) { + if(oc.getPropSet(0).getVal().toString().equals(name)) { + return oc.getObj(); + } + } + } + return null; + } + + public ManagedObjectReference findHost(String name) throws Exception { + ObjectContent[] ocs= getHostPropertiesOnDatacenterHostFolder(new String[] { "name" }); + + if(ocs != null) { + for(ObjectContent oc : ocs) { + if(oc.getPropSet(0).getVal().toString().equals(name)) { + return oc.getObj(); + } + } + } + return null; + } + + public ManagedObjectReference getVmFolder() throws Exception { + return (ManagedObjectReference)_context.getServiceUtil().getDynamicProperty(_mor, "vmFolder"); + } + + public ObjectContent[] getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws Exception { + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("HostSystem"); + pSpec.setPathSet(propertyPaths); + + TraversalSpec computeResource2HostTraversal = new TraversalSpec(); + computeResource2HostTraversal.setType("ComputeResource"); + computeResource2HostTraversal.setPath("host"); + computeResource2HostTraversal.setName("computeResource2HostTraversal"); + + SelectionSpec recurseFolders = new SelectionSpec(); + recurseFolders.setName("folder2childEntity"); + + TraversalSpec folder2childEntity = new TraversalSpec(); + folder2childEntity.setType("Folder"); + folder2childEntity.setPath("childEntity"); + folder2childEntity.setName(recurseFolders.getName()); + folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders, computeResource2HostTraversal }); + + TraversalSpec dc2HostFolderTraversal = new TraversalSpec(); + dc2HostFolderTraversal.setType("Datacenter"); + dc2HostFolderTraversal.setPath("hostFolder"); + dc2HostFolderTraversal.setName("dc2HostFolderTraversal"); + dc2HostFolderTraversal.setSelectSet(new SelectionSpec[] { folder2childEntity } ); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(_mor); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { dc2HostFolderTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + + return _context.getService().retrieveProperties( + _context.getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + } + + public ObjectContent[] getDatastorePropertiesOnDatacenter(String[] propertyPaths) throws Exception { + + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("Datastore"); + pSpec.setPathSet(propertyPaths); + + TraversalSpec dc2DatastoreTraversal = new TraversalSpec(); + dc2DatastoreTraversal.setType("Datacenter"); + dc2DatastoreTraversal.setPath("datastore"); + dc2DatastoreTraversal.setName("dc2DatastoreTraversal"); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(_mor); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { dc2DatastoreTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + + return _context.getService().retrieveProperties( + _context.getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + } + + public ObjectContent[] getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception { + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("VirtualMachine"); + pSpec.setPathSet(propertyPaths); + + TraversalSpec dc2VmFolderTraversal = new TraversalSpec(); + dc2VmFolderTraversal.setType("Datacenter"); + dc2VmFolderTraversal.setPath("vmFolder"); + dc2VmFolderTraversal.setName("dc2VmFolderTraversal"); + + SelectionSpec recurseFolders = new SelectionSpec(); + recurseFolders.setName("folder2childEntity"); + + TraversalSpec folder2childEntity = new TraversalSpec(); + folder2childEntity.setType("Folder"); + folder2childEntity.setPath("childEntity"); + folder2childEntity.setName(recurseFolders.getName()); + folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders }); + dc2VmFolderTraversal.setSelectSet(new SelectionSpec[] { folder2childEntity } ); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(_mor); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { dc2VmFolderTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + + return _context.getService().retrieveProperties( + _context.getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + } + + public static Pair getOwnerDatacenter(VmwareContext context, + ManagedObjectReference morEntity) throws Exception { + + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("Datacenter"); + pSpec.setPathSet(new String[] { "name" }); + + TraversalSpec entityParentTraversal = new TraversalSpec(); + entityParentTraversal.setType("ManagedEntity"); + entityParentTraversal.setPath("parent"); + entityParentTraversal.setName("entityParentTraversal"); + entityParentTraversal.setSelectSet(new SelectionSpec[] { new SelectionSpec(null, null, "entityParentTraversal") }); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(morEntity); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { entityParentTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + + ObjectContent[] ocs = context.getService().retrieveProperties( + context.getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + + assert(ocs != null); + assert(ocs[0].getObj() != null); + assert(ocs[0].getPropSet(0) != null); + assert(ocs[0].getPropSet(0).getVal() != null); + + String dcName = ocs[0].getPropSet(0).getVal().toString(); + return new Pair(new DatacenterMO(context, ocs[0].getObj()), dcName); } @@ -469,5 +469,5 @@ public class DatacenterMO extends BaseMO { System.out.println("Plugging NIC device into network " + networkInfo.second() + " backed by dvSwitch: " + dvSwitchUuid); return dvPortBacking; - } + } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java index 4ee85cb5545..c8e0ca1e5e2 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java @@ -889,12 +889,12 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost { if(s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - getHyperHostHardwareSummary() done"); - return resourceSummary; - } - - @Override - public boolean isHyperHostConnected() throws Exception { - HostRuntimeInfo runtimeInfo = (HostRuntimeInfo)_context.getServiceUtil().getDynamicProperty(_mor, "runtime"); - return runtimeInfo.getConnectionState() == HostSystemConnectionState.connected; + return resourceSummary; + } + + @Override + public boolean isHyperHostConnected() throws Exception { + HostRuntimeInfo runtimeInfo = (HostRuntimeInfo)_context.getServiceUtil().getDynamicProperty(_mor, "runtime"); + return runtimeInfo.getConnectionState() == HostSystemConnectionState.connected; } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index e475907fe4c..944d66cdfc3 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -14,8 +14,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.hypervisor.vmware.mo; - +package com.cloud.hypervisor.vmware.mo; + import java.io.File; import java.net.URI; import java.net.URISyntaxException; @@ -62,29 +62,29 @@ import com.vmware.vim25.VirtualMachineConfigSpec; import com.vmware.vim25.VirtualMachineFileInfo; import com.vmware.vim25.VirtualMachineVideoCard; import com.vmware.vim25.VirtualSCSISharing; - -public class HypervisorHostHelper { - private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class); + +public class HypervisorHostHelper { + private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class); private static final int DEFAULT_LOCK_TIMEOUT_SECONDS = 600; - private static final String s_policyNamePrefix = "cloud.policy."; - - // make vmware-base loosely coupled with cloud-specific stuff, duplicate VLAN.UNTAGGED constant here - private static final String UNTAGGED_VLAN_NAME = "untagged"; - - public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, - ObjectContent[] ocs, String name) { - - if(ocs != null && ocs.length > 0) { - for(ObjectContent oc : ocs) { - DynamicProperty prop = oc.getPropSet(0); - assert(prop != null); - if(prop.getVal().toString().equals(name)) - return new VirtualMachineMO(context, oc.getObj()); - } - } - return null; + private static final String s_policyNamePrefix = "cloud.policy."; + + // make vmware-base loosely coupled with cloud-specific stuff, duplicate VLAN.UNTAGGED constant here + private static final String UNTAGGED_VLAN_NAME = "untagged"; + + public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, + ObjectContent[] ocs, String name) { + + if(ocs != null && ocs.length > 0) { + for(ObjectContent oc : ocs) { + DynamicProperty prop = oc.getPropSet(0); + assert(prop != null); + if(prop.getVal().toString().equals(name)) + return new VirtualMachineMO(context, oc.getObj()); + } + } + return null; } - + public static ManagedObjectReference findDatastoreWithBackwardsCompatibility(VmwareHypervisorHost hyperHost, String uuidName) throws Exception { ManagedObjectReference morDs = hyperHost.findDatastore(uuidName.replace("-", "")); if(morDs == null) @@ -92,21 +92,21 @@ public class HypervisorHostHelper { return morDs; } - - public static DatastoreMO getHyperHostDatastoreMO(VmwareHypervisorHost hyperHost, String datastoreName) throws Exception { - ObjectContent[] ocs = hyperHost.getDatastorePropertiesOnHyperHost(new String[] { "name"} ); - if(ocs != null && ocs.length > 0) { - for(ObjectContent oc : ocs) { - DynamicProperty[] objProps = oc.getPropSet(); - if(objProps != null) { - for(DynamicProperty objProp : objProps) { - if(objProp.getVal().toString().equals(datastoreName)) - return new DatastoreMO(hyperHost.getContext(), oc.getObj()); - } - } - } - } - return null; + + public static DatastoreMO getHyperHostDatastoreMO(VmwareHypervisorHost hyperHost, String datastoreName) throws Exception { + ObjectContent[] ocs = hyperHost.getDatastorePropertiesOnHyperHost(new String[] { "name"} ); + if(ocs != null && ocs.length > 0) { + for(ObjectContent oc : ocs) { + DynamicProperty[] objProps = oc.getPropSet(); + if(objProps != null) { + for(DynamicProperty objProp : objProps) { + if(objProp.getVal().toString().equals(datastoreName)) + return new DatastoreMO(hyperHost.getContext(), oc.getObj()); + } + } + } + } + return null; } public static String getPublicNetworkNamePrefix(String vlanId) { @@ -116,7 +116,7 @@ public class HypervisorHostHelper { return "cloud.public." + vlanId; } } - + public static String composeCloudNetworkName(String prefix, String vlanId, Integer networkRateMbps, String vSwitchName) { StringBuffer sb = new StringBuffer(prefix); if(vlanId == null || UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) @@ -684,222 +684,222 @@ public class HypervisorHostHelper { return true; } - - public static ManagedObjectReference waitForNetworkReady(HostMO hostMo, - String networkName, long timeOutMs) throws Exception { - - ManagedObjectReference morNetwork = null; - - // if portGroup is just created, getNetwork may fail to retrieve it, we - // need to retry - long startTick = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTick <= timeOutMs) { - morNetwork = hostMo.getNetworkMor(networkName); - if (morNetwork != null) { - break; - } - - s_logger.info("Waiting for network " + networkName + " to be ready"); - Thread.sleep(1000); - } - - return morNetwork; - } - - public static boolean createBlankVm(VmwareHypervisorHost host, String vmName, - int cpuCount, int cpuSpeedMHz, int cpuReservedMHz, boolean limitCpuUse, int memoryMB, int memoryReserveMB, String guestOsIdentifier, - ManagedObjectReference morDs, boolean snapshotDirToParent) throws Exception { - - if(s_logger.isInfoEnabled()) - s_logger.info("Create blank VM. cpuCount: " + cpuCount + ", cpuSpeed(MHz): " + cpuSpeedMHz + ", mem(Mb): " + memoryMB); - - // VM config basics - VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec(); - vmConfig.setName(vmName); - VmwareHelper.setBasicVmConfig(vmConfig, cpuCount, cpuSpeedMHz, cpuReservedMHz, memoryMB, memoryReserveMB, guestOsIdentifier, limitCpuUse); - - // Scsi controller - VirtualLsiLogicController scsiController = new VirtualLsiLogicController(); - scsiController.setSharedBus(VirtualSCSISharing.noSharing); - scsiController.setBusNumber(0); - scsiController.setKey(1); - VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec(); - scsiControllerSpec.setDevice(scsiController); - scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.add); - - VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo(); - DatastoreMO dsMo = new DatastoreMO(host.getContext(), morDs); - fileInfo.setVmPathName(String.format("[%s]", dsMo.getName())); - vmConfig.setFiles(fileInfo); - - VirtualMachineVideoCard videoCard = new VirtualMachineVideoCard(); - videoCard.setControllerKey(100); - videoCard.setUseAutoDetect(true); - - VirtualDeviceConfigSpec videoDeviceSpec = new VirtualDeviceConfigSpec(); - videoDeviceSpec.setDevice(videoCard); - videoDeviceSpec.setOperation(VirtualDeviceConfigSpecOperation.add); - - vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec, videoDeviceSpec }); - if(host.createVm(vmConfig)) { - VirtualMachineMO vmMo = host.findVmOnHyperHost(vmName); - assert(vmMo != null); - - int ideControllerKey = -1; - while(ideControllerKey < 0) { - ideControllerKey = vmMo.tryGetIDEDeviceControllerKey(); - if(ideControllerKey >= 0) - break; - - s_logger.info("Waiting for IDE controller be ready in VM: " + vmName); - Thread.sleep(1000); - } - - if(snapshotDirToParent) { - String snapshotDir = String.format("/vmfs/volumes/%s/", dsMo.getName()); - - s_logger.info("Switch snapshot working directory to " + snapshotDir + " for " + vmName); - vmMo.setSnapshotDirectory(snapshotDir); - - // Don't have a good way to test if the VM is really ready for use through normal API after configuration file manipulation, - // delay 3 seconds - Thread.sleep(3000); - } - - s_logger.info("Blank VM: " + vmName + " is ready for use"); - return true; - } - return false; - } - - public static String resolveHostNameInUrl(DatacenterMO dcMo, String url) { - - s_logger.info("Resolving host name in url through vCenter, url: " + url); - - URI uri; - try { - uri = new URI(url); - } catch (URISyntaxException e) { - s_logger.warn("URISyntaxException on url " + url); - return url; - } - - String host = uri.getHost(); - if(NetUtils.isValidIp(host)) { - s_logger.info("host name in url is already in IP address, url: " + url); - return url; - } - - try { - ManagedObjectReference morHost = dcMo.findHost(host); - if(morHost != null) { + + public static ManagedObjectReference waitForNetworkReady(HostMO hostMo, + String networkName, long timeOutMs) throws Exception { + + ManagedObjectReference morNetwork = null; + + // if portGroup is just created, getNetwork may fail to retrieve it, we + // need to retry + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick <= timeOutMs) { + morNetwork = hostMo.getNetworkMor(networkName); + if (morNetwork != null) { + break; + } + + s_logger.info("Waiting for network " + networkName + " to be ready"); + Thread.sleep(1000); + } + + return morNetwork; + } + + public static boolean createBlankVm(VmwareHypervisorHost host, String vmName, + int cpuCount, int cpuSpeedMHz, int cpuReservedMHz, boolean limitCpuUse, int memoryMB, int memoryReserveMB, String guestOsIdentifier, + ManagedObjectReference morDs, boolean snapshotDirToParent) throws Exception { + + if(s_logger.isInfoEnabled()) + s_logger.info("Create blank VM. cpuCount: " + cpuCount + ", cpuSpeed(MHz): " + cpuSpeedMHz + ", mem(Mb): " + memoryMB); + + // VM config basics + VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec(); + vmConfig.setName(vmName); + VmwareHelper.setBasicVmConfig(vmConfig, cpuCount, cpuSpeedMHz, cpuReservedMHz, memoryMB, memoryReserveMB, guestOsIdentifier, limitCpuUse); + + // Scsi controller + VirtualLsiLogicController scsiController = new VirtualLsiLogicController(); + scsiController.setSharedBus(VirtualSCSISharing.noSharing); + scsiController.setBusNumber(0); + scsiController.setKey(1); + VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec(); + scsiControllerSpec.setDevice(scsiController); + scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.add); + + VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo(); + DatastoreMO dsMo = new DatastoreMO(host.getContext(), morDs); + fileInfo.setVmPathName(String.format("[%s]", dsMo.getName())); + vmConfig.setFiles(fileInfo); + + VirtualMachineVideoCard videoCard = new VirtualMachineVideoCard(); + videoCard.setControllerKey(100); + videoCard.setUseAutoDetect(true); + + VirtualDeviceConfigSpec videoDeviceSpec = new VirtualDeviceConfigSpec(); + videoDeviceSpec.setDevice(videoCard); + videoDeviceSpec.setOperation(VirtualDeviceConfigSpecOperation.add); + + vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec, videoDeviceSpec }); + if(host.createVm(vmConfig)) { + VirtualMachineMO vmMo = host.findVmOnHyperHost(vmName); + assert(vmMo != null); + + int ideControllerKey = -1; + while(ideControllerKey < 0) { + ideControllerKey = vmMo.tryGetIDEDeviceControllerKey(); + if(ideControllerKey >= 0) + break; + + s_logger.info("Waiting for IDE controller be ready in VM: " + vmName); + Thread.sleep(1000); + } + + if(snapshotDirToParent) { + String snapshotDir = String.format("/vmfs/volumes/%s/", dsMo.getName()); + + s_logger.info("Switch snapshot working directory to " + snapshotDir + " for " + vmName); + vmMo.setSnapshotDirectory(snapshotDir); + + // Don't have a good way to test if the VM is really ready for use through normal API after configuration file manipulation, + // delay 3 seconds + Thread.sleep(3000); + } + + s_logger.info("Blank VM: " + vmName + " is ready for use"); + return true; + } + return false; + } + + public static String resolveHostNameInUrl(DatacenterMO dcMo, String url) { + + s_logger.info("Resolving host name in url through vCenter, url: " + url); + + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + s_logger.warn("URISyntaxException on url " + url); + return url; + } + + String host = uri.getHost(); + if(NetUtils.isValidIp(host)) { + s_logger.info("host name in url is already in IP address, url: " + url); + return url; + } + + try { + ManagedObjectReference morHost = dcMo.findHost(host); + if(morHost != null) { HostMO hostMo = new HostMO(dcMo.getContext(), morHost); String managementPortGroupName; if(hostMo.getHostType() == VmwareHostType.ESXi) managementPortGroupName = (String)dcMo.getContext().getStockObject("manageportgroup"); else managementPortGroupName = (String)dcMo.getContext().getStockObject("serviceconsole"); - - VmwareHypervisorHostNetworkSummary summary = hostMo.getHyperHostNetworkSummary(managementPortGroupName); - if(summary == null) { - s_logger.warn("Unable to resolve host name in url through vSphere, url: " + url); - return url; - } - - String hostIp = summary.getHostIp(); - - try { - URI resolvedUri = new URI(uri.getScheme(), uri.getUserInfo(), hostIp, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment()); - - s_logger.info("url " + url + " is resolved to " + resolvedUri.toString() + " through vCenter"); - return resolvedUri.toString(); - } catch (URISyntaxException e) { - assert(false); - return url; - } - } - } catch(Exception e) { - s_logger.warn("Unexpected exception ", e); - } - - return url; - } - - public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, - ManagedObjectReference morRp, ManagedObjectReference morHost) throws Exception { - - assert(morRp != null); - - OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams(); - importSpecParams.setHostSystem(morHost); - importSpecParams.setLocale("US"); - importSpecParams.setEntityName(vmName); - importSpecParams.setDeploymentOption(""); - importSpecParams.setDiskProvisioning(diskOption); // diskOption: thin, thick, etc - importSpecParams.setPropertyMapping(null); - - String ovfDescriptor = HttpNfcLeaseMO.readOvfContent(ovfFilePath); - VmwareContext context = host.getContext(); - OvfCreateImportSpecResult ovfImportResult = context.getService().createImportSpec( - context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, - dsMo.getMor(), importSpecParams); - - if(ovfImportResult == null) { - String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath + ", vmName: " - + vmName + ", diskOption: " + diskOption; - s_logger.error(msg); - throw new Exception(msg); - } - - DatacenterMO dcMo = new DatacenterMO(context, host.getHyperHostDatacenter()); - ManagedObjectReference morLease = context.getService().importVApp(morRp, - ovfImportResult.getImportSpec(), dcMo.getVmFolder(), morHost); - if(morLease == null) { - String msg = "importVApp() failed. ovfFilePath: " + ovfFilePath + ", vmName: " - + vmName + ", diskOption: " + diskOption; - s_logger.error(msg); - throw new Exception(msg); - } - final HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(context, morLease); - HttpNfcLeaseState state = leaseMo.waitState( - new HttpNfcLeaseState[] { HttpNfcLeaseState.ready, HttpNfcLeaseState.error }); - try { - if(state == HttpNfcLeaseState.ready) { - final long totalBytes = HttpNfcLeaseMO.calcTotalBytes(ovfImportResult); - File ovfFile = new File(ovfFilePath); - - HttpNfcLeaseInfo httpNfcLeaseInfo = leaseMo.getLeaseInfo(); - HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl(); - long bytesAlreadyWritten = 0; - - final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter(); - try { - for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls) { - String deviceKey = deviceUrl.getImportKey(); - for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) { - if (deviceKey.equals(ovfFileItem.getDeviceId())) { - String absoluteFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath(); - String urlToPost = deviceUrl.getUrl(); - urlToPost = resolveHostNameInUrl(dcMo, urlToPost); - - context.uploadVmdkFile(ovfFileItem.isCreate() ? "PUT" : "POST", urlToPost, absoluteFile, - bytesAlreadyWritten, new ActionDelegate () { - public void action(Long param) { - progressReporter.reportProgress((int)(param * 100 / totalBytes)); - } - }); - - bytesAlreadyWritten += ovfFileItem.getSize(); - } - } - } - } finally { - progressReporter.close(); - } - leaseMo.updateLeaseProgress(100); - } - } finally { - leaseMo.completeLease(); - } - } -} + + VmwareHypervisorHostNetworkSummary summary = hostMo.getHyperHostNetworkSummary(managementPortGroupName); + if(summary == null) { + s_logger.warn("Unable to resolve host name in url through vSphere, url: " + url); + return url; + } + + String hostIp = summary.getHostIp(); + + try { + URI resolvedUri = new URI(uri.getScheme(), uri.getUserInfo(), hostIp, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment()); + + s_logger.info("url " + url + " is resolved to " + resolvedUri.toString() + " through vCenter"); + return resolvedUri.toString(); + } catch (URISyntaxException e) { + assert(false); + return url; + } + } + } catch(Exception e) { + s_logger.warn("Unexpected exception ", e); + } + + return url; + } + + public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, + ManagedObjectReference morRp, ManagedObjectReference morHost) throws Exception { + + assert(morRp != null); + + OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams(); + importSpecParams.setHostSystem(morHost); + importSpecParams.setLocale("US"); + importSpecParams.setEntityName(vmName); + importSpecParams.setDeploymentOption(""); + importSpecParams.setDiskProvisioning(diskOption); // diskOption: thin, thick, etc + importSpecParams.setPropertyMapping(null); + + String ovfDescriptor = HttpNfcLeaseMO.readOvfContent(ovfFilePath); + VmwareContext context = host.getContext(); + OvfCreateImportSpecResult ovfImportResult = context.getService().createImportSpec( + context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, + dsMo.getMor(), importSpecParams); + + if(ovfImportResult == null) { + String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath + ", vmName: " + + vmName + ", diskOption: " + diskOption; + s_logger.error(msg); + throw new Exception(msg); + } + + DatacenterMO dcMo = new DatacenterMO(context, host.getHyperHostDatacenter()); + ManagedObjectReference morLease = context.getService().importVApp(morRp, + ovfImportResult.getImportSpec(), dcMo.getVmFolder(), morHost); + if(morLease == null) { + String msg = "importVApp() failed. ovfFilePath: " + ovfFilePath + ", vmName: " + + vmName + ", diskOption: " + diskOption; + s_logger.error(msg); + throw new Exception(msg); + } + final HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(context, morLease); + HttpNfcLeaseState state = leaseMo.waitState( + new HttpNfcLeaseState[] { HttpNfcLeaseState.ready, HttpNfcLeaseState.error }); + try { + if(state == HttpNfcLeaseState.ready) { + final long totalBytes = HttpNfcLeaseMO.calcTotalBytes(ovfImportResult); + File ovfFile = new File(ovfFilePath); + + HttpNfcLeaseInfo httpNfcLeaseInfo = leaseMo.getLeaseInfo(); + HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl(); + long bytesAlreadyWritten = 0; + + final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter(); + try { + for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls) { + String deviceKey = deviceUrl.getImportKey(); + for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) { + if (deviceKey.equals(ovfFileItem.getDeviceId())) { + String absoluteFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath(); + String urlToPost = deviceUrl.getUrl(); + urlToPost = resolveHostNameInUrl(dcMo, urlToPost); + + context.uploadVmdkFile(ovfFileItem.isCreate() ? "PUT" : "POST", urlToPost, absoluteFile, + bytesAlreadyWritten, new ActionDelegate () { + public void action(Long param) { + progressReporter.reportProgress((int)(param * 100 / totalBytes)); + } + }); + + bytesAlreadyWritten += ovfFileItem.getSize(); + } + } + } + } finally { + progressReporter.close(); + } + leaseMo.updateLeaseProgress(100); + } + } finally { + leaseMo.completeLease(); + } + } +} diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java index 97237ba5bdd..49747d2af02 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java @@ -204,53 +204,53 @@ public class SnapshotDescriptor { info.setDisks(disks); info.setDisplayName(_properties.getProperty(String.format("snapshot%d.displayName", id))); l.add(info); - } - - current = _properties.getProperty(String.format("snapshot%d.parent", id)); - } - - return l.toArray(new SnapshotInfo[0]); - } - - public static class SnapshotInfo { - private int _id; - private String _displayName; - private int _numOfDisks; - private DiskInfo[] _disks; - - public SnapshotInfo() { - } - - public void setId(int id) { - _id = id; - } - - public int getId() { - return _id; - } - - public void setDisplayName(String name) { - _displayName = name; - } - - public String getDisplayName() { - return _displayName; - } - - public void setNumOfDisks(int numOfDisks) { - _numOfDisks = numOfDisks; - } - - public int getNumOfDisks() { - return _numOfDisks; - } - - public void setDisks(DiskInfo[] disks) { - _disks = disks; - } - - public DiskInfo[] getDisks() { - return _disks; + } + + current = _properties.getProperty(String.format("snapshot%d.parent", id)); + } + + return l.toArray(new SnapshotInfo[0]); + } + + public static class SnapshotInfo { + private int _id; + private String _displayName; + private int _numOfDisks; + private DiskInfo[] _disks; + + public SnapshotInfo() { + } + + public void setId(int id) { + _id = id; + } + + public int getId() { + return _id; + } + + public void setDisplayName(String name) { + _displayName = name; + } + + public String getDisplayName() { + return _displayName; + } + + public void setNumOfDisks(int numOfDisks) { + _numOfDisks = numOfDisks; + } + + public int getNumOfDisks() { + return _numOfDisks; + } + + public void setDisks(DiskInfo[] disks) { + _disks = disks; + } + + public DiskInfo[] getDisks() { + return _disks; } @Override @@ -273,29 +273,29 @@ public class SnapshotDescriptor { sb.append("]}"); return sb.toString(); - } - } - - public static class DiskInfo { - private String _diskFileName; - private String _deviceName; - - public DiskInfo(String diskFileName, String deviceName) { - _diskFileName = diskFileName; - _deviceName = deviceName; - } - - public String getDiskFileName() { - return _diskFileName; - } - - public String getDeviceName() { - return _deviceName; + } + } + + public static class DiskInfo { + private String _diskFileName; + private String _deviceName; + + public DiskInfo(String diskFileName, String deviceName) { + _diskFileName = diskFileName; + _deviceName = deviceName; + } + + public String getDiskFileName() { + return _diskFileName; + } + + public String getDeviceName() { + return _deviceName; } @Override public String toString() { return "DiskInfo: { device: " + _deviceName + ", file: " + _diskFileName + " }"; - } - } -} + } + } +} diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index a03fa54f771..cd54127fcc2 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -988,8 +988,8 @@ public class VirtualMachineMO extends BaseMO { if(s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); } - - // vmdkDatastorePath: [datastore name] vmdkFilePath + + // vmdkDatastorePath: [datastore name] vmdkFilePath public List> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception { if(s_logger.isTraceEnabled()) @@ -1701,315 +1701,315 @@ public class VirtualMachineMO extends BaseMO { } } } - - // return pair of VirtualDisk and disk device bus name(ide0:0, etc) - public Pair getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); - - s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath); - DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath); - String srcBaseName = dsSrcFile.getFileBaseName(); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualDisk) { - s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber()); - - VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); - if(backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { - VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; - do { - s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName()); - - DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName()); - String backingBaseName = dsBackingFile.getFileBaseName(); - if(matchExactly) { - if(backingBaseName .equalsIgnoreCase(srcBaseName)) { - String deviceNumbering = getDeviceBusName(devices, device); - - s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); - return new Pair((VirtualDisk)device, deviceNumbering); - } - } else { - if(backingBaseName.contains(srcBaseName)) { - String deviceNumbering = getDeviceBusName(devices, device); - - s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); - return new Pair((VirtualDisk)device, deviceNumbering); - } - } - - diskBackingInfo = diskBackingInfo.getParent(); - } while(diskBackingInfo != null); - } - } - } - } - - return null; + + // return pair of VirtualDisk and disk device bus name(ide0:0, etc) + public Pair getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); + + s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath); + DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath); + String srcBaseName = dsSrcFile.getFileBaseName(); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualDisk) { + s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber()); + + VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); + if(backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { + VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; + do { + s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName()); + + DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName()); + String backingBaseName = dsBackingFile.getFileBaseName(); + if(matchExactly) { + if(backingBaseName .equalsIgnoreCase(srcBaseName)) { + String deviceNumbering = getDeviceBusName(devices, device); + + s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); + return new Pair((VirtualDisk)device, deviceNumbering); + } + } else { + if(backingBaseName.contains(srcBaseName)) { + String deviceNumbering = getDeviceBusName(devices, device); + + s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); + return new Pair((VirtualDisk)device, deviceNumbering); + } + } + + diskBackingInfo = diskBackingInfo.getParent(); + } while(diskBackingInfo != null); + } + } + } + } + + return null; } - @Deprecated - public List> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception { - VirtualDeviceBackingInfo backingInfo = disk.getBacking(); - if(!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) { - throw new Exception("Unsupported VirtualDeviceBackingInfo"); - } - - List> pathList = new ArrayList>(); - VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; - - if(!followChain) { - pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); - return pathList; - } - - Pair dcPair = getOwnerDatacenter(); - VirtualMachineFileInfo vmFilesInfo = getFileInfo(); - DatastoreFile snapshotDirFile = new DatastoreFile(vmFilesInfo.getSnapshotDirectory()); - DatastoreFile vmxDirFile = new DatastoreFile(vmFilesInfo.getVmPathName()); - - do { - if(diskBackingInfo.getParent() != null) { - pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); - diskBackingInfo = diskBackingInfo.getParent(); - } else { - // try getting parent info from VMDK file itself - byte[] content = null; - try { - String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName()); - content = getContext().getResourceContent(url); - if(content == null || content.length == 0) { - break; - } - - pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); - } catch(Exception e) { - // if snapshot directory has been changed to place other than default. VMware has a bug - // that its corresponding disk backing info is not updated correctly. therefore, we will try search - // in snapshot directory one more time - DatastoreFile currentFile = new DatastoreFile(diskBackingInfo.getFileName()); - String vmdkFullDsPath = snapshotDirFile.getCompanionPath(currentFile.getFileName()); - - String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkFullDsPath); - content = getContext().getResourceContent(url); - if(content == null || content.length == 0) { - break; - } - - pathList.add(new Pair(vmdkFullDsPath, diskBackingInfo.getDatastore())); - } - - VmdkFileDescriptor descriptor = new VmdkFileDescriptor(); - descriptor.parse(content); - if(descriptor.getParentFileName() != null && !descriptor.getParentFileName().isEmpty()) { - // create a fake one - VirtualDiskFlatVer2BackingInfo parentDiskBackingInfo = new VirtualDiskFlatVer2BackingInfo(); - parentDiskBackingInfo.setDatastore(diskBackingInfo.getDatastore()); - - String parentFileName = descriptor.getParentFileName(); - if(parentFileName.startsWith("/")) { - int fileNameStartPos = parentFileName.lastIndexOf("/"); - parentFileName = parentFileName.substring(fileNameStartPos + 1); - parentDiskBackingInfo.setFileName(vmxDirFile.getCompanionPath(parentFileName)); - } else { - parentDiskBackingInfo.setFileName(snapshotDirFile.getCompanionPath(parentFileName)); - } - diskBackingInfo = parentDiskBackingInfo; - } else { - break; - } - } - } while(diskBackingInfo != null); - - return pathList; - } - - private String getDeviceBusName(VirtualDevice[] allDevices, VirtualDevice theDevice) throws Exception { - for(VirtualDevice device : allDevices) { - if(device.getKey() == theDevice.getControllerKey().intValue()) { - if(device instanceof VirtualIDEController) { - return String.format("ide%d:%d", ((VirtualIDEController)device).getBusNumber(), theDevice.getUnitNumber()); - } else if(device instanceof VirtualSCSIController) { - return String.format("scsi%d:%d", ((VirtualSCSIController)device).getBusNumber(), theDevice.getUnitNumber()); - } else { - throw new Exception("Device controller is not supported yet"); - } - } - } - throw new Exception("Unable to find device controller"); - } - - public VirtualDisk[] getAllDiskDevice() throws Exception { - List deviceList = new ArrayList(); - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualDisk) { - deviceList.add((VirtualDisk)device); - } - } - } - - return deviceList.toArray(new VirtualDisk[0]); - } - - public VirtualDisk[] getAllIndependentDiskDevice() throws Exception { - List independentDisks = new ArrayList(); - VirtualDisk[] allDisks = getAllDiskDevice(); - if(allDisks.length > 0) { - for(VirtualDisk disk : allDisks) { - String diskMode = ""; - if(disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) { - diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) { - diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { - diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) { - diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) { - diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode(); - } - - if(diskMode.indexOf("independent") != -1) { - independentDisks.add(disk); - } - } - } - - return independentDisks.toArray(new VirtualDisk[0]); - } - - public int tryGetIDEDeviceControllerKey() throws Exception { - VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualIDEController) { - return ((VirtualIDEController)device).getKey(); - } - } - } - - return -1; - } - - public int getIDEDeviceControllerKey() throws Exception { - VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualIDEController) { - return ((VirtualIDEController)device).getKey(); - } - } - } - - assert(false); - throw new Exception("IDE Controller Not Found"); - } - - public int getNextIDEDeviceNumber() throws Exception { - int controllerKey = getIDEDeviceControllerKey(); - return getNextDeviceNumber(controllerKey); - } - - public VirtualDevice getIsoDevice() throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualCdrom) { - return device; - } - } - } - return null; - } - - public int getPCIDeviceControllerKey() throws Exception { - VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualPCIController) { - return ((VirtualPCIController)device).getKey(); - } - } - } - - assert(false); - throw new Exception("PCI Controller Not Found"); - } - - public int getNextPCIDeviceNumber() throws Exception { - int controllerKey = getPCIDeviceControllerKey(); - return getNextDeviceNumber(controllerKey); - } - - public int getNextDeviceNumber(int controllerKey) throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - int deviceNumber = -1; - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) { - if(device.getUnitNumber() != null && device.getUnitNumber().intValue() > deviceNumber) { - deviceNumber = device.getUnitNumber().intValue(); - } - } - } - } - return ++deviceNumber; - } - - public VirtualDevice[] getNicDevices() throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - List nics = new ArrayList(); - if(devices != null) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualEthernetCard) { - nics.add(device); - } - } - } - - return nics.toArray(new VirtualDevice[0]); - } - - public Pair getNicDeviceIndex(String networkNamePrefix) throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - List nics = new ArrayList(); - if(devices != null) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualEthernetCard) { - nics.add(device); - } - } - } - - Collections.sort(nics, new Comparator() { - @Override - public int compare(VirtualDevice arg0, VirtualDevice arg1) { - int unitNumber0 = arg0.getUnitNumber() != null ? arg0.getUnitNumber().intValue() : -1; - int unitNumber1 = arg1.getUnitNumber() != null ? arg1.getUnitNumber().intValue() : -1; - if(unitNumber0 < unitNumber1) - return -1; - else if(unitNumber0 > unitNumber1) - return 1; - return 0; - } + @Deprecated + public List> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception { + VirtualDeviceBackingInfo backingInfo = disk.getBacking(); + if(!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) { + throw new Exception("Unsupported VirtualDeviceBackingInfo"); + } + + List> pathList = new ArrayList>(); + VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; + + if(!followChain) { + pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); + return pathList; + } + + Pair dcPair = getOwnerDatacenter(); + VirtualMachineFileInfo vmFilesInfo = getFileInfo(); + DatastoreFile snapshotDirFile = new DatastoreFile(vmFilesInfo.getSnapshotDirectory()); + DatastoreFile vmxDirFile = new DatastoreFile(vmFilesInfo.getVmPathName()); + + do { + if(diskBackingInfo.getParent() != null) { + pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); + diskBackingInfo = diskBackingInfo.getParent(); + } else { + // try getting parent info from VMDK file itself + byte[] content = null; + try { + String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName()); + content = getContext().getResourceContent(url); + if(content == null || content.length == 0) { + break; + } + + pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); + } catch(Exception e) { + // if snapshot directory has been changed to place other than default. VMware has a bug + // that its corresponding disk backing info is not updated correctly. therefore, we will try search + // in snapshot directory one more time + DatastoreFile currentFile = new DatastoreFile(diskBackingInfo.getFileName()); + String vmdkFullDsPath = snapshotDirFile.getCompanionPath(currentFile.getFileName()); + + String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkFullDsPath); + content = getContext().getResourceContent(url); + if(content == null || content.length == 0) { + break; + } + + pathList.add(new Pair(vmdkFullDsPath, diskBackingInfo.getDatastore())); + } + + VmdkFileDescriptor descriptor = new VmdkFileDescriptor(); + descriptor.parse(content); + if(descriptor.getParentFileName() != null && !descriptor.getParentFileName().isEmpty()) { + // create a fake one + VirtualDiskFlatVer2BackingInfo parentDiskBackingInfo = new VirtualDiskFlatVer2BackingInfo(); + parentDiskBackingInfo.setDatastore(diskBackingInfo.getDatastore()); + + String parentFileName = descriptor.getParentFileName(); + if(parentFileName.startsWith("/")) { + int fileNameStartPos = parentFileName.lastIndexOf("/"); + parentFileName = parentFileName.substring(fileNameStartPos + 1); + parentDiskBackingInfo.setFileName(vmxDirFile.getCompanionPath(parentFileName)); + } else { + parentDiskBackingInfo.setFileName(snapshotDirFile.getCompanionPath(parentFileName)); + } + diskBackingInfo = parentDiskBackingInfo; + } else { + break; + } + } + } while(diskBackingInfo != null); + + return pathList; + } + + private String getDeviceBusName(VirtualDevice[] allDevices, VirtualDevice theDevice) throws Exception { + for(VirtualDevice device : allDevices) { + if(device.getKey() == theDevice.getControllerKey().intValue()) { + if(device instanceof VirtualIDEController) { + return String.format("ide%d:%d", ((VirtualIDEController)device).getBusNumber(), theDevice.getUnitNumber()); + } else if(device instanceof VirtualSCSIController) { + return String.format("scsi%d:%d", ((VirtualSCSIController)device).getBusNumber(), theDevice.getUnitNumber()); + } else { + throw new Exception("Device controller is not supported yet"); + } + } + } + throw new Exception("Unable to find device controller"); + } + + public VirtualDisk[] getAllDiskDevice() throws Exception { + List deviceList = new ArrayList(); + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualDisk) { + deviceList.add((VirtualDisk)device); + } + } + } + + return deviceList.toArray(new VirtualDisk[0]); + } + + public VirtualDisk[] getAllIndependentDiskDevice() throws Exception { + List independentDisks = new ArrayList(); + VirtualDisk[] allDisks = getAllDiskDevice(); + if(allDisks.length > 0) { + for(VirtualDisk disk : allDisks) { + String diskMode = ""; + if(disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) { + diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) { + diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { + diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) { + diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) { + diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode(); + } + + if(diskMode.indexOf("independent") != -1) { + independentDisks.add(disk); + } + } + } + + return independentDisks.toArray(new VirtualDisk[0]); + } + + public int tryGetIDEDeviceControllerKey() throws Exception { + VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualIDEController) { + return ((VirtualIDEController)device).getKey(); + } + } + } + + return -1; + } + + public int getIDEDeviceControllerKey() throws Exception { + VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualIDEController) { + return ((VirtualIDEController)device).getKey(); + } + } + } + + assert(false); + throw new Exception("IDE Controller Not Found"); + } + + public int getNextIDEDeviceNumber() throws Exception { + int controllerKey = getIDEDeviceControllerKey(); + return getNextDeviceNumber(controllerKey); + } + + public VirtualDevice getIsoDevice() throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualCdrom) { + return device; + } + } + } + return null; + } + + public int getPCIDeviceControllerKey() throws Exception { + VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualPCIController) { + return ((VirtualPCIController)device).getKey(); + } + } + } + + assert(false); + throw new Exception("PCI Controller Not Found"); + } + + public int getNextPCIDeviceNumber() throws Exception { + int controllerKey = getPCIDeviceControllerKey(); + return getNextDeviceNumber(controllerKey); + } + + public int getNextDeviceNumber(int controllerKey) throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + int deviceNumber = -1; + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) { + if(device.getUnitNumber() != null && device.getUnitNumber().intValue() > deviceNumber) { + deviceNumber = device.getUnitNumber().intValue(); + } + } + } + } + return ++deviceNumber; + } + + public VirtualDevice[] getNicDevices() throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + List nics = new ArrayList(); + if(devices != null) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualEthernetCard) { + nics.add(device); + } + } + } + + return nics.toArray(new VirtualDevice[0]); + } + + public Pair getNicDeviceIndex(String networkNamePrefix) throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + List nics = new ArrayList(); + if(devices != null) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualEthernetCard) { + nics.add(device); + } + } + } + + Collections.sort(nics, new Comparator() { + @Override + public int compare(VirtualDevice arg0, VirtualDevice arg1) { + int unitNumber0 = arg0.getUnitNumber() != null ? arg0.getUnitNumber().intValue() : -1; + int unitNumber1 = arg1.getUnitNumber() != null ? arg1.getUnitNumber().intValue() : -1; + if(unitNumber0 < unitNumber1) + return -1; + else if(unitNumber0 > unitNumber1) + return 1; + return 0; + } }); - + int index = 0; String attachedNetworkSummary; String dvPortGroupName; @@ -2039,38 +2039,38 @@ public class VirtualMachineMO extends BaseMO { dvPortGroupMor.setType("DistributedVirtualPortgroup"); return (String) _context.getServiceUtil().getDynamicProperty(dvPortGroupMor, "name"); } - - public VirtualDevice[] getMatchedDevices(Class[] deviceClasses) throws Exception { - assert(deviceClasses != null); - - List returnList = new ArrayList(); - - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null) { - for(VirtualDevice device : devices) { - for(Class clz : deviceClasses) { - if(clz.isInstance(device)) { - returnList.add(device); - break; - } - } - } - } - - return returnList.toArray(new VirtualDevice[0]); - } - - public void mountToolsInstaller() throws Exception { - _context.getService().mountToolsInstaller(_mor); - } - - public void unmountToolsInstaller() throws Exception { - _context.getService().unmountToolsInstaller(_mor); - } - - public void redoRegistration(ManagedObjectReference morHost) throws Exception { + + public VirtualDevice[] getMatchedDevices(Class[] deviceClasses) throws Exception { + assert(deviceClasses != null); + + List returnList = new ArrayList(); + + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null) { + for(VirtualDevice device : devices) { + for(Class clz : deviceClasses) { + if(clz.isInstance(device)) { + returnList.add(device); + break; + } + } + } + } + + return returnList.toArray(new VirtualDevice[0]); + } + + public void mountToolsInstaller() throws Exception { + _context.getService().mountToolsInstaller(_mor); + } + + public void unmountToolsInstaller() throws Exception { + _context.getService().unmountToolsInstaller(_mor); + } + + public void redoRegistration(ManagedObjectReference morHost) throws Exception { String vmName = getVmName(); VirtualMachineFileInfo vmFileInfo = getFileInfo(); boolean isTemplate = isTemplate(); diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java index 2290f7c548b..d6226ffce58 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java @@ -14,11 +14,11 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. - -package com.cloud.hypervisor.vmware.mo; - -public enum VirtualSwitchType { - StandardVirtualSwitch, - VMwareDistributedVirtualSwitch, - NexusDistributedVirtualSwitch, -} + +package com.cloud.hypervisor.vmware.mo; + +public enum VirtualSwitchType { + StandardVirtualSwitch, + VMwareDistributedVirtualSwitch, + NexusDistributedVirtualSwitch, +} diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java index 155a3a75ee7..6dd6475ae11 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java @@ -27,38 +27,38 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSession; - -import org.apache.log4j.Logger; - -import com.cloud.hypervisor.vmware.mo.DatacenterMO; -import com.cloud.hypervisor.vmware.mo.DatastoreFile; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + +import org.apache.log4j.Logger; + +import com.cloud.hypervisor.vmware.mo.DatacenterMO; +import com.cloud.hypervisor.vmware.mo.DatastoreFile; import com.cloud.utils.ActionDelegate; -import com.vmware.apputils.version.ExtendedAppUtil; -import com.vmware.apputils.vim25.ServiceConnection; -import com.vmware.apputils.vim25.ServiceUtil; -import com.vmware.vim25.ManagedObjectReference; -import com.vmware.vim25.ObjectContent; -import com.vmware.vim25.ObjectSpec; -import com.vmware.vim25.PropertyFilterSpec; -import com.vmware.vim25.PropertySpec; -import com.vmware.vim25.SelectionSpec; -import com.vmware.vim25.ServiceContent; -import com.vmware.vim25.TaskInfo; -import com.vmware.vim25.TraversalSpec; -import com.vmware.vim25.VimPortType; - -public class VmwareContext { +import com.vmware.apputils.version.ExtendedAppUtil; +import com.vmware.apputils.vim25.ServiceConnection; +import com.vmware.apputils.vim25.ServiceUtil; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.ObjectContent; +import com.vmware.vim25.ObjectSpec; +import com.vmware.vim25.PropertyFilterSpec; +import com.vmware.vim25.PropertySpec; +import com.vmware.vim25.SelectionSpec; +import com.vmware.vim25.ServiceContent; +import com.vmware.vim25.TaskInfo; +import com.vmware.vim25.TraversalSpec; +import com.vmware.vim25.VimPortType; + +public class VmwareContext { private static final Logger s_logger = Logger.getLogger(VmwareContext.class); private static int MAX_CONNECT_RETRY = 5; @@ -69,229 +69,229 @@ public class VmwareContext { private Map _stockMap = new HashMap(); private int _CHUNKSIZE = 1*1024*1024; // 1M - - static { - try { - javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; - javax.net.ssl.TrustManager tm = new TrustAllManager(); - trustAllCerts[0] = tm; - javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL"); - sc.init(null, trustAllCerts, null); - javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } catch (Exception e) { - s_logger.error("Unexpected exception ", e); - } - } - - public VmwareContext(ExtendedAppUtil appUtil, String address) { - assert(appUtil != null) : "Invalid parameter in constructing VmwareContext object"; - - _appUtil = appUtil; - _serverAddress = address; - } - - public void registerStockObject(String name, Object obj) { - synchronized(_stockMap) { - _stockMap.put(name, obj); - } - } - - public void uregisterStockObject(String name) { - synchronized(_stockMap) { - _stockMap.remove(name); - } - } - - @SuppressWarnings("unchecked") - public T getStockObject(String name) { - synchronized(_stockMap) { - return (T)_stockMap.get(name); - } - } - - public String getServerAddress() { - return _serverAddress; - } - - public ServiceConnection getServiceConnection() { - return _appUtil.getServiceConnection3(); - } - - public VimPortType getService() { - return getServiceConnection().getService(); - } - - public ServiceContent getServiceContent() { - return getServiceConnection().getServiceContent(); - } - - public ServiceUtil getServiceUtil() { - return _appUtil.getServiceUtil3(); - } - - public ManagedObjectReference getRootFolder() { - return getServiceContent().getRootFolder(); - } - - public ManagedObjectReference getHostMorByPath(String inventoryPath) throws Exception { - assert(inventoryPath != null); - - String[] tokens; - if(inventoryPath.startsWith("/")) - tokens = inventoryPath.substring(1).split("/"); - else - tokens = inventoryPath.split("/"); - - ManagedObjectReference mor = getRootFolder(); - for(int i=0; i < tokens.length;i++) { - String token = tokens[i]; - ObjectContent[] ocs; - if(mor.getType().equalsIgnoreCase("Datacenter")) { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("ManagedEntity"); - pSpec.setPathSet(new String[] { "name" }); - - TraversalSpec dcHostFolderTraversal = new TraversalSpec(); - dcHostFolderTraversal.setType("Datacenter"); - dcHostFolderTraversal.setPath("hostFolder"); - dcHostFolderTraversal.setName("dcHostFolderTraversal"); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { dcHostFolderTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - ocs = getService().retrieveProperties( - getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - } else if(mor.getType().equalsIgnoreCase("Folder")) { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("ManagedEntity"); - pSpec.setPathSet(new String[] { "name" }); - - TraversalSpec folderChildrenTraversal = new TraversalSpec(); - folderChildrenTraversal.setType("Folder"); - folderChildrenTraversal.setPath("childEntity"); - folderChildrenTraversal.setName("folderChildrenTraversal"); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { folderChildrenTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ocs = getService().retrieveProperties( - getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - } else if(mor.getType().equalsIgnoreCase("ClusterComputeResource")) { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("ManagedEntity"); - pSpec.setPathSet(new String[] { "name" }); - - TraversalSpec clusterHostTraversal = new TraversalSpec(); - clusterHostTraversal.setType("ClusterComputeResource"); - clusterHostTraversal.setPath("host"); - clusterHostTraversal.setName("folderChildrenTraversal"); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { clusterHostTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ocs = getService().retrieveProperties( - getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - } else { - s_logger.error("Invalid inventory path, path element can only be datacenter and folder"); - return null; - } - - if(ocs != null && ocs.length > 0) { - boolean found = false; - for(ObjectContent oc : ocs) { - String name = oc.getPropSet()[0].getVal().toString(); - if(name.equalsIgnoreCase(token) || name.equalsIgnoreCase("host")) { - mor = oc.getObj(); - found = true; - if (name.equalsIgnoreCase("host")) - i--; - break; - } - } - if(!found) { - s_logger.error("Path element points to an un-existing inventory entity"); - return null; - } - } else { - s_logger.error("Path element points to an un-existing inventory entity"); - return null; - } - } - return mor; - } - - // path in format of / - public ManagedObjectReference getDatastoreMorByPath(String inventoryPath) throws Exception { - assert(inventoryPath != null); - - String[] tokens; - if(inventoryPath.startsWith("/")) - tokens = inventoryPath.substring(1).split("/"); - else - tokens = inventoryPath.split("/"); - - if(tokens == null || tokens.length != 2) { - s_logger.error("Invalid datastore inventory path. path: " + inventoryPath); - return null; - } - - DatacenterMO dcMo = new DatacenterMO(this, tokens[0]); - if(dcMo.getMor() == null) { - s_logger.error("Unable to locate the datacenter specified in path: " + inventoryPath); - return null; - } - - return dcMo.findDatastore(tokens[1]); - } - - public void waitForTaskProgressDone(ManagedObjectReference morTask) throws Exception { - while(true) { - TaskInfo tinfo = (TaskInfo)getServiceUtil().getDynamicProperty(morTask, "info"); - Integer progress = tinfo.getProgress(); - if(progress == null) - break; - - if(progress.intValue() >= 100) - break; - - Thread.sleep(1000); - } - } - - public void getFile(String urlString, String localFileFullName) throws Exception { - HttpURLConnection conn = getHTTPConnection(urlString); - - InputStream in = conn.getInputStream(); - OutputStream out = new FileOutputStream(new File(localFileFullName)); - byte[] buf = new byte[_CHUNKSIZE]; - int len = 0; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - in.close(); - out.close(); - } + + static { + try { + javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; + javax.net.ssl.TrustManager tm = new TrustAllManager(); + trustAllCerts[0] = tm; + javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, null); + javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } catch (Exception e) { + s_logger.error("Unexpected exception ", e); + } + } + + public VmwareContext(ExtendedAppUtil appUtil, String address) { + assert(appUtil != null) : "Invalid parameter in constructing VmwareContext object"; + + _appUtil = appUtil; + _serverAddress = address; + } + + public void registerStockObject(String name, Object obj) { + synchronized(_stockMap) { + _stockMap.put(name, obj); + } + } + + public void uregisterStockObject(String name) { + synchronized(_stockMap) { + _stockMap.remove(name); + } + } + + @SuppressWarnings("unchecked") + public T getStockObject(String name) { + synchronized(_stockMap) { + return (T)_stockMap.get(name); + } + } + + public String getServerAddress() { + return _serverAddress; + } + + public ServiceConnection getServiceConnection() { + return _appUtil.getServiceConnection3(); + } + + public VimPortType getService() { + return getServiceConnection().getService(); + } + + public ServiceContent getServiceContent() { + return getServiceConnection().getServiceContent(); + } + + public ServiceUtil getServiceUtil() { + return _appUtil.getServiceUtil3(); + } + + public ManagedObjectReference getRootFolder() { + return getServiceContent().getRootFolder(); + } + + public ManagedObjectReference getHostMorByPath(String inventoryPath) throws Exception { + assert(inventoryPath != null); + + String[] tokens; + if(inventoryPath.startsWith("/")) + tokens = inventoryPath.substring(1).split("/"); + else + tokens = inventoryPath.split("/"); + + ManagedObjectReference mor = getRootFolder(); + for(int i=0; i < tokens.length;i++) { + String token = tokens[i]; + ObjectContent[] ocs; + if(mor.getType().equalsIgnoreCase("Datacenter")) { + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("ManagedEntity"); + pSpec.setPathSet(new String[] { "name" }); + + TraversalSpec dcHostFolderTraversal = new TraversalSpec(); + dcHostFolderTraversal.setType("Datacenter"); + dcHostFolderTraversal.setPath("hostFolder"); + dcHostFolderTraversal.setName("dcHostFolderTraversal"); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(mor); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { dcHostFolderTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + ocs = getService().retrieveProperties( + getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + + } else if(mor.getType().equalsIgnoreCase("Folder")) { + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("ManagedEntity"); + pSpec.setPathSet(new String[] { "name" }); + + TraversalSpec folderChildrenTraversal = new TraversalSpec(); + folderChildrenTraversal.setType("Folder"); + folderChildrenTraversal.setPath("childEntity"); + folderChildrenTraversal.setName("folderChildrenTraversal"); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(mor); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { folderChildrenTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + + ocs = getService().retrieveProperties( + getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + } else if(mor.getType().equalsIgnoreCase("ClusterComputeResource")) { + PropertySpec pSpec = new PropertySpec(); + pSpec.setType("ManagedEntity"); + pSpec.setPathSet(new String[] { "name" }); + + TraversalSpec clusterHostTraversal = new TraversalSpec(); + clusterHostTraversal.setType("ClusterComputeResource"); + clusterHostTraversal.setPath("host"); + clusterHostTraversal.setName("folderChildrenTraversal"); + + ObjectSpec oSpec = new ObjectSpec(); + oSpec.setObj(mor); + oSpec.setSkip(Boolean.TRUE); + oSpec.setSelectSet(new SelectionSpec[] { clusterHostTraversal }); + + PropertyFilterSpec pfSpec = new PropertyFilterSpec(); + pfSpec.setPropSet(new PropertySpec[] { pSpec }); + pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); + + ocs = getService().retrieveProperties( + getServiceContent().getPropertyCollector(), + new PropertyFilterSpec[] { pfSpec }); + } else { + s_logger.error("Invalid inventory path, path element can only be datacenter and folder"); + return null; + } + + if(ocs != null && ocs.length > 0) { + boolean found = false; + for(ObjectContent oc : ocs) { + String name = oc.getPropSet()[0].getVal().toString(); + if(name.equalsIgnoreCase(token) || name.equalsIgnoreCase("host")) { + mor = oc.getObj(); + found = true; + if (name.equalsIgnoreCase("host")) + i--; + break; + } + } + if(!found) { + s_logger.error("Path element points to an un-existing inventory entity"); + return null; + } + } else { + s_logger.error("Path element points to an un-existing inventory entity"); + return null; + } + } + return mor; + } + + // path in format of / + public ManagedObjectReference getDatastoreMorByPath(String inventoryPath) throws Exception { + assert(inventoryPath != null); + + String[] tokens; + if(inventoryPath.startsWith("/")) + tokens = inventoryPath.substring(1).split("/"); + else + tokens = inventoryPath.split("/"); + + if(tokens == null || tokens.length != 2) { + s_logger.error("Invalid datastore inventory path. path: " + inventoryPath); + return null; + } + + DatacenterMO dcMo = new DatacenterMO(this, tokens[0]); + if(dcMo.getMor() == null) { + s_logger.error("Unable to locate the datacenter specified in path: " + inventoryPath); + return null; + } + + return dcMo.findDatastore(tokens[1]); + } + + public void waitForTaskProgressDone(ManagedObjectReference morTask) throws Exception { + while(true) { + TaskInfo tinfo = (TaskInfo)getServiceUtil().getDynamicProperty(morTask, "info"); + Integer progress = tinfo.getProgress(); + if(progress == null) + break; + + if(progress.intValue() >= 100) + break; + + Thread.sleep(1000); + } + } + + public void getFile(String urlString, String localFileFullName) throws Exception { + HttpURLConnection conn = getHTTPConnection(urlString); + + InputStream in = conn.getInputStream(); + OutputStream out = new FileOutputStream(new File(localFileFullName)); + byte[] buf = new byte[_CHUNKSIZE]; + int len = 0; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + } public void uploadFile(String urlString, String localFileFullName) throws Exception { uploadFile(urlString, new File(localFileFullName)); diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java index 746b7143e44..47ff8e20004 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package com.cloud.hypervisor.vmware.util; +package com.cloud.hypervisor.vmware.util; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; @@ -108,9 +108,9 @@ public class VmwareHelper { nic.setAddressType("Manual"); nic.setConnectable(connectInfo); nic.setMacAddress(macAddress); - nic.setUnitNumber(deviceNumber); - nic.setKey(-contextNumber); - return nic; + nic.setUnitNumber(deviceNumber); + nic.setKey(-contextNumber); + return nic; } public static VirtualDevice prepareDvNicDevice(VirtualMachineMO vmMo, ManagedObjectReference morNetwork, VirtualEthernetCardType deviceType, @@ -160,93 +160,93 @@ public class VmwareHelper { nic.setKey(-contextNumber); return nic; } - - // vmdkDatastorePath: [datastore name] vmdkFilePath - public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, - int sizeInMb, ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception { - - VirtualDisk disk = new VirtualDisk(); - - VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); - backingInfo.setDiskMode(VirtualDiskMode.persistent.toString()); - backingInfo.setThinProvisioned(true); - backingInfo.setEagerlyScrub(false); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - disk.setBacking(backingInfo); + + // vmdkDatastorePath: [datastore name] vmdkFilePath + public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, + int sizeInMb, ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception { + + VirtualDisk disk = new VirtualDisk(); + + VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); + backingInfo.setDiskMode(VirtualDiskMode.persistent.toString()); + backingInfo.setThinProvisioned(true); + backingInfo.setEagerlyScrub(false); + backingInfo.setDatastore(morDs); + backingInfo.setFileName(vmdkDatastorePath); + disk.setBacking(backingInfo); if(controllerKey < 0) controllerKey = vmMo.getIDEDeviceControllerKey(); if(deviceNumber < 0) deviceNumber = vmMo.getNextDeviceNumber(controllerKey); disk.setControllerKey(controllerKey); - - disk.setKey(-contextNumber); - disk.setUnitNumber(deviceNumber); - disk.setCapacityInKB(sizeInMb*1024); - - VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); - connectInfo.setConnected(true); - connectInfo.setStartConnected(true); - disk.setConnectable(connectInfo); - - return disk; + + disk.setKey(-contextNumber); + disk.setUnitNumber(deviceNumber); + disk.setCapacityInKB(sizeInMb*1024); + + VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); + connectInfo.setConnected(true); + connectInfo.setStartConnected(true); + disk.setConnectable(connectInfo); + + return disk; } - // vmdkDatastorePath: [datastore name] vmdkFilePath, create delta disk based on disk from template - public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, - int sizeInMb, ManagedObjectReference morDs, VirtualDisk templateDisk, int deviceNumber, int contextNumber) throws Exception { - - assert(templateDisk != null); - VirtualDeviceBackingInfo parentBacking = templateDisk.getBacking(); - assert(parentBacking != null); - - // TODO Not sure if we need to check if the disk in template and the new disk needs to share the - // same datastore - VirtualDisk disk = new VirtualDisk(); - if(parentBacking instanceof VirtualDiskFlatVer1BackingInfo) { - VirtualDiskFlatVer1BackingInfo backingInfo = new VirtualDiskFlatVer1BackingInfo(); - backingInfo.setDiskMode(((VirtualDiskFlatVer1BackingInfo)parentBacking).getDiskMode()); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - backingInfo.setParent((VirtualDiskFlatVer1BackingInfo)parentBacking); - disk.setBacking(backingInfo); - } else if(parentBacking instanceof VirtualDiskFlatVer2BackingInfo) { - VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); - backingInfo.setDiskMode(((VirtualDiskFlatVer2BackingInfo)parentBacking).getDiskMode()); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - backingInfo.setParent((VirtualDiskFlatVer2BackingInfo)parentBacking); - disk.setBacking(backingInfo); - } else if(parentBacking instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { - VirtualDiskRawDiskMappingVer1BackingInfo backingInfo = new VirtualDiskRawDiskMappingVer1BackingInfo(); - backingInfo.setDiskMode(((VirtualDiskRawDiskMappingVer1BackingInfo)parentBacking).getDiskMode()); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - backingInfo.setParent((VirtualDiskRawDiskMappingVer1BackingInfo)parentBacking); - disk.setBacking(backingInfo); - } else if(parentBacking instanceof VirtualDiskSparseVer1BackingInfo) { - VirtualDiskSparseVer1BackingInfo backingInfo = new VirtualDiskSparseVer1BackingInfo(); - backingInfo.setDiskMode(((VirtualDiskSparseVer1BackingInfo)parentBacking).getDiskMode()); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - backingInfo.setParent((VirtualDiskSparseVer1BackingInfo)parentBacking); - disk.setBacking(backingInfo); - } else if(parentBacking instanceof VirtualDiskSparseVer2BackingInfo) { - VirtualDiskSparseVer2BackingInfo backingInfo = new VirtualDiskSparseVer2BackingInfo(); - backingInfo.setDiskMode(((VirtualDiskSparseVer2BackingInfo)parentBacking).getDiskMode()); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - backingInfo.setParent((VirtualDiskSparseVer2BackingInfo)parentBacking); - disk.setBacking(backingInfo); - } else { - throw new Exception("Unsupported disk backing: " + parentBacking.getClass().getCanonicalName()); - } - - if(controllerKey < 0) - controllerKey = vmMo.getIDEDeviceControllerKey(); - disk.setControllerKey(controllerKey); - if(deviceNumber < 0) + // vmdkDatastorePath: [datastore name] vmdkFilePath, create delta disk based on disk from template + public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, + int sizeInMb, ManagedObjectReference morDs, VirtualDisk templateDisk, int deviceNumber, int contextNumber) throws Exception { + + assert(templateDisk != null); + VirtualDeviceBackingInfo parentBacking = templateDisk.getBacking(); + assert(parentBacking != null); + + // TODO Not sure if we need to check if the disk in template and the new disk needs to share the + // same datastore + VirtualDisk disk = new VirtualDisk(); + if(parentBacking instanceof VirtualDiskFlatVer1BackingInfo) { + VirtualDiskFlatVer1BackingInfo backingInfo = new VirtualDiskFlatVer1BackingInfo(); + backingInfo.setDiskMode(((VirtualDiskFlatVer1BackingInfo)parentBacking).getDiskMode()); + backingInfo.setDatastore(morDs); + backingInfo.setFileName(vmdkDatastorePath); + backingInfo.setParent((VirtualDiskFlatVer1BackingInfo)parentBacking); + disk.setBacking(backingInfo); + } else if(parentBacking instanceof VirtualDiskFlatVer2BackingInfo) { + VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); + backingInfo.setDiskMode(((VirtualDiskFlatVer2BackingInfo)parentBacking).getDiskMode()); + backingInfo.setDatastore(morDs); + backingInfo.setFileName(vmdkDatastorePath); + backingInfo.setParent((VirtualDiskFlatVer2BackingInfo)parentBacking); + disk.setBacking(backingInfo); + } else if(parentBacking instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { + VirtualDiskRawDiskMappingVer1BackingInfo backingInfo = new VirtualDiskRawDiskMappingVer1BackingInfo(); + backingInfo.setDiskMode(((VirtualDiskRawDiskMappingVer1BackingInfo)parentBacking).getDiskMode()); + backingInfo.setDatastore(morDs); + backingInfo.setFileName(vmdkDatastorePath); + backingInfo.setParent((VirtualDiskRawDiskMappingVer1BackingInfo)parentBacking); + disk.setBacking(backingInfo); + } else if(parentBacking instanceof VirtualDiskSparseVer1BackingInfo) { + VirtualDiskSparseVer1BackingInfo backingInfo = new VirtualDiskSparseVer1BackingInfo(); + backingInfo.setDiskMode(((VirtualDiskSparseVer1BackingInfo)parentBacking).getDiskMode()); + backingInfo.setDatastore(morDs); + backingInfo.setFileName(vmdkDatastorePath); + backingInfo.setParent((VirtualDiskSparseVer1BackingInfo)parentBacking); + disk.setBacking(backingInfo); + } else if(parentBacking instanceof VirtualDiskSparseVer2BackingInfo) { + VirtualDiskSparseVer2BackingInfo backingInfo = new VirtualDiskSparseVer2BackingInfo(); + backingInfo.setDiskMode(((VirtualDiskSparseVer2BackingInfo)parentBacking).getDiskMode()); + backingInfo.setDatastore(morDs); + backingInfo.setFileName(vmdkDatastorePath); + backingInfo.setParent((VirtualDiskSparseVer2BackingInfo)parentBacking); + disk.setBacking(backingInfo); + } else { + throw new Exception("Unsupported disk backing: " + parentBacking.getClass().getCanonicalName()); + } + + if(controllerKey < 0) + controllerKey = vmMo.getIDEDeviceControllerKey(); + disk.setControllerKey(controllerKey); + if(deviceNumber < 0) deviceNumber = vmMo.getNextDeviceNumber(controllerKey); disk.setKey(-contextNumber); @@ -285,19 +285,19 @@ public class VmwareHelper { if(controllerKey < 0) controllerKey = vmMo.getIDEDeviceControllerKey(); - if(deviceNumber < 0) - deviceNumber = vmMo.getNextDeviceNumber(controllerKey); - - disk.setControllerKey(controllerKey); - disk.setKey(-contextNumber); - disk.setUnitNumber(deviceNumber); - - VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); - connectInfo.setConnected(true); - connectInfo.setStartConnected(true); - disk.setConnectable(connectInfo); - - return disk; + if(deviceNumber < 0) + deviceNumber = vmMo.getNextDeviceNumber(controllerKey); + + disk.setControllerKey(controllerKey); + disk.setKey(-contextNumber); + disk.setUnitNumber(deviceNumber); + + VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); + connectInfo.setConnected(true); + connectInfo.setStartConnected(true); + disk.setConnectable(connectInfo); + + return disk; } public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, @@ -339,23 +339,23 @@ public class VmwareHelper { return disk; } - - private static void setParentBackingInfo(VirtualDiskFlatVer2BackingInfo backingInfo, - ManagedObjectReference morDs, String[] parentDatastorePathList) { - - VirtualDiskFlatVer2BackingInfo parentBacking = new VirtualDiskFlatVer2BackingInfo(); - parentBacking.setDatastore(morDs); - parentBacking.setDiskMode(VirtualDiskMode.persistent.toString()); - - if(parentDatastorePathList.length > 1) { - String[] nextDatastorePathList = new String[parentDatastorePathList.length -1]; - for(int i = 0; i < parentDatastorePathList.length -1; i++) - nextDatastorePathList[i] = parentDatastorePathList[i + 1]; - setParentBackingInfo(parentBacking, morDs, nextDatastorePathList); - } - parentBacking.setFileName(parentDatastorePathList[0]); - - backingInfo.setParent(parentBacking); + + private static void setParentBackingInfo(VirtualDiskFlatVer2BackingInfo backingInfo, + ManagedObjectReference morDs, String[] parentDatastorePathList) { + + VirtualDiskFlatVer2BackingInfo parentBacking = new VirtualDiskFlatVer2BackingInfo(); + parentBacking.setDatastore(morDs); + parentBacking.setDiskMode(VirtualDiskMode.persistent.toString()); + + if(parentDatastorePathList.length > 1) { + String[] nextDatastorePathList = new String[parentDatastorePathList.length -1]; + for(int i = 0; i < parentDatastorePathList.length -1; i++) + nextDatastorePathList[i] = parentDatastorePathList[i + 1]; + setParentBackingInfo(parentBacking, morDs, nextDatastorePathList); + } + parentBacking.setFileName(parentDatastorePathList[0]); + + backingInfo.setParent(parentBacking); } private static void setParentBackingInfo(VirtualDiskFlatVer2BackingInfo backingInfo, @@ -375,14 +375,14 @@ public class VmwareHelper { backingInfo.setParent(parentBacking); } - - public static Pair prepareIsoDevice(VirtualMachineMO vmMo, String isoDatastorePath, ManagedObjectReference morDs, - boolean connect, boolean connectAtBoot, int deviceNumber, int contextNumber) throws Exception { - - boolean newCdRom = false; - VirtualCdrom cdRom = (VirtualCdrom )vmMo.getIsoDevice(); - if(cdRom == null) { - newCdRom = true; + + public static Pair prepareIsoDevice(VirtualMachineMO vmMo, String isoDatastorePath, ManagedObjectReference morDs, + boolean connect, boolean connectAtBoot, int deviceNumber, int contextNumber) throws Exception { + + boolean newCdRom = false; + VirtualCdrom cdRom = (VirtualCdrom )vmMo.getIsoDevice(); + if(cdRom == null) { + newCdRom = true; cdRom = new VirtualCdrom(); assert(vmMo.getIDEDeviceControllerKey() >= 0);