From 3ae274a47c45f717c9801c494693e93a84876baf Mon Sep 17 00:00:00 2001 From: David Nalley Date: Fri, 29 Jun 2012 11:16:18 -0400 Subject: [PATCH] adding runbook and publican-cloudstack to docs --- docs/publican-cloudstack/LICENSE | 202 ++++++ docs/publican-cloudstack/NOTICE | 5 + docs/publican-cloudstack/README | 8 + docs/publican-cloudstack/en-US/Feedback.xml | 27 + .../en-US/Legal_Notice.xml | 39 + .../en-US/css/overrides.css | 57 ++ .../en-US/images/.directory | 4 + docs/publican-cloudstack/en-US/images/1.png | Bin 0 -> 1365 bytes docs/publican-cloudstack/en-US/images/1.svg | 28 + docs/publican-cloudstack/en-US/images/10.png | Bin 0 -> 1705 bytes docs/publican-cloudstack/en-US/images/10.svg | 28 + docs/publican-cloudstack/en-US/images/11.png | Bin 0 -> 1379 bytes docs/publican-cloudstack/en-US/images/11.svg | 28 + docs/publican-cloudstack/en-US/images/12.png | Bin 0 -> 1721 bytes docs/publican-cloudstack/en-US/images/12.svg | 28 + docs/publican-cloudstack/en-US/images/13.png | Bin 0 -> 1810 bytes docs/publican-cloudstack/en-US/images/13.svg | 28 + docs/publican-cloudstack/en-US/images/14.png | Bin 0 -> 1597 bytes docs/publican-cloudstack/en-US/images/14.svg | 28 + docs/publican-cloudstack/en-US/images/15.png | Bin 0 -> 1689 bytes docs/publican-cloudstack/en-US/images/15.svg | 28 + docs/publican-cloudstack/en-US/images/16.png | Bin 0 -> 1817 bytes docs/publican-cloudstack/en-US/images/16.svg | 28 + docs/publican-cloudstack/en-US/images/17.png | Bin 0 -> 1688 bytes docs/publican-cloudstack/en-US/images/17.svg | 28 + docs/publican-cloudstack/en-US/images/18.png | Bin 0 -> 1832 bytes docs/publican-cloudstack/en-US/images/18.svg | 28 + docs/publican-cloudstack/en-US/images/19.png | Bin 0 -> 1823 bytes docs/publican-cloudstack/en-US/images/19.svg | 28 + docs/publican-cloudstack/en-US/images/2.png | Bin 0 -> 1608 bytes docs/publican-cloudstack/en-US/images/2.svg | 28 + docs/publican-cloudstack/en-US/images/20.png | Bin 0 -> 1937 bytes docs/publican-cloudstack/en-US/images/20.svg | 28 + docs/publican-cloudstack/en-US/images/21.png | Bin 0 -> 1723 bytes docs/publican-cloudstack/en-US/images/21.svg | 28 + docs/publican-cloudstack/en-US/images/22.png | Bin 0 -> 1620 bytes docs/publican-cloudstack/en-US/images/22.svg | 28 + docs/publican-cloudstack/en-US/images/23.png | Bin 0 -> 2007 bytes docs/publican-cloudstack/en-US/images/23.svg | 28 + docs/publican-cloudstack/en-US/images/24.png | Bin 0 -> 1774 bytes docs/publican-cloudstack/en-US/images/24.svg | 28 + docs/publican-cloudstack/en-US/images/25.png | Bin 0 -> 1937 bytes docs/publican-cloudstack/en-US/images/25.svg | 28 + docs/publican-cloudstack/en-US/images/26.png | Bin 0 -> 1975 bytes docs/publican-cloudstack/en-US/images/26.svg | 28 + docs/publican-cloudstack/en-US/images/27.png | Bin 0 -> 1873 bytes docs/publican-cloudstack/en-US/images/27.svg | 28 + docs/publican-cloudstack/en-US/images/28.png | Bin 0 -> 2055 bytes docs/publican-cloudstack/en-US/images/28.svg | 28 + docs/publican-cloudstack/en-US/images/29.png | Bin 0 -> 2033 bytes docs/publican-cloudstack/en-US/images/29.svg | 28 + docs/publican-cloudstack/en-US/images/3.png | Bin 0 -> 1677 bytes docs/publican-cloudstack/en-US/images/3.svg | 28 + docs/publican-cloudstack/en-US/images/4.png | Bin 0 -> 1457 bytes docs/publican-cloudstack/en-US/images/4.svg | 28 + docs/publican-cloudstack/en-US/images/5.png | Bin 0 -> 1597 bytes docs/publican-cloudstack/en-US/images/5.svg | 28 + docs/publican-cloudstack/en-US/images/6.png | Bin 0 -> 1691 bytes docs/publican-cloudstack/en-US/images/6.svg | 28 + docs/publican-cloudstack/en-US/images/7.png | Bin 0 -> 1567 bytes docs/publican-cloudstack/en-US/images/7.svg | 28 + docs/publican-cloudstack/en-US/images/8.png | Bin 0 -> 1711 bytes docs/publican-cloudstack/en-US/images/8.svg | 28 + docs/publican-cloudstack/en-US/images/9.png | Bin 0 -> 1696 bytes docs/publican-cloudstack/en-US/images/9.svg | 28 + docs/publican-cloudstack/en-US/images/dot.png | Bin 0 -> 341 bytes docs/publican-cloudstack/en-US/images/dot.svg | 21 + .../publican-cloudstack/en-US/images/dot2.png | Bin 0 -> 342 bytes .../publican-cloudstack/en-US/images/dot2.svg | 21 + .../en-US/images/h1-bg.png | Bin 0 -> 565 bytes .../en-US/images/h1-bg.svg | 21 + .../en-US/images/image_left.png | Bin 0 -> 4044 bytes .../en-US/images/image_left.svg | 331 +++++++++ .../en-US/images/image_right.png | Bin 0 -> 2260 bytes .../en-US/images/image_right.svg | 21 + .../en-US/images/important.png | Bin 0 -> 2318 bytes .../en-US/images/important.svg | 30 + .../publican-cloudstack/en-US/images/note.png | Bin 0 -> 2086 bytes .../publican-cloudstack/en-US/images/note.svg | 28 + .../en-US/images/stock-go-back.png | Bin 0 -> 790 bytes .../en-US/images/stock-go-back.svg | 21 + .../en-US/images/stock-go-forward.png | Bin 0 -> 860 bytes .../en-US/images/stock-go-forward.svg | 21 + .../en-US/images/stock-go-up.png | Bin 0 -> 753 bytes .../en-US/images/stock-go-up.svg | 21 + .../en-US/images/stock-home.png | Bin 0 -> 819 bytes .../en-US/images/stock-home.svg | 21 + .../en-US/images/title_logo.png | Bin 0 -> 585 bytes .../en-US/images/title_logo.svg | 335 +++++++++ .../en-US/images/warning.png | Bin 0 -> 1941 bytes .../en-US/images/warning.svg | 130 ++++ .../en-US/images/watermark-draft.png | Bin 0 -> 25365 bytes .../en-US/images/watermark-draft.svg | 21 + .../publican-cloudstack.spec | 46 ++ docs/runbook/en-US/Author_Group.xml | 12 + docs/runbook/en-US/Book_Info.xml | 32 + docs/runbook/en-US/Chapter.xml | 33 + docs/runbook/en-US/Environment.xml | 224 ++++++ docs/runbook/en-US/Management.xml | 107 +++ docs/runbook/en-US/Overview.xml | 67 ++ docs/runbook/en-US/Preface.xml | 13 + docs/runbook/en-US/Revision_History.xml | 22 + docs/runbook/en-US/Runbook.ent | 4 + docs/runbook/en-US/Runbook.xml | 17 + docs/runbook/en-US/config.xml | 159 ++++ docs/runbook/en-US/images/icon.svg | 19 + docs/runbook/en-US/kvm.xml | 83 +++ .../hypervisor/vmware/mo/DatacenterMO.java | 474 ++++++------ .../cloud/hypervisor/vmware/mo/HostMO.java | 14 +- .../vmware/mo/HypervisorHostHelper.java | 504 ++++++------- .../vmware/mo/SnapshotDescriptor.java | 136 ++-- .../vmware/mo/VirtualMachineMO.java | 680 +++++++++--------- .../vmware/mo/VirtualSwitchType.java | 16 +- .../hypervisor/vmware/util/VmwareContext.java | 508 ++++++------- .../hypervisor/vmware/util/VmwareHelper.java | 242 +++---- 115 files changed, 4322 insertions(+), 1287 deletions(-) create mode 100644 docs/publican-cloudstack/LICENSE create mode 100644 docs/publican-cloudstack/NOTICE create mode 100644 docs/publican-cloudstack/README create mode 100644 docs/publican-cloudstack/en-US/Feedback.xml create mode 100644 docs/publican-cloudstack/en-US/Legal_Notice.xml create mode 100644 docs/publican-cloudstack/en-US/css/overrides.css create mode 100644 docs/publican-cloudstack/en-US/images/.directory create mode 100644 docs/publican-cloudstack/en-US/images/1.png create mode 100644 docs/publican-cloudstack/en-US/images/1.svg create mode 100644 docs/publican-cloudstack/en-US/images/10.png create mode 100644 docs/publican-cloudstack/en-US/images/10.svg create mode 100644 docs/publican-cloudstack/en-US/images/11.png create mode 100644 docs/publican-cloudstack/en-US/images/11.svg create mode 100644 docs/publican-cloudstack/en-US/images/12.png create mode 100644 docs/publican-cloudstack/en-US/images/12.svg create mode 100644 docs/publican-cloudstack/en-US/images/13.png create mode 100644 docs/publican-cloudstack/en-US/images/13.svg create mode 100644 docs/publican-cloudstack/en-US/images/14.png create mode 100644 docs/publican-cloudstack/en-US/images/14.svg create mode 100644 docs/publican-cloudstack/en-US/images/15.png create mode 100644 docs/publican-cloudstack/en-US/images/15.svg create mode 100644 docs/publican-cloudstack/en-US/images/16.png create mode 100644 docs/publican-cloudstack/en-US/images/16.svg create mode 100644 docs/publican-cloudstack/en-US/images/17.png create mode 100644 docs/publican-cloudstack/en-US/images/17.svg create mode 100644 docs/publican-cloudstack/en-US/images/18.png create mode 100644 docs/publican-cloudstack/en-US/images/18.svg create mode 100644 docs/publican-cloudstack/en-US/images/19.png create mode 100644 docs/publican-cloudstack/en-US/images/19.svg create mode 100644 docs/publican-cloudstack/en-US/images/2.png create mode 100644 docs/publican-cloudstack/en-US/images/2.svg create mode 100644 docs/publican-cloudstack/en-US/images/20.png create mode 100644 docs/publican-cloudstack/en-US/images/20.svg create mode 100644 docs/publican-cloudstack/en-US/images/21.png create mode 100644 docs/publican-cloudstack/en-US/images/21.svg create mode 100644 docs/publican-cloudstack/en-US/images/22.png create mode 100644 docs/publican-cloudstack/en-US/images/22.svg create mode 100644 docs/publican-cloudstack/en-US/images/23.png create mode 100644 docs/publican-cloudstack/en-US/images/23.svg create mode 100644 docs/publican-cloudstack/en-US/images/24.png create mode 100644 docs/publican-cloudstack/en-US/images/24.svg create mode 100644 docs/publican-cloudstack/en-US/images/25.png create mode 100644 docs/publican-cloudstack/en-US/images/25.svg create mode 100644 docs/publican-cloudstack/en-US/images/26.png create mode 100644 docs/publican-cloudstack/en-US/images/26.svg create mode 100644 docs/publican-cloudstack/en-US/images/27.png create mode 100644 docs/publican-cloudstack/en-US/images/27.svg create mode 100644 docs/publican-cloudstack/en-US/images/28.png create mode 100644 docs/publican-cloudstack/en-US/images/28.svg create mode 100644 docs/publican-cloudstack/en-US/images/29.png create mode 100644 docs/publican-cloudstack/en-US/images/29.svg create mode 100644 docs/publican-cloudstack/en-US/images/3.png create mode 100644 docs/publican-cloudstack/en-US/images/3.svg create mode 100644 docs/publican-cloudstack/en-US/images/4.png create mode 100644 docs/publican-cloudstack/en-US/images/4.svg create mode 100644 docs/publican-cloudstack/en-US/images/5.png create mode 100644 docs/publican-cloudstack/en-US/images/5.svg create mode 100644 docs/publican-cloudstack/en-US/images/6.png create mode 100644 docs/publican-cloudstack/en-US/images/6.svg create mode 100644 docs/publican-cloudstack/en-US/images/7.png create mode 100644 docs/publican-cloudstack/en-US/images/7.svg create mode 100644 docs/publican-cloudstack/en-US/images/8.png create mode 100644 docs/publican-cloudstack/en-US/images/8.svg create mode 100644 docs/publican-cloudstack/en-US/images/9.png create mode 100644 docs/publican-cloudstack/en-US/images/9.svg create mode 100644 docs/publican-cloudstack/en-US/images/dot.png create mode 100644 docs/publican-cloudstack/en-US/images/dot.svg create mode 100644 docs/publican-cloudstack/en-US/images/dot2.png create mode 100644 docs/publican-cloudstack/en-US/images/dot2.svg create mode 100644 docs/publican-cloudstack/en-US/images/h1-bg.png create mode 100644 docs/publican-cloudstack/en-US/images/h1-bg.svg create mode 100644 docs/publican-cloudstack/en-US/images/image_left.png create mode 100644 docs/publican-cloudstack/en-US/images/image_left.svg create mode 100644 docs/publican-cloudstack/en-US/images/image_right.png create mode 100644 docs/publican-cloudstack/en-US/images/image_right.svg create mode 100644 docs/publican-cloudstack/en-US/images/important.png create mode 100644 docs/publican-cloudstack/en-US/images/important.svg create mode 100644 docs/publican-cloudstack/en-US/images/note.png create mode 100644 docs/publican-cloudstack/en-US/images/note.svg create mode 100644 docs/publican-cloudstack/en-US/images/stock-go-back.png create mode 100644 docs/publican-cloudstack/en-US/images/stock-go-back.svg create mode 100644 docs/publican-cloudstack/en-US/images/stock-go-forward.png create mode 100644 docs/publican-cloudstack/en-US/images/stock-go-forward.svg create mode 100644 docs/publican-cloudstack/en-US/images/stock-go-up.png create mode 100644 docs/publican-cloudstack/en-US/images/stock-go-up.svg create mode 100644 docs/publican-cloudstack/en-US/images/stock-home.png create mode 100644 docs/publican-cloudstack/en-US/images/stock-home.svg create mode 100644 docs/publican-cloudstack/en-US/images/title_logo.png create mode 100644 docs/publican-cloudstack/en-US/images/title_logo.svg create mode 100644 docs/publican-cloudstack/en-US/images/warning.png create mode 100644 docs/publican-cloudstack/en-US/images/warning.svg create mode 100644 docs/publican-cloudstack/en-US/images/watermark-draft.png create mode 100644 docs/publican-cloudstack/en-US/images/watermark-draft.svg create mode 100644 docs/publican-cloudstack/publican-cloudstack.spec create mode 100644 docs/runbook/en-US/Author_Group.xml create mode 100644 docs/runbook/en-US/Book_Info.xml create mode 100644 docs/runbook/en-US/Chapter.xml create mode 100644 docs/runbook/en-US/Environment.xml create mode 100644 docs/runbook/en-US/Management.xml create mode 100644 docs/runbook/en-US/Overview.xml create mode 100644 docs/runbook/en-US/Preface.xml create mode 100644 docs/runbook/en-US/Revision_History.xml create mode 100644 docs/runbook/en-US/Runbook.ent create mode 100644 docs/runbook/en-US/Runbook.xml create mode 100644 docs/runbook/en-US/config.xml create mode 100644 docs/runbook/en-US/images/icon.svg create mode 100644 docs/runbook/en-US/kvm.xml 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 0000000000000000000000000000000000000000..098e7dfd698b0da6c235cf7c48cd667dc98c8168 GIT binary patch literal 1365 zcmeAS@N?(olHy`uVBq!ia0vp^3Lq@N1|*eVE!z&H*pj^6UH*dsXTCChKQn4b(=1T^oX_#y+2~fBy zAng0*n3Pg;FGnY@bnmSz60wqx|0jOQFL-|IyF z`Z4y7pT~~?JGW*KzD`}U2=?eT*L4-`H; za!pT9U;d>q=&C+rQMtj6UAuO1{ir(w1Pq-|UcP*}vZOI<>suf=Fx$Ks2oAiyz8DA? z90EmDn;AP<1S<**?Ck9LjwHDQ!6nXp{cUXBN0S&U>QYlvSubQnMMpyla zf`-?xQ;cS=nfoDT3fJ1O)vOh_FI~DMlwiOE1U3zf6HlBwcaHDF*VU(=7BSBBv6}05 zTHQu`*1GlU*R#L*26RPk!{aw)yZ5&Iez#je?)%Rgy91BqfMA;6j+-{Nwzj-AKNL8c z81~d!13e%Avts6%t5>gvnw?Ae^ybZ*HCoIk_Wbx)o0XNt8i9=(bT@9Nrner&z&=8&Y4#lw;LQ9a`eQ-;B#s{@ZWA)jQbWtti6P`h+jMN-wyz^r_^8U(Q`qj~`nqz}J3QRpP^y z6UGgxJ#LEw-)&gZ9y;4cEtr$dKxgG~dFi8aIrA80o)=ii6t!#H&e^wNoei^(T9A(i zukY#*t;dbC7Tqy6Oe^Yg8(tgM!t=CH5ZvvcQ8 zMvbmzFNL<ZIFgY*Qx*Ce-w>BqQ>7IaUA~!PCjFq`4KOh=^76(4 z!B%m-ZAa(&6+KvV`J>JG>Gpm{w>E^`zIN>z+n4W?*|^S6R$X*;!u_RgXXGp9$s7QR zg~cv?&Zs0bheuTHd&Zme7N0;z4z^}T2LYx=2ZidrGZ;GO&)Ek|vhU|xNd4Yk`RVD0 z`d_PFnl0gRUkWTJR7+eVN>UO_QmvAUQh^kMk%6J1u7Q!RfoX`Lp_Pf5l`)8IWnhq2 zde0g~LvDUbW?Cg~4dNPU?LZB2ARCIy(yfvbi&J$=i!vF~GILU`^!4>K@^e%5vr|n9 z3k&sK@{>z*Q}arS^^^K_8~Q}c8~gY`3W6Vp?R^$qoa VMxSW?WDB&3!PC{xWt~$(69A;XW0e2^ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1d2ab13127b2cfedac4d3456e724c1e8793890fb GIT binary patch literal 1705 zcmZ|Pc~nzZ8UXM|h>@@jvV@TVWHP`YiwP8{2JFBX$|5D0#+D^4fg~m&n}(=BWHL4^ z4HOL+(F%%yfO1A)2ucA#hER-(RJJNnmP!OG&_HNN0i_rJn)zdX=iK+bbI<+mz3;v6 zzOQ3r!Yxc4Od$xeh>XA!L3G(}RtRwY%g=RpK|rJ(4##hOfQ(yv0eX=9hW0Ck!5@S*mf7rW*W1E{jauG#KQ0zv-eNj?I2Exug z@OIg*P&E2ZpdRhLz?R6{He4lx5~}37&G$522AO`S#?R^1@JZ>#Z~KE%y0?DmU$Yx| zGW(CfLFSXJjZX+uj}FXfUc7_7ub)?YK193fxzzR#sO0_(Gvb zBr+!_#e1X77BSX)ZB2K$Si8Bpxi!5YR!p?CwD^XgBLU=DXtXpriNj{I;au**$r!a&kIPRj3y;ah0pVi~4s!I5K3se{SesfcWkAthR)E_Y9)1@n|FeZ)av^C@vTt zgTXMFURI{HTsnB%vfz>C#6Q1mq63ipR!2vNLtGMv#bUu?2tNWwZ5=&5J$oXeSX?ew z?>z7Z7Zem^JU*TPFr1Cd_@^T*%ST4Q*9+J(?#lhlvZt_cc6OGkmmJ(>AAaYH=;BXn zp8g;iq@y29Ca0vN>{+~a`8g0-s}q`uwz$|onu}Hb2M!$AeICO5*2u^oM;lgec6WC> z8?@J}s;Z`EU>@?LfP&MyxU{r1d}oa1@9>SnM^;-`R|k{HE(7le0vtL4V=FOnlCB2R zQ?BlpYlBgK@nF~cI8!gq-y`&DI@;UYQ%iJkw~C&OiNjE97O08!WeF?{k0%m|)|{!A z-@W9n^(?B@>cn5#wOXZ8iGRKPZh6IedRDSfnR>{jP%4#XN06yhs%z_%>aJWaw?o0m zxDwzj1`?jz>HJq))4a#I(&!qCyS9<;W`Z`X#|L&Ef7dQIYfmh;9tUTMv zb3kvA&PyCuOY)TW+TWkq4^(k13kF^-Z>nu`Hx0aszZLc!^^{BVAhhqzfv+rvG9K#q zHYU|IH8p4Yw@b0v>i*E4w{Bwc?H}L%+G{UuEb1MM_vvPEjJyxYQfZC)rtzOG7$Ee1uvx}~3H?AGg zFruS#fd(eL} zYBTdV$h4&eR~fT&{@25RIQn8)S(%OKCsJZptt7ZzxqW;%)31WtQRkyZhKGm6|MnXW zdCF3uWKj>+2o|10Kd@BB(eb-g_Rj0hAv4J2d{Li{xo{=V`$)l8nWvme`uh3~O9oT}=kmaXzU%)XR3dAOBza32;NR<(85WmGrDW1@=_hC)Kz>+XUmvWW z4>o}0>x=Ub#C^1VkHcc=!pWfjN#O9POnTP;Pq6o(7l4G6?G*$kkKxiN0-BHT1QVh& z*)$vmgJJMEG)xA~|M>Ca7(6ds$f0pF1(rUSHMzGWLOOT_TN*_{tg?B81w)D literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..897afb30257b797aef99c9ff2c9781b20562a7cf GIT binary patch literal 1379 zcmZ{kX;70_6o$V9CTxO?Mp>l^RzyoofW(dgL}`!^WidjCC?aHm)P(F1WyB~@NLvaF zPzsoFlp@6iln_A#sxm^Ng&;OqAtWj=fPe%DvXrGC{%U{pnK}2pb7tQ6-23BRS!8&K zt+lf?006e3L;@L9#75b}z;)+`n~k8r5|4%u)<0uKUC@CYD<1Kr5LDvlI-)*zaHE;Z zJDdb6;&bIJUzG!ZIWm-RI4W5`QWh5Bd>sCr!6}mIiB*as5nB7LVUr!s?wNU(GFz9t z{y!b#oQBph%PzWypB~v%R(N>eVy_oE55f~g7Lcu^Du@p`a`OGp1x94%F*)U$?PZ;> zP+yv!^zlGx^OBj{o(7$jDsPq>w>YX98XBS@T=o6^{m>gPS65drB1-Uqfq@p}8se8* z)cHw{t!L^i96Qcp9HkEE3+d_UkV-y}$FrAwx}#7iPAvP^^p^rMJ6H?|#L!q)R_25# z^bZIKDA{-X?t|9W)*X`hZ&OlI>?BJ9kw^pwJios|#~=z3(9L!oot>SRsgq-4V?_Lu zlH}xjRIlyQ(HIJa0_5FPDwXqYn^a-rnVB+~%SY5W4SG`Vb?QK2?2zzR-}_WAn54A`v%N+vT())0%tR$B$0z z^?6Kpe@0ODG?1#uBQ6fvzeTxr@};qZI-PD)WHGrWisTS46Eu^G+lL1_^LK!}Ps^G% zfcK0yg9pEA$PJn33fo`N1^wcnC)_%CYGy>TTs+2mNR0mKDG=mINDX(>s8p(4N%cBT z-|_~G{bOOf&7KLR8Vh3Xe@Q<$IEZTe@x#k;;&BF6uSYgB>I<2bT@OHDm}4{=tx{LN zx4nK?oTM0e{&t|^=C+uM*umc3UMThM3lJdewN|TDqZC;Mfhh0WB_`NOiZ0`bDLk?+ z4KELW{O&Js!fG1Ryd8_f;YQ}R4A|W1m%8HRT}%bUu2ZkqyY=++fDz*Lr$P?Dy2!O@ zOysYb)5ec>E2WfyzP>(~X`u*attr}dLt9{|@@NcvdtLy%GDO6R(*icDkWbW+EbIJ^ zwh$G3TNe1t%*~PZmgciVLYJ$$-PO|*6BB=JvogTmmVyuI<*{dnJvJsyK$iuHc~F>tta7W4f78yq~DIiMka zV}dX>37?oCWT3!aA{%=BSj=c)7V@woz4}}xEwT3 uoXBR;5>inAZZc9((I?O>PC^nxi1zm02WG#%KO6*(0z!ks3AI6Iulxgb>2k#Y literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b2aa1bddc4fcc06c1ba3ab33ef0d28d3c7e2b946 GIT binary patch literal 1721 zcmZ|PdsGuw8UXM~cnJcE(uE?p6qF!@Oh^Dp0C_affF=e+2}&V>ghvbkNhYKyngEu1 zknkuRiy(-tSj%G(nnn+bL5heWi>N$A14X22A%Inph~QrQYxj@+opa}#x#xUy=YHRu zdx}B-%EHXf41yqwa4IDVM8~zU(HLBv|7uWzV4S%7E6T@DOquVVfEm+FYOD}M>ZcLb zcX-#@q&PD;1w_YBqwsyrIS4Y!4yOc1r;bloY2oS&+uobG!Mi(JTSBWNU)epr_0x}v z^W{&WE*~q)>pf)#m{llvX}$eq(6;ex#~SLk0yaB7pHBVl-p@ag6}&O|FB4riFe|j7 zeWHj(QrYt(fid&*$jz@u5F+k){t4>_rQaXvqbJl0uU_4~d)MszkQ_kgtn~Nyo3j*K z?d|QM1C8`c4@hG|U#BvvVWw|AplVM^1EkEFy1KdzhQ=;HPG{Ze4jA>fB8-T~;~~Dl z3xF^UI-M?k0I3)#DK0KHioc%9}>zhTW~k$J%E1sate?#eyFXjox7bavN(NP zqtVb6slauq;i%WgKwzsznF(#$oyqeyPAc%KnGSRL$?D+w{Pf70- zYR8TMK)PpmaBvXS%8bLEnOR+Db~55(lqnOtwq4cl1tIke$lV>}B0(%xNJt2J;ZIsj zOpJ|V<$?YC_mduz0*JQe#w@nXx8nYhB$HWPnP&P$Dx1yjQplRHZF(a^3UC!3{cPf9 zwpc7i_x2tJRLTs{4V^ST(9h3rCe>!kp@f8l`LTbO{8I=>!-$|`B4?A0C6|YuU9F#b z{k*)qd=o3t$=loe?cy!k%@SI^3@cOH7H(!{HQsZthd9F>Yu8-(ZHXez&-|=>N`-PL!&xih2^~O-oKUH8(dK zQJkD4Ib=}4ElYY~Zf@?%qWIeCrc;!s-x~PFm6uHH3=R$lRE;qnfU19wKp?=e@L2Gm z)pj<@kb~%GYL3Jg6cssPS*i{Xkae-HFtI@{&Q@PIBqbdI-slRPE))%;HkpRIyl`?g zb9pcT=xZ7lUT-!#8KRm9#A31Lt;{>gq9g3~M|`>1KR!A-x?-xzO)4>q7~!^13;Q07 zGLIcQ=ATPhn(Wr=^&}MwU$tka+i4pcafjCO*avFZ*$Y>f#K`6P`Wg3-y|o)1NTe7O zI&KEFyu2;zg8W?X-N#C2KtA@A8z--#L@^kQKkQ`z|1dQ@eLhjl&x z6>bKH#cX=)o6Kv^uI_XF*=ydM%DrNTOD%d;$P zQOc7}TdPw9B9Vx?SZ-gkfg6_T`vo9Be(liu>sJh14bf4*M7do898mqaUsm=IiG3%F zf*jANr*|raGmW0R0>R;9%(zTNh2k)~3kIC$11vtXVW7T`2#r9LH#VGKP-*TB#dX^G zJuKV7^EvEgS1gSB(kS9#LcJ^4+*D*-ae!b||9J8vG!@x05P7sfe^GLn#Vu0SM&llU13hm#>n%1DPZkwku4 q5?kQ$-;-Q{$NqhAS~@$0D}+4>IPmULtJ-p~6cipxr?iBy^8N#3wEqDB literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c6e0022be066e9005a9d6a05c7c75a64430d1a3f GIT binary patch literal 1810 zcmZ|Pdpw)x9suxHf`b!ET7+)usJV2xkfNGKT^8z+Y1i^$ts;>GX(IPBLZUrHbttK* zwyZrJsT!@Mb(^heo7Au>+Vygf+9x_X_pP+3+M|E%{BgdY&-4D?_jy0h_5HoisRPmb zEG--@APBOI2qzr`(Rrg-n}X~1-|O2zFr`NABdvd69{*+p)R=R_zZ8HN{-K2R9NW85 zd7K-Z3ZnCeB3rpw13@MO5v1UlH2ur!DD;)1sP1+4VBgKJ)2D{;E_hmzw!QW1Yg+cN zPE|LMEfqxt+7ksg{?$U)4UMAz9Ug|dn|#+@izuPc@S&ljjh>Gb%XX=HpKq@Hh`smI zn_-`T+??!M$-|fHMA^dBuD9RZ6;B%x{j4O{3|Foc6cm^QU2#C6P|(tno4dPvzFIvq zGs7O6CO7`V#5@%EX8@4Q@aoko^CD6UASG2O6be(K#0iN+^4ATtkzDgL91csEnVAXi zi}D3Dr}9K1(c*j49oEJG6dVj5MbfrR&=(f+LLu&NH{B=BJv=-ht4$NY94K_iYbI8gmzM*i(BreU)t+cH+W2S24~f?$?HZgxgETXS1-Z>lPEJC^ zfJ4B#6goWf?AbHa{6Y$!&&P9l6nr(g%>FI?92u<3J?JvZ$;ru7ODzbwd}$#dXVavx z574}hVK5l=Ynt5LsL04j=``!)on%PgmCj@`Rcl01k;9 zZif0fg2n*dIl(M+0|Nur&PbhBtBrpn;8A=WOBB4{7mop%Na@d~CGS14Sga|TQ4_6H z=k?yne>m}H{?)5XOH0R{iCuMdbtcIz?FrbY@1bX`mUy)3$mnJuU#BZBF1ARfxq@{g z{Qb|>)YO=ajLIu2Dxd-?jYc!JHhZ_Ww$`+|^L$aVS{(`~{4>zf!=L-vGojXSvg?Hx z>eL^BC3vfe@1wkTX<$b1(o#End;9!?0+mXI?-QWyWcPlB5)&VLa(!1<9|4;CVH^%; zuEf~6xFKe|y`@{ZAAE#m&19NTD17|@zRR(!w6s(@_u>f96!>)NDbO_hoK+s~s(Nud zG8RTb|egmX(d1Ym#?P_3yR)OC!(6=jWMpK7wbmh*Hv*zPBE;}#%0mq? zJBGV&Rzi-SCnY7ln1Oc&7TsC+^HU54bL*xff_dw(<<(!n9@MQ2h~)Dp>_I3kyR-L&*7M z0i8~-qwoI@|HRnX3b55Ic_7Wl(Gm8pDPeDE0P!F&tG`|eC6tm}%83cd{r&lX-M+Mc zs;m8@Ec}jmY_WK?ZdK)88CmCJJjUg;w$2u}WhN#j)~>l0=Anfvo>Q zvj0haz`k>GL0(>-l^2TaCcm#(nR=?z=}hKlKR&Ia8X+UHv$F~FE27xgSX<46+_igf z5WLnQ=V!4I-M7UJ&CSjAb1@A8Zo8|;9es?QS!|mLl0%s?l1!FJB)98Yvm7q0SI3+$ zFE6KfJMXu=e8x2u*|T_I%2%$);&pT>mCEk--ivLTmlcL+ta4~<>U90_I851u!C-)s zLd(Zb_J9-=il@D@cf8*a&@CKVq z^zo3z)ziPNjS%cFG5O}^-%4HN<)65W zB^_=2{?oG$&-DCcLJooTSZ3sG3*v3s^;w)?naPTas=s>Y1~>~To~#20!cJw|e!sC5 z0jC;Uln>+)vh^+Nux%a>EO#!F-M}ILi7+%?NTUepgcLp<1PJft?TzumW4wH0yuArN zeuSMH_XIC5hDg8Xe;Tkkv~@E + + + + + 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 0000000000000000000000000000000000000000..93833719cff14bf0fccbbfd7b5a2d0a2797538a7 GIT binary patch literal 1597 zcmZ|Pc~lce7y$6agdivw6%BU~L68aw5I_+q*Z|=uAVQR*90?&DA>m3aAsn?TV4$dZ zfD$86jJDO(`)LYF6v9ysL5dtwP7zQJ6$6P#=-^-NAN{>I`|X>3voqi9w^JDC@1?1s zrvX8brZ)i}1fubJLn6R+_nWH^KtPauz3^*as2^J%0zK*}gwS*l316CLYm)1FCo9FB z3Zn6smjCIJ0D|Bv-gx)m_~FTmZ2@5c+RgROjoedb?pGb^Me3W~^Gqr_A^V{a&rAI4 zg%@XEQR>@4f#)hJV{&l0Y5MtJ-wkE$_TU)!Se{K^XkxB;#2lYl}mjwcWO61Lk zu@w1ByP`wYfzW1NSy>sPF6TQUk%+J;WdeDAWtEkc&sLo?>+9hJ20xk2X6xPhY=^~S zp$PF7EiJ8w{9l4Acsw4gF3S;z!@;jya|B>eN%MqM0v$byA8qms4-eNL&6uB^olP;{ zukG!93dr+!w70icC76Z+hp`ZIrnq=%X^AyD-#N#stuc2-R=Zi2`ltwUNF>q*g70;a zNR*9$?KkiRBySSI;_Op$7Zw$q+uMycR${gl;@vV8elm;2axj4*xuK$057ng)7$AL-r0=E~Fr@D$+G8}$LK_+ydJK;w8X6cF6iJ}+ zadMPcf^Rq-qvLjcZed|TZQssqQTQ`$l>1?#CnX7GDzi&svG~Be zs>h!%A3Oq-g$D&MfdDk-f;G{Clj{D$|3(4V*U!%nj;nb5__1qr=0H47FE@9HyC{>% zm`mwpY7trfU{A?Z$nx`N4#>5%){HfmeGJtGt8+9BEp*t-tEi}Wb9_}OeE$4-(0o(< zQvVz)O9xS~BjavOl5*-9pU>BKv+Rw>RgA9UO)mQF$@-KPia^@=2!mR)9Z(v2?jIDX zfZMkn;JZXl=jiH!tPLeio>br+YaCwcBP4xIol_~g@M@y_v_`J=biU@vNtHD5lV~h7 zHPr@m+ev0=-)FjXs91P;)d1Bitvm2XjrVN{{FPw4)tZyT;c)8eqqh<`brII(Fm-iZ z04g!p)*#g%x<8<$5yp-@%+aYine>&QQxqS3p@Cw)c4 z>#Ezfrvn3PY9h5um(RDf#wOBew4&jY;@1<+3WXvwH`(TF)j*X`NK{nRmO6GwaB#48 zlI}U)CBO4_!Vm8?x_8TA=2>(zy<==^FZEE+s8HGeB(yF_De z0Fbx0D$tGc_a&E>zItkQAoN<#j0t+G^(Z+gVZ8zaLp(GroD4%vg48oR?Qxx5GcBrq zAv^Z=y2xDfo<8a5YJf);3l0`=+0G994#fA)>+4Z2;R1iIPxAnz=v4b9>SEuB*4n1< z7_Uke?+6~8hh`Zb$1-ALGAK^uGztiiE!M`y3TtbHwGXzjal$z`*{$C@VX<+{;e-Df zkj#iph|B!{0Vs>Od@vwteTH-v)rl07PO)O9B|vcrG>Q`jgNbJ(Q!q&s94IOboNQqnOtIBW23^x-61FcswO M;gA3QQ1pp^0G=h#0RR91 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e50bcb9503189f14d5640ec52ca43b4aaca18b4e GIT binary patch literal 1689 zcmZ|PeK=El902e$t=drDqC#ls(yVz|a!1!NwW;eR zgnRRn<$B4>ilvoqM0LF+L~bb-xgpK{>92eLxS!|wp6_{n&+|Lq?>Xmt4&U2z?>bd| zRS1ICkx9e@Ae*d&<{EG`eRrb{q&1QI_7a!BK?Z&v1S`mRQcxnuq;IiDe(Z;pMRvSP z49F(mB5m<%0R*iMAQN5ujtq?lJ;D|rGEC+cmu!*UzMUk3Q|!~bt`uI=QG;JZ-6YaD1IU1U*+tvF*Kw!f@w{ZspbjDxKV=9|a)J_U8M+uL4AXp3)} zCcf@|vQRL4$MAWp^Vwy~KS%6M28Wg9{Hm(s08GM3PEIze4t@c^@+RNEf3F_jV5KKa zHF`3!ujGKGbmCEz?PkRcl}sihP4Zs!_Vz-NOgf!D)iWUHF6o&t^7s1!Ql)bHyUdKBa7MUh*49y^!X~R68&Cky}m|XM^2nbk) z!K^Oj=H}`Sx1~LN_|QW-nRMsnltQaj&E64(LaA6_4h07XtC(d!1)w2{ez@er^z`(q zMp0v9BR+cc?b{E4^v-e5(jMg4_&N;@4LgHt&$v!T8eLt4OXuG1!s9^;qU2YT&7kL^ z4=jg_%*;$hQPDm~n0Wc&%-DVT1KH^?S=8phturw5RVzCa8-g9NM*?&`hTGCzP78VvJ zJ_9@TyL5c~`Sa&`;dRD_hKAN>cqnCPgk-b&nsdw6A53|DPL7U_26TzoNO@ub5nh|! zti!GDi?uK8j%6?ytLEm$x+*HnW7Kqqw6$^iqHXhi6&noz7((%q!{u`Ixr0Jx9Y*)o~Tov^*4tgH-iN;zHmg|mPdUUU)UdQ%ux5{X2|VYhiD z_jEJpeeL@xHW(ggeFqoE!otb9it4hJXhEd_c)?uKsyZ$o|1^Gwr}WtzM-b#)}9PUuCr?{JxS*mURE&zo=qtRc`mG_nOrPbpKvFwanSIynFS`ruh zYt32ifvl(q78OrPpn?S1THDxQtZgyYJN;~I@Hl(C-O4%M+B!OE$nifL;uul1XwLs{ z*k}=*1~!DPR7hmU;3FdvshFe$8Wc^7rQ)$z>=8yB6?=?|V=|doB7>3?N2Rk8v6NUw zQdAU!MPbBY$=HH7{I>z4@ON)z$p(bK&cJ2VzM%lQgfKm|I-IG}98lLhG Dq + + + + + 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 0000000000000000000000000000000000000000..ff3705d120a675488a0c21de178dcb37f7144a9e GIT binary patch literal 1817 zcmZ|QdpMg}8UXNw1c|y5Yq-4oxTB?E}(`v^hsYIG0NhP5uQr3g5x{mEl z=$P%a6-<>9Gj3g%vTlp2ZCxT-n+`*&P3gF_bM&v>Klb-L=X<~BJl}iH_nqfG=gSKY z^wmS|LqZ@By%TCr?nmqMe^zI5UNv;+cI`lMP-Ld=R^tWm2r2jn3-%JI-Xo zr@9qBl<>Tdn$tQ6_d1(8S%RWfR}qtUqYHPBe+ADxo<;nwc6pI7qniIPw}q|XC)O93;=J>Xby8UmBYCPZYS+bkkGQ9rBbP` zj@}TktqVh&UjqpmD*2Mo!<^m_5fv3BkD6Pfg(%!JLj3SJK)EO ziHUFMDGuJ=-tx4$;^H!(bKv?Z=>(FL_7Yf3BPS$BMn+l`mAZh33|dn}$;rux*9&{E z9k(vJc?6HgYvfW^0r60xNF+M8$*GUya=D+3pv;KDk<&C94KgXG+LrcTG`)>6)Pa#N zTwt@=hliABK@E3YBSd3I#KkL(l{oC8J-L>@h`2tE;QUPYXjsLPEr1@%{Vv z?KU>0OAQSTE_7~PYinzHL07CsVp6{%A;rVp-Cg;zvw{8kt*%aPety2%i;hfBw<`97 z+1NHUHa7li1cd_2B;|PDkBcS@4-O8>n%IQEpr9a4t)m$k86Br#hP~>P67IC3E2pZe z%4%-r7m(H{KV<1xBa_L@=J+L7zeH(&d9w*rGPM$3>0K&bZU_kopi-&Vv|(Wq z-UDsxoS%5_-QlKJN0jf)l{W)o0W}f#R(W*jTcTm-tA8#ew5Sjd!Ps}1Xbwy`NJm2Y;71nnNqm9kJcg1B)=78`#$+pBWopjd3mjgA*hTRO=!piP=gy4 zVu^W(e`xj%vf=LCyI;wSKW^pb=ITs#w`9`(LvqsAFhN?`lHjHN3O-TT^$!bl0nMRI z<8u0?OP7e9^oK9v4yD=o3)429J%9dO3uoqNdKGSCLvVF|P{uym-|LawflufFGu^xefa3o934;(mWHN*-kLUyz2oO9t zJux^u2Ioq1cJ?5+dARJ{d*E;}qFK-XNr>k$IWfuqKLKSIlLHc>c4iPHvOUf*1T2gw zfdh%*#IZcESnPRTJPRAkB3!(95li7ki{e>ap#U2l#}hG`JYh619?KV + + + + + 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 0000000000000000000000000000000000000000..594964530b0a072ff0fd597909e52718a10ac0de GIT binary patch literal 1688 zcmZ|PdpMJO902flVwqf~6e?8it8FM@I4HT+?1;6VGs>8`>_S+x&`4@$$rFmyD%GLP zrA~E>6qSz3WgOPYq2`ijN^)7vhMe=$U+4UBKF{-ezwh&V-|z48yx-r;C*b|{bk^%Y z5Tq9v;2R3!rsal&gRAAoih2;>lwg0~zrRC}<_19zA}Qct3Wx#Uo8QaCAC^1WNj@|X zH+^rX<}V8&NQ)Tg>k}6DZtP&hwo43?$MgOo^h9+yW6@~Or&ixM^sS6MYt5HPedI624R77G7&0P{p~!4?gZH_r;(S}L3tv?w)?c6Sn{?+WD+JuH3~7S8wx}ZWs{C_i z#FS!Ck|{HoXbTxSuEV}%rtK^~N>wT3ot>TgTIg4VLZMdm>#?yhYRec7&>&+3&nYu! z_Hw1%t-!L;bH-}TA+kq)>NI;E> zih^+z75DGoHxf5_czJmln9Ya|-+T7-=~G@#j#{lw_eP=Z?Ci92ApJI_Qn_E1PfH<`>}FwmB;(-im$H)h807ejpVLDimOnRCvcc5U6j8c&6zGuuRB(VuB${YX zOVc?Vj!8mebIwLqLK>)pl}Q;*VzGGqwteY{Xo4FVsUd!>rm1Q-my{G27eka}E|-hT z?3=Ua_0o4#9`A zOeRxbwe&XjUjJgf?P&t)d=Ok?TI;5{fpci+iz}5BUh|J2yUcjPnip2p`ysX5vTJk? z0ORxb0lb09RGg64?*R(aOdN6h)AIW4&W8gXdiVN=fh&2>!*fps{}O7CG&HoZurRno zB4g(AelSYw+V2bx&pJfDynOgDkXc<~mCx*?RCMOd8C{v_u)vsEKcIJq1a{>U@NH&v zc6N3(M_mXCH7ohOJOlN7txh=VybdX%rna^gu5Yj+xO}(dAyu3IJmhns;6*VBrPm1k`(aye1tPv zhSYwMTq!MddUK$+PhOjUIskxTuh*7UHy-L?Gmk2lTtF=zuLrRT_ zN~PkWk5EB?oWMaqJ2;^ooWmR)aXWV6wlCk~92{cP-nsuLfx(K2k4^vo1Y^6{Qy}5c z@(d|#8jcc`LPe(?iHBn2=~NsRi;ZJ3sMtj6j^yNItS>7%jX`CmreLG#thAUIR%$eh xflW%I(Bq?{nCO3ZQkm%R{n&U$6pfmKb#%diu}L$ABVZ~ha1Y+McGuyYe*g?#1IhpZ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7e8dbb464e3d681e9818964136c3a30c2bf0c657 GIT binary patch literal 1832 zcmZ{kdo-Kb7Qny6V=!nKH_?Y)x1LQ)LR2Fil4{a=O=*fmS>u^Rypj-1G@;rOq@;9a zih6Zn)V~r?x6b79< zVPdq)2!bFJUmr3RXzOi3=!37#!grlO>Bsn=Aa8xdkgibziy_x1EDdO%k8=EeqSv-D zgL{+(wDm_3uUAz=klvgx`Dk$bv?^>EQy*@*wb~zlyn#r4!y_ShW5-kIkIPc~> zJ=H5~o6~7E?><*VPi^RaXo@0s!W1S;uPe1He33|Gh21p>$eo?d%gfV~CwSuVc#Q^z4 z_m|)QLae#&9UTx5V2nWhqEsr4hvHNKNFLKhS6Is@cK+kWSZGK{2+YAD5gK1ajT*UI5!b_Jf3E{9Cb}eI}G#X8ZMpFX-vMCa{*=ziT4@(Yq?Qi)LFCNl?{H)c+j#u=aZqI!y{fvp+C;cE0+x_)^VgA)5qQCX2Y^r9ivi^*uNh<# z!4mfE)kF|Hey;`@m3bA9y22I+1QV;e0>QmCS+cF?kGN94>QgOWwxJe8twM_ZYSKbxE`>>fgc%^`}I_IR#ui@r-ba+ zNHx^e+isC3uiSS}ywum3_~+705z5BG%gg?(y7{Q+eq&=%QIV0gO>9g|%=v7p+0)_S zv9Yng)jhc}mT-tGV7u)qUQ!di&VVw-b>KqfjjH#J+TI`4{*BcAm#dVcqoX=OeFgh^ z{_TC2AQ@1lc9Z;!=G6}}v0sI8)B_0lI?6Y+W>;IAt$600oq3@yo={m^Tl>j-&Ha(h z53L3q2c>&V#r+$eZntmVylMQE=2l-{ z-`?fbVu?gj|BB!_H9kHLb#$Bw4-bdc^OBO19<6Szt()&%TeJPwDhYxwXrILU`TP4% zeRj6lC(r?Y>JEj~wZWvac|4vA0&yA4{adBml2lGAtMawYq!ldDZ`-Z}JLZeUVozd9 z&F)}wb5Ia_d5Utnv-jJgF6!w|^!4>2_sNG3AHM8nPkaBSZmX#DOSlkBp3kUi%CSbW z7z_psJ+=sV7-kj>Q6^Mur{!sQkb!ZqqlFQvu@a2G&c^0v;AyL=!G|Cf5B8y)b8}O> zBeJ&y*&Zl_(RQ2WDkIDbhE#D91Ch_~u@{PPzok+S4-MNj_C(5d)GZqvKGxa4mazEZ z^1)M*fhepcBw=J`W?o$i)bsn_Xn xGKQNTlf;gVPI3C9k&)sQavH-) + + + + + 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 0000000000000000000000000000000000000000..eb43c6fdca1a60be38f4486b298840a72217eefb GIT binary patch literal 1823 zcmZ|Pc~DbH8UXN@5IKc$fF(pgA_y`{OgNTPK{3i9n?VtTaONTe2;m6Vj6%3Y3Rnsv z2y!@u0|F8#jSNCW4u^5%5RfnqAto&0Tvy~UKyhs2U$cMgud3hos;j>4e%;^eJTHQ) zy6RC?2!hnz-SF2yL?5&xir{Iy^m981isUP<`2DX`{Ny6gqY~rh9}lA2*LL}Jq|-rX zV$20Pi0H2^cl&-71Ra`o$6vS}E|%R3GOrBLALwQZo=#{q39l5S*p}e3?!F~P1s=f~ z_i}Fsw78#eIWbeMmgkr^8KjF0AS?IvcHwsfSsmpXqbMIA1I&K@TH2~7zuGdgeaG2$ z$liWraqCu1d@6RH6tt(bSKn$NfL#Bz-f1cf*8w85w))g#VtjmD!F=EQ z#*G_F`pd$}$;nTw2QDN$9*Sume0b%E4sz~_0thBTg%FSH^ z@f1!^Ppc~@QX#{gZ`WX4-Je6gr)LQnFlG zRaLdChwy501=7DUw6wCaO3%*+W5y4lqBSZ%&dkif>mI5DFmf!BNUTsFu~2^-Q3j+x zdfnC4bvCRoGvgG%$$$%jc}msiA{h)u+w_rQH`9{WP&S!Lr6SDC?CkCBVXLdwM+%qan8u#`1#K*#31Oc9Y9_k-x z=kxh67;H9Nq?06HSXc-@{{Zb+&?k-S2;6Sy=s2XLq@*x9S^#jobWtdjN>`d8@J(QF zg{P@jOk!$sa1J5fKrpUXQkc=6&8F z*l(2~{>P;`c}0f#Kzea8IP}?0HFR-ZeSQ5n^Kl{=YGd99RdCt3cA}-Zx%us`CxJzK z_~ONjJsr5d{^0QNFnnMj5*Spg*Q^eCHQ{5flfU?E^!H-NbJJkY9!zQ1*!%6ypxct)zCucMoE!nm! zSzKRVFO7C|>;$Yvy7!rJadBgcFv7+Z@C7MZn->a&zRxkmW?T;w0|P(vlK`hry0*1b zb2zjl)s&!q_v3R@j#TM8-+vEH^7;d?7#~o=!yFAP}6JOCUaZ<6`eg z{3N~vSkSYwv-<;{_(j=FDVF_^k`fym3+qZ9lE&DvySvlCFVm%e$p9g+a9hP z16va)k@ofX_v2kFV}CTGFU=>#x3T+vHraR*C&Zf@F17EwqflAhN0Xr;WG(9+e=**_IGPvoe2qfoQ(OQy!Icr)~_ zT%Ak*jXJB~d0DZev2$4t-T86Tl8RdUp7P-xHGgU26xZX>!bSkFo_y-+PpPjovt1r+ zo^~qOo!*I+wF4rYi?q&tvF@ia_A90LktMA00uSZp|p zNyA3ctie%Y@hnOLlNQa6$5NtL2~;YJO<^&yF$v@-289%j`D-UF8sp=QWiUx}T0GXm X{tOs + + + + + 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 0000000000000000000000000000000000000000..e550c21cb112df2f1a182c1196a75c52df0a9eac GIT binary patch literal 1608 zcmZ{kdo!H`Q)jujarYO>G_NTvg|Jctt&-;DPbI$X8&-=d5d9!`+2Vt69GywpB z;jkD#P)*ijlNz|1&fSuLqDJvLh*|pql(akqW}qCbKNnQ&kMQg|?XsSX;kbo@YVsp8 zSB1p@psJ3;xDmqMPF}?w2?#QLyryyOd$XQ9suMZ$=hA~F^iOT)Uo1(s1zIi( zr;}yeUYqJWN$JV?71$#t&p7R$N5{t}CnxFTS|{guIBWILuS zYa1g3-IFP3q_wp*M8Ws_gRlxf`n=*;n&5!}SNH)Ewlo1sc7N&v4 z->Iyu)Jg}4^G}~X)lz)r#>K@sa^hw`@|`c)3<)YKu3Wid=z8;7NlA&Cjt*f@!5n;T z126rdxS^o|Y8ZMNJUH4ua65y=VyPYS>Y5@QpN?t>Y?a2cByV8(h3nk`9o$h6g{-B? z*~!UivG@7xkX$Zr5CF8G#IMg@zkaRB@7)T|G+oK=H#4gk2)E_LH%cTD^~BY3(6IGW zR6;_6(V_Nv2yB*Pp}Q?mF%US6L14#4**ZTn-` zQHNyX^D$15O2I$p=H%qSKExU!K);3W2^gu-&<-(VDtXBAH13O;F(=C>)}N2Z_w(N14tyYO*j@i*`=F}+5UCyQP)(rp1pi> zXG)J};|nea`658_mgtrx+mNKY zh`oFFDkpsp3=R(7I8r}E5|hjyqyu__iE(dT<5Gb@piZNIURqiL)Z9HhJXFaNgr%kB zS(#!@rGBhqwE@_A&&X(whuX^3_1T4OPU)c3$Rk`WcWQ^2xFkLSsb5=xqA3DIQqkx~ zB<|3y-?<=HbzN`6s@_?$t(%ReG(XM8V z&1jz2{*;vxKSw(|J2f8y1*E)3Q%m5L>vZ!sd^&r?9YQ=qp{~zwYFgUZ*jR|kp1Js! zUnH)AN1B>g=Ed&j6VBY}&MY62pPwJ3Vqk***9oGE#}1IV>FB`#av!8mL!~_bCUO3A ze6xLPT-eM#J`T#L*HAIb)F`}of|{5VA0Lmp-hUBt4(%3rMrJyA^(^Z`pHhLR`=Myj z7v(U+8LhuJkGy;(DlqpIbW_Bnzb==&dX=A_ulFG|t-8Lxe#N)8)5v};F?PjZQI+3& zdt%@l_&4t0d60Ot5FQ;xjiQ4BSX&{H7FO04R<;Br61C3`WwX9VSy`Qme(Us~0w$Zr zI2HH*1qQoLWr77K*B!Vqp(siSmu?Xq#Q;t*BIqat0ujb$(h;ZW`ywMF5g0Z#nn`Ez zxCm+lJDNsg^Qdelf)h=NU{FI?7XMDtSr*5RA{fk&P&yZ3Z3(u{+mW>ZIsrHjJmwCX Goc0em_}O9r literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..692badc3cd1f2ab269d8070421c4ee9b7f428b32 GIT binary patch literal 1937 zcmZ{ldo+~$8pq#vG>SwbiHUJ5N23`-XlO(u?Cmm!En+X18F$l+G48iP4mLZritIC_ z8$-=Z!X6`y`*o8@9cS<4dL*}Ma92GCIG?qi_j%W|)^mB^?{7W7JhH39K6wp! z2!i%GIg%*Aqjzk-EO_cIR5k!78}y?C>DzbYyf?-`M2_j`69c^CcRSY?N!$s>F>OPE zM}N1RPo-rb)y;`y>lrpa>(h^=rmNZrit)x3cf(BCl!xjR=>j$LhX@RLpffXj)XvV^ zCm+4^MJ7l`?dIO;tIj2PZy)ZG7W5?O>#;q%xp9Pw`j)Qvi^BQXIZ=rTzWnLajq#Yl zjnWm#1aK+gB5h8(>S~YI4&e ztE*w0x`ny9xt6QD;xP;cqcHjM!Q;n|37kV%R!mF`4279#EGwe|aA+A`iPzt zH5g!&klfSN)dly`$^cN5$Qz^f4c;Blviia^EiH}M`m$&^%FMdsSXc(6r?c5?)ybA`&jAqME59o!(Yj;Vme&L(K{#$+;wLNv9C9rX`z=^>T%_4U^cW0M|>#o`h} z9xun0H$oTPz1!E<=aiBr@B%8)MOgox?$M__Jdl8YC#8O=A{(lTQTQugVJj;`F-qGF z;9cSm;q|5V%`Sj_|s>yU#(_!of#!H_OgZ@xM8zIICGpBvgP@`tsmkpVcwN zb#-;75yWW(y60*|c&5zir{?BnVnoN0uDVd&tB!0B9aYafwk=>&efc$a222pCTb|<( z5D&&U$Zmx(@ocSl)$wr?0Oanz4**@D15F97 zeSM%Ae}=U*ay^wv#W(t$*f1ydywUOXwmaK7dcNAz2v$@C>U38j`)O5590A!6b$?Iw zhp(v#2?>_OZX@C&F`v&@;B;(lHQhK*qtWz<-SP$wiwFIQwfWCsI~{^E`6se^%`XZv z{}eOT{96>2l$2&F8VcP~Qc|orXRZ_#6(K)-40dvIl5>4um9`%DXI2eT?3YK<)e*M7 zm-X5#DAdc^SpPc!qSb;Wr1%8J+xWY?yTdhgS>qn?@gm8SJAm8?r_XRxQx&WI`KU+N z;%Hc8pu|4;N~P`X{enxW1{@5SX3OwE-{_0!rmAg8=ICM^L&kW z?+jn}&Hl?|bJWG-54+wDnIn{Yl=`{1tL1L->3eG^7mVyBw(;>j3x{)#+Y)WST0x$v zCe2G3TYBD@bbue$Avwd<3X&;2cB6k5`k~_7-QmgXp>o;cgA~e8_TIu{V9gBnH?H__ zI^=*1NOCn<2KnQ8lzGy(q1J`H{123BvV=MM8B$PUnzF5y9(F6P4`U0g zNlz0Kf|)tNbmyIb!-d3-Tm4T0ok0r^N&No_hYUk|IGhyMWC909jsfz5oCK literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..231735e5aa99aaac5df568e0ce0395ca1f291e61 GIT binary patch literal 1723 zcmZ{keK=cp6vuDWOC;#ltXS)@tXc3>BtfceybO&dv}lubV`YLQN?t`oy|lungj$>0 z(2Zi6PI+ciGw~L*HA`!2tCV!9Decrti*;Q>L-*6awm;L#iQh9y`rbC=qIvrITZrM!BLb(BF5BGzJBbQZiPaEC{9Yg0KUye8CPU zV==}m!UW4-a@cbupe9b(JnzQbItBT&+H$gZ7QB?SHzcw zr_Tcx(_$Cb^taaf)$1@*J!>@!rm=h(8J;8iv9q%i@kBZe=+kQTdc6~?#mU*(+06dt zojZ4wC;SRATND(i5Cvj(ewpW#N+qmlpa2jk7E2_OD>GwS^(%XHB(H5Bpzj`+!C;`o zLcLC>Th<4!n2bi_@kw24d3m}0x*>7f^G{>QV9f`ua(< zUw3V7?c`>-SW5Eu_qWY4o&`0n#`$2a&|prY4qoc*?S233`Mm&Zc)@u9-fxC4@BhB7 zt<9ogrUWp1T{S#6HSqyeQ>_caRCMdgU#tLqBcBJ? z9fF#gYysf=(dqOpOLIpeBO^DXzqmItGIDz+zBSX&c{A<6JYW<1N^^5FUOq4->4+IC z=u(f&zsO>xDsvo*3x6|PSVYZ8vO3jj^%K)TT(1nY-;|WJk=Iv2s0M&}noOqd6EQhC ziHV7rwUsKTDat4LUjt%X7vR5ZE{~?{svZ68^y$-TEOhu_{kwyu-j2CW8Cm{1v)%DT zzECK<|6OMH`1p9#s`|`3H^GqPmoNVXc!>-Qs!s;@W&7lJ@2XTP?4&6tJ3ITg6=XoJ zP$Uvr9lX@j)8oJT%H~uJVC}y0`9(9=$ZM?IV1k2#q;RNOD3wY_(vWb(xiHmmjRU2s zvHf9@L%6&QbtU5&(!S){L$Q4D3{Vr}slo7f7O37s=+iELr}?=K;-Z%SFodw#91chI zpo`%`+e;N)<9Ad$ghMxT-;3^WH?3KicLScF3hV;+y*44aa@l z%9Mm5*7rKT57E1xewiuP{s3gMcw*|;z*Y!P#o3oUsBt5AYBU<>Hx%%PIvqG0F_SM1 zrKP2|ad*wtdEi(~kIePTycH-^|@XDK?ytoO_Tv{uG>;iBC zemgeT>x2G);Fc^>!+}v_Mg+hV2-l-{LV;?k)&gGme9t+o>vny*-D6U_> zPMLW#K6&=RTqp+9`+;Plrwbf&Ge;Yjve{tOpR4z|tvb13QSo^1)q3iu)Q=~g!YZ$2 z_4UIPRSnbgbyF|qTUuH?vjxj8PAMMBx3+HGdI!@{XqG2`??}S(qC2J6(9PxTK%#-P2BNF&2VcV84V$fZ@N5)L@zI|EwlsM9UUE^%AvT{u3igfD9)pF z#1e>k>g|f{m>q{@GMP^;^W5~Zs0D84io@ZCH24pBc|ssBG#X1#Nx+7C&hX6b%xFK~ zuShZGW*ss3jNA*p?LQe!K>2$DRXZ%+>Zszs8E{5#AT=2C5#7w4^u{jU`|^A%^1k+I zE^onDRN0`tIGWP-*P|kYxFN32&E4I7KIn&^oPE|;o-Msfc-DODqRsh@-!xVl5+!BF zOF8632?sdHi|Fa;LG6BF_C~n;BiQ)si_2tC^22Y5lYhtiF{Eyn=O(iiUb64 udICQ=F<$8L?;uC$afCrg7Q`oU(g + + + + + 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 0000000000000000000000000000000000000000..a77ea0faa5ba97a8c20a807d7ed464ae909baa15 GIT binary patch literal 1620 zcmZ{kdsNbA7{`A=pm<3`(P{Ip)hfW-T%psMlsY`1h?mMlXXh2=p%^C$pk6)XVKu~GqaMId4(20LO0Uop{V!s$@#5>zJbU1k3nJo(C z0(E_7CCle8KoAlWNeZR&w7={pQyqo2dDi~NisQ+lx9Jh3Y3Zls(a6nM8}$}}${#P8 z5zhCW3F+n4hxB!M<5hTp<pwsD~#m~|M z&Yjs$jlrBG!K3Lk8V$4fbZ=^Es+((NJOG}RH3gWFSBP`$U8x7JUIz3|a=2XXR?*YP zU|8jS`9mGsX96~HKz(js&7B|t&{HHAWf2`)ys1t&Ms zu0S0}SuEBDYg1dZVs|*IPWifTPgqzOLX`L7NO#iLu}|!STBEnw!Udz_y z(*{vJ$X&CxTEy-8?9mCobE6!6^_S&iqobqj7uU0US69_)H7Vt3it*XWB)oi$;fkSq zjLuRCRj}vTPXlw1a&n9rC8PHE0~K^Skry-)HqzAG@BpNiHsZI!^pqR(zjQhpfp5( z-_g+l!=N`wvg1Kp6f$lF0Nls=f7}tU8(@lv&ZU)`m@g*|jXa;9pNHx7cZY|EVI@qN zOt$+~P@bjE(62};phQ|(aXB0g+@?j-VAVS#>Q2Jf(Y}ttTLQX+jciMx0y>CGmGHb_j4RA522>t_kd>~Ph+xuYb*xG zT%4VqQT6q$3G8yDguFAP_BHD7H@a6fbtWE|NC3J{^UbXB+H=!WpGHMRv7VWA+P|lO z@k&VzagCaL0L8*WL}5mm{OnhSWf3I7@#w6D`_<9aRaI4}IY~odeY}nRCbPjM(J|-K zsZ| z)RHyCs?IfR1y{Khe3M?1y@?W5s)S8s9$^E4e7${qaNfQ+?+@udK1BZjqTl+Q= + + + + + 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 0000000000000000000000000000000000000000..1802579ef90e80a54a3becf5a97a4c3936e05253 GIT binary patch literal 2007 zcmZ{lX;c$P633Hp2RR($aEO2yXE>8^EJ8p*1r3OZgh3Dn2_fOi!4V=?1i8Zvt{ifT zVnhX*$siyqK~}^C11y3%5CjQ`O;y6aW5J={;Iz_sBJ z2t>sN=i~`gf7{gM!MOkZ%{CzNK_^c*efy4*k7xpTlp=AyF+g$O?fCPE!`n_~uN>|BCqPs^v=EO)=sYVdRmTsSR=!B?icBm?}FRLh~v2-?Lo!M0jhrP5A4t#@!JSJpkU;R+@sEF2uy-5FjO>tEHs{GQXjnf4t`* zTD>pWLQ7x0y|c4Z#xsmUp_ooh7nhcn%G=mh+r|h7rawHli-Q*lxZHdIPwaE%%$c1n z9UHRxfiv0?&ly=r=`Y(zc%+MS)z;F| zf+n$I0B=_1U}phS6CL0z)>H4EHZ(LGnELnb>%*b4{~2jL*Ysm{F80>zwt4Mo$`>J|*1^VQ}_{(Oofm6Ntdk&UM!#5U2IH&P1mzui+F&v&NHdoI3q#Y;4RTIx|Zd4u_YE#7UPN^&t-* z&ZCxzcbhjiHa4JK?hAl-1Ef)L*RC6aNWurd&XI5zc#Fy&0I|loJ|!guB776*20{D}3`lrRk#eo3MI7Y+T`X|6ZTUe=#a1NyN z>yY!yAwElDu~^^ksVl|O)Kh2X%4%zC2k*XTSORzhZeZ=vY(hCV*E!>?H*QG>!Dz0r zH!AC&9gwUuPMtcH|Ct4aw$TI+?tn(OHa5$p;D=rmS|6OL=iSBBg{o%X-P>*bR^4H zH4+gA@Ihyzye%qR8$6)`!Q5c2gWBDDg#`r#SKnUPio@Y>iam-ixZQ4F0Q7Dc?xf;inF_8S%={ z(2&PwV$x#|Lj=roLDZ9fd}Mfdn9w2PAN((ryFy$-2_ZH2$gnzlODdICgh-~IoQsPm zk;!D3wo2ow)e*Rok*TR^u;MVEFOf*Fn8UP+i#M4SsaIg`?$ZFbR_SQn`1OFU_V#wg zzS;DjZ+Rgz=Ci9RBf`SM2oKl|Bf7s5-K!Lpm6eIf^iBIfS^?(gt8rUR+3b$wZ(mtL z$}oaFUdNehI9Z1JtzzOWjE%%%vD(Ya;`k`3lA6B1e(YrgUN9HW zW!-&}o#5E~H#7Q~)LvD^iNLoQb>55ivMV(t|d3m`a5?Qn<<~XH0 zP6>s=-g(l3FX)kV`-%;(xE?4f8Uls!LjBrX6^W0%d9i;x4tc}QCzmw{3yKO14Aigl zES5oJq~6H(aT-(GW7Sp1E^~Dzr%5LjhHTO+uj%!yhf{oy9rfZ=R##V()J`0oZp3rk z&1+G=gJvl1dKbR4lta37{LSv2}_J70fAUx%+1X(7G{`# zc$u4Ht*o(@+jA@iLyn!a`=0 zENIA~bSeoQL9&X9ib6ZliLq1?jS+(;Qs}Y4!E^?ZPDMw?22sL@1e)1@J4rONU-0NK eDj|dvgSN0lfxS&;pXPy75Eo~6r{<%9sec1MJgs2> literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..16e96e7e68b7ed6ce148638f6570def99880cf03 GIT binary patch literal 1774 zcmZ|Pdo~LDq$*uF2OH7X2Sfn>I8MjIM)L;Al@qW&Ee&64D&hNQ>zvuS|gUluMGr5tiLb*^H|n#Rf2Wnj7vz)vd2KBJVXE!T>#xFREAajWWg~U!HG}{I=Sq6gqKAae`&ZMi z7^kWL#m@SVdi26yPtEx_&YJ)a(cj#T4^OUr-G-F32A75YJ%$l0|`ugv> zK+>BDUu{Jg~8hSzw0C{+#P^kCs7bxu#^?pXz z)#&JGXykzl7K?@M%LakYZ-4H~%gxP&MTr^l@$s@PKPr_zKC^5|EEcDV5wGyq3;N|-i3 zP~ubbQfpxFrm#Bw2~!}A)Q=F|Sd__R2X!`=LWp2xHs`mFjt*poY8)g%`=D7sU|^v0 zu($VXuoqmjTi(Lb(vr3~V`6G*>YeJza1|XS2kN@YU@-b^;CgvWJW6NMPg|2IbZnsw z+pH*##bV{R%Q)6nR#xT2`7Q2jCQSjd{8%w(hl?bW$u&9%H;*V1i3FVu{K3`L^&mg` zN>^)ZtHDE33c&nKZvpufmnP7&@83U?^K=HnVAcUan7>?yh$-XYDu#AlS!5_XCN(v6 zeEpk=xtG>Lyw#S(>u?>;%3Taj^XtATMg$=4I;i~ko8Pq?qW(8Y2XNVem4^YxjUQ9e zfp<3)a=AjGfZwTESzca-@_m}Z8l)wQe}32@;ak=O&N@Qbdwr7&0P^8P1ghl4z+qjH z@^-F;`B}ipwRLe*5-q%V+C- zeMNwjsPcr9_8_u*wBb+k&iK$udt)C>FuiJm>qEcqj-3D{Z1of&jxB$8QBqk|RRwpC z;_-MN0}zXfE!E_Ugd(Km^R3Xx2VvZpm~((2^bIHyf`K&#hBTYAV1>`qQZpn8ZZAeg z2G1RGnV)Q10S2zzGU{GCwEpDL=1v~~C&c;t`|CKm`~obbzxustc4+qLK9I!89an$B zy~jB@Ciy;do4uT)OYo8F0k+o0)z)t%pWn8c4O(6sg??UL6^TT9`{rOj;n6t=y*xk6 zj9vB}cKZx4;KGVfT?*=YKz^joSev!mbl-38DG~~WYARJNq5hSU-}y<cYxI@D2Z;gwZ*5(6#}Ew)=Gu+daZ z&dB&9w#6vOj$xd^WhamCldtOn8v5VvY;SL0-AzdjXZYJ=Zhk~u$+#+BZD&HcL8X1PKQ^MuvW@!QAnvtP=`P@C9{Go-Z2RT-j9OA~o_F)u3M;F{wB-8qG*#QPBxhY*JDZ8lOl`W>GKkxM(snF_}V1Hyv l)JqQMLeO!n7&?`UcEX~-+-1GS + + + + + 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 0000000000000000000000000000000000000000..7bfac576852e057935c24c4ebadf811a616c012f GIT binary patch literal 1937 zcmZ|Qdo+~m8UXNd8yOPA30vDGYRhSwG46vfsVx;k*x2qf?w6S{<5uQ#$+f7|Ld__I zjffd{vd6e>#IU-^Mj5mbLP!Yb)nDiQaeiw(-}9|!t><~yx8C<%Uz)A;uZIyoAz(1r z;ft0Qb|9-9gcKY+)jpLpfCTrx^sB}G4`R-neQyX>$k<})KPJxCWD_0*e z7;I&~%DPSW1=k?TAIltN#Akwd_~;~aq|@Wi@;8CH)ve=WV`Jj-5^4Z6+R9?F1ak*s zUbyqtXV*?3(}XA2ZU6%4=bfFM798Gkd!pzO*j)`xP0de>A7>bQhwcpHes^_sRm4=3 zm6w+b)<^y`J3Gs>wk^P%K7CrEF`8XcQUX6D@sh{miNYjPI+}!qg2QA)u9b7STs+60 z@$lh8oYBqENxrnAqN4a;zLfxECWS;I$pY{v4YgJqEBuZWsEfsBvnix>WjN1VLlz;B z*V@$7q_DCv(AU?86BU}86uQ%=`E6`}UZn zi#&St)9nlAt}^K@V9ZsASR;k=roWuD0yO&k9V*@grn8(cpUh4x{JJ?nWaky$>W*A~ z|Dx!Rw6v+IDer~V^|eWkca8JAr(P>xiXAi`xbR-RndkHQ=2vG@S-cLDzjZi|^a%hb zpAZxj)Zd)b5DA7Os#{uWYiosD<4`&MA0e0BncnPQAWK;V1qHFrE?qr6JwdwwV18>U ziN1O3LXotJc*mR<3)hCOO8gK zKGREM4Po(1OGlK?UiaK@-`T7Kpx)Z*>T1u4LB0VFhr=$*Eg3h|*Sb``rRCORIbXk{r{xllx>y!kiB78eyg`?n z+U-n^xQ1*tU>16Y)I2&0Pi*HT=_@PW#1|N}87J2%-?)24Xz^jHz9}jpF(W-a9j0WX zB6TPiWogvY@ol}Vs;WvdYJYG3RjEyUfhw{`PR`ZE#YMhLMrLPwdmEOfjzXaZ;-YB- zrX&67hp03pk!qJbJEMLyql+`qGP5{57!q!KGP@U+9Y7+HRt>a~RrF;gQoUe%UC>CC zKt+WR0NLf`=jRWe6(5kN>~Cu^9!KMjDPD5S?clFQ8Jm@H86h#7rsZQlW6lx$6*W zacQ@aygtm58$7cI(Bz@z%U?*be7>}djEscssbp^uc`wRx-Sh9IdJk3gHj@w0&mNG*e zTUeL|ID>-+-zBK3nx$kCBiz{R{vu{WlOkLDw;wOxgiVigK|2Z!^=8;wI{xK;Au>3tF5ga-`EHaBb+mQRUMfI>)%ulj&5pcX;IA0D|`0rnXg1AT)$yuWhI<5VRHQV zac=Vj(Zn+#4O3cEGY+h2bE4H$3rb5%Q_4_E$yfedSbof8GD8Mt;^b1hRsrbohv9z} zstF!ZRUsRatgg3ZWo7XQ6Np5ZliHV8vV+~>_il@Imhc~O! zcJ#^)*p(a2-+0<5ECsuG-rAxH@0su) DO2~?n literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..08de0655857055dc63e415d69c2a2147bd0e5665 GIT binary patch literal 1975 zcmZ{lX*3(!7RQqq6KX1@b#Dcwv`DBDRL#V!xXM)((ugTi5?Z}QP;*r}Q}a|hsOzd( z%GK6Tbwj;0`jEs_+Nz@d)XYIB2-fNw+&psJ$E_VA6hY%15WS>3O z+8roz&!mLGs`~k16A#()QY5$i(%iv4M}ePO5foG}+Ih(M7)Ep4-) z5QIkCTU&Srb7p)TojiPH{VIh<|LygsTgARXQBkNO{LzTzG#-(w0o7OUqH*a8N8jcu zoJ0q_x`T%7m!n!zgXv6xq^(RS0w(Qf1uu3F57R`p8)Ayah$!}fM;*=ThO-<>#M*gN z;$p+v%r;+W-BJ3-lYQ$fsjX^xGU;HpttzhJ#np{(YJb)Zak*T{%cqV5Xg&3fjg8%J zj-6qppEysWH@wzSlLALTE6=S^2vmnBkP|0G~3=G%<~!QRlU%JTAZf!w0jON$)S z&QA~W^Yg_DO5H;O0|Qm)x4!ZIP8Knz{;2V7ihx3LdZxBvumYD!UcO-^fHr;_a2S&o zr>y1lgcS-ce8ylfex+k40r4;>)v+Vi!^_J{`0CDlRLeOtW+Yj3-Tjd#V(y1)(WzLN zwT)j#{Pw0K5=W|OYim%dtE;O(vcPLVcn|CIn>TM9kf(ZTUDm zJDXzz`5>>V$^vw9h-oh;aLml~-oCy*Xk*iTKq9+#-X>9dx6T2A3vVlVdW}BJ=Z&70)U?OKO&PsTZp(N*WD8q8X8I)t{Mg;-ag7KGX3M8 zPe&WEY4mI75_$t)tz@T;3&{|?KQJ&cF%iIZ($Q&r{`@(_*O$zF5hvE3z#SVK6Aup; z2cW;p><!DV(909YI+H;1z=fO~ZVP2r0xvRPU@$s3I4IR*YB0*<@sPN>Qwcj; z8#hIf*Yli?jISqsacr$0?UP>$Ed2RN;56yaJfhAZiuN5Z}Zm{DP}}?>A=9y(9oIAPX&dAg)7dTZ=I~HtOV95 zhfx>|Cifsk$aQhfIYoAD@jaW(<~K4Y(0NYk>dt8?dkv+_^fBoSRU@L@FtP46UQc$( zQt-zdOteG!P;l<@Y9lMOLHHjDoepoo@NjxP<=oPSWvN@Q;BiF##!$Ik&dB$auHN2W zY|t-+XBtzW8Kj_a?h8{WgtcnDMbk=%gExjy)n1 zB=(NiYom}dN;1eF=p2+f^T1XWo~q~L;NXCu7jeLC3Rioo0bYFlu=>k_d=`W$q3QKP zURfD*wnTy1?$X4|G^gbg7_9hACX~-V!t}Vh`MkNgx%X9)q*D4zj*q5tVuf$9V6&u| zI~0}H@cTE(@0VeT=8zvN(lc{0C~a-+$l6i?>bH2q&wJ4p}avQsN6cXqb}$02Og&}j&j>G>s$$| ztZA@}H!q@v+CO7G%r4G+`&J%xz8!ZZi^FqDJ|_35hjDkT7}j!1RaI5M?O4aS@@A?8 za=@0c^P!%|9C2T{l!CQ>S9spFpGP)yjzcIPibnZe+5GXz1F13h<@3TNC@I6Q)%r@Z z%FTo;-DI_Dx9N``Kf;WRz-VK1FmFg9m<2|Z)VhA|dEQNU3BBLG|M<}=aB4Yz{<~U( zjh7>IhM-X`E>*+7Zkuxb#ITjK{}h^tD2P`imJQ!jRk=&&CknG9Jue>=uh7`!EJ9_W z>v~j7yIFQk?M>~^F}_*{#M&@2S$HskbHlEwfSJM1S=V1BPSx%jZz-J}z;O`+U!}oM zq(-&zrd|l35{&Ut1RxMSw63l;T2C8&(oDE9vc z$ZG_pfdK!#3X~Y4abN(2pdB3*0tpHUCm5qps9-XQfC?k%M@B}XtjYLj5+Q<0LE*#6 z(HAa|sdzF8bul_HJOm#Qq5a=ZLWK5j9;gsf0FgjJ=^5yN+*3jhTc8xg-p0lHnI$gi EKN^gi#{d8T literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ac73b8eebd521bcb8fe5e2d991df0d5c48f9536d GIT binary patch literal 1873 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 W4aS~fF + + + + + 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 0000000000000000000000000000000000000000..dddaea9e4f88121a09589ff3c70c65b5e9d0339e GIT binary patch literal 2055 zcmZ|Qdpy(K9{}(fCYMo&E@X2lUCaz~8$}CEq07^zdbw=2xy@Y06l2o!r1Y>7>XD^# zry?bLYV0WyGI{0NB$sC7TDc_TIrZ1?_s8>oz0UXZeVy0$bI$jB&iS5m(c9AvuChf1 z0)fB}y5o<6i1=C7!@$+(Q_&L;U}O(B{Ms+dq{V(vqa5Mx6AhyKuj1Mq>h!ZRHo}<> zBH~xM@cm{UNPT$_?|eLHK58C=SOs@T^7=EKT$~hn#nh#6lc+|=bX8>`F)gxgxuaDIy%V&; z2%qk^i*C2Gj26$lPQ5-O@>9vVdt$Hz`NKy(x6KIP{`01@vs0m>Vs2q!0g9Cj4-Xsq zSDOJwjRznd9g8y`>NOM;Hv)28cVkWcWcd@si^;32F9B||6%L0> zh=ZyA)4Cgr#p=8X;_prRp~q`|@%;Jo#ANxgtJ5>}u~YA?{X;_;48~N?=4rL6a+llQ zkS&bEhY!OCWjUFdnP0W^Dj#)rb#*Du%>~kEG^l#hD9`~O*41SLh@GWEp-_Kz!IMBB zyi2+1t&~QMii*;FGcT3NWYKU9xbV!^(ZdMGJO$x7Xn9wNqKYa5n+tdMGSJu8S9ICW z?5~a7Pr9wO1B}ry_v1&gSnQdf@6X|I@;KXfuvsh?#Mf6Bb-Gs6Vy74T^u73#payGc zX<4n*Zt*O_R!{wp@iA}E?jNP)M#8*X)zw*m8U<|yM%40knl4>@)9wX2C8ZGPKcWN! zuSuvKv9eZ#!C;uzqeU;tRh6r5Zmqy(TEdDr&wPlK1^MM@L5=J9@&>owwsGuCE`^{$NpE9kC%Glm;^;+G@1 z9k#%_iu;~kUS6sWgHsZ>jBSq4if(~GU^mUa@~W+^?N5$OmA`eXD$pNGBwoZD$~BO0 z9NI29IQ_QR>(;mVYElvK?X6Xl9Be<3QaKd=vWjvWSR7r1#nJeKWQ>l5v%l8PCwILOylt; zdLH;GHIN0TQS=-HJYCEq$U~t}Zf$K#OACS9Xc#g!(PRAn5}sT|QY+~yFz}lk?4?Tj zQ0ekvYdo?vKY~r%l|>kw8&}fUhVxG|$eV7-+D-gM*>_yK6j^XI3GhE7C@wBmB9Rat ziz7{CWo5fWL6b8xGfIIEc|6{Fg#Fn?M3d*Fc(?RT>rgKV^MY0M_fzHQM<>B*mn}(G zRvuPYSNAQ>&-eB9`GoIHqsB+XW=qU%)p>+hYLmJF0aSoX$jZ*nhOyZ6z`#I=UwwK; zMuuvuhjAS+`SgYJ^#aQ}j?raa*4NLUKX2IPx6A0%p*M1x;{yxYzvuKUeU-J#TUclq zI3=u`Tkx$*Si<;Y;J_3|Pj=^0RDAk#lyU8s=Fj$AI@!)gBylh?F;OJ>CN6!EdJH97 zZ@F5BHzWcGY&O~k`KZPfcsOI_UUs|`;2zS^)6;vMbUf)a=Gn)nxO*7k@pqA@@W>rg7vN_tTrLt% zZm}zK7~?=*BKy^*)MVvVQj>@Hdnbgx4`e!S*OoeppIp*AzamGZBw>GimkcGz`Ox4C zHG6iVz{zI9IzVCt2C%61lqf0)5DePF!VHZuLt7uWu&}qn+FSm-w@0ICF#`_&m%v~K z2Gh>`cY>}d?E*;f``JTuEZv?Q5KT3Ui3*0$g2Slx=H})>Oa|3Flxh_j8EKAZQeqg? za8|TAC5#yp7|3K%m<;oX7;;!JB_Q1Fe=DisX1^UX4`u|=snO;bTNG&fwDlY~ogt8e M2R!ljUHs4e3yKS_nE(I) literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f901971df438593398a6e6ba782755eaef8a8a37 GIT binary patch literal 2033 zcmZ{ldpy+H8^_1cBu48}X=%$Utw=+}Fm7vyh$bW>xs5TyWSB8GjKPpytg&S`sU^{_ zGK<_wVMHjmq|3U*Fmf4T+;YGFj{f@n{`kFLujl*uzMj{4&N;8=InO!C&X}_ba%yrA z2t>ib9_;Cpo9!BZeGf5)@v?XT?dSQY}$9;*FiI#BzsX4evIx#MI}e+&ew z@zoO7vhIS=Vh8k(Zb1X1m%Z)(@IAQQe!j2kR&VdQqJ2gx7vV~M2UeAqq;xPZI%G5nr7USJ37+eY5sbrl+R7iL2LR zOop?TO*^v3mb2;E*RhS9U0W^*Ar(@Y3N16Pf)agmb8~nP`8xo&0cWI^%I#R*+FW1e zb_71{n<^Bz{qru!i0h`NqM{-#=?NQYPCIH%CWnQE87S^&&JMn~rcQbIx%)cga>x^7 z6B83@ym)@BKVM%0 zfuJ?W*sGwR5R%nkll0r0*49?&3->bzcvD_tRemHqoXeYxS|=kSv}Tn?N{xy-E6J#yZFH2vyS4 z+}tdC;|6u&U;f2<7~jpa$X$L!{5)cAXqU5lg+L&HAB4*TB)2kJ{PB4FM`l5R?{m&- zeeXEy0wA&OP(w;*XXm9~BDc&@C{!lS(=&-NJ5wE=3V`FwnJgCT^y?1~zXiYz^{HzM z;~%_=HaDLDyeuwc|DBhYXTTH9EV63~ITXrH(i(Wb85BB{svfI zY=%#9cX`ZgTm~d14^$ypH0K9pv*EC7aqFCzfgmHb%QYz}#PW}?)5|@kg_ZQg^z{Xj zpPwH$dZ1Salm=d2HbkrRD$Hte^YQU{LlH^HbUNM8N(v_usno3?_n6pFV->`~U@A)M&4B_9u)N6cFH%sH1bgKcbV>Yu{W9M2q#v8ps*O&UIGcf7AAYB>~# zTG<#<9HicMI{u*;b?Sg)p6iK{=qQkEV-%%SSjC(?fX#mJW*=>J01T&%LZynkCkaiT zKBWQbmyqHpHk)muQ8#%fGc$9Y2^|_P07xaHbDgz&^j4Op7AL!l>7yb+C2Okp46E?n z$mr;(R9YGdz_mXHlF9Wrnb9^XLMqyce;!Hg5xW4~b9@qiZNe3r! zzU>_MW&83N?xnK5138_^0JbJxicAH=8^H01?nTfVFWx2oXoN8W|rxl7R4KOu7I=N^6-=L!VV)6=2GN^2i-LgqF& z%348)xxmtCPiwvt=rx#}oV~Pdf!0|xUt?Zf;ZNVUjRiS5wY9aen<8m#3J?i~t;i zV1}m=fIv>`8yM*6pVreq<7QxBW@Kz;xbttOuTNwSp#CQygc3j^M*jZ*Rc&G-2=Lum zfzApv^T*K%dQ2J#LL`w1W(Wi#h!R3T1QU$FTZBMU@XQcGD1(l`lPS!A015+72|-Yq u{$vs!7pnK)PC}^OrHcqs2riI7N1Qf21?I+G>emBHK^$x`=tnkw@&5tmtj{L^ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e78d18cb51d356b4e032d36f1ce44f18041d00ee GIT binary patch literal 1677 zcmZ|PeKgZ+902g&Hs*cY(nw;x+!C?1G#bVPu7m(Q? zV}8W(h4KmrG7Ji&kVE6ufc#^^!otv)VziBo4T4OT0PpmZ2x|o**Eu1n>N9uZz?J( zme1Rde>h)LQ+79geaYl zcRpEV6^-i!pr}@B02&%fzy0ECX3opJrlzW@D#z;3;Gm!&Xk}rDB2+ypz8r~@5j;FR zV4wUs9F9VtvpA2kvJi44oh~RSfI0d)I668asz{sdQAYHAqO7belvD92kWDX@$z+ox z*w7H6tdFYa5T>iHM%~@rrh-GwDwXPeGh)vk zJjT^l9j;si9l9ZV_I+xP9Zs4R?%}SR@ji)0#Z%DE>6BwDq6( z$PNkjx!K{ee&qS{=kSAfN=r*^U)?|R=+UF#=tDARc4bb;Y3BG5=|`IZ)XViv?d|!% z8NQSZ9Y4G6Ldd+i0TNWStN-L5OYKpoIuFQw^?EY{I82-+P=f!MZV5L=-4=zbwG{@+4(*pwoyU-?r*?V|nD@mwx@kyV1)^Nn=>({SKr${7*o7BuW|A+?`iC8BY z&ZT9F8Rqafe4{LSnOr^&q^+SZuAED2bf)J%;N4X!l@P&WI!vJL00o2R<}Lyz2A=Jr zoAxI75Q#*1e?RE{mh6#{!NI}Z#L>A0xm>;?I$@iev}gKdUo%{YR2^Oh`t@<9HqD`W zsHj`AXw8)+GTAC%F6qOX@)EM_Qf+N*9@^=O1)NN!QjwTq_2JKIIfB-3nQjg!-D0tZ z_NZ{JwQ0RYt2q8`h;efBPk^6@I9z^EtY27IAZ3&`8O*X*msAEnLT)bCPs+qDl=WOk!*b6C?pu&){5THl(El&6abg_@ z3nIUtkebdW9*9Y0x(ZV`5Q~$z=g literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..525915d66901c5df89375f783de04bc8ceef2172 GIT binary patch literal 1457 zcmZ|Pc{G%J7zgl~#yTRo5|b-inwBv`LSq{mvafTIgJz$sgBi4_W{S|9G9}?MA;*%P zQ(SS&l8aL&my2XcWS2>98B6B=^w+(A+|N1B`+d)I&htLM^Pcm*sh;j<6yXRs1OicX za>RRs)ZQs&8F1BGC~g2DLv}fXm;4~_zcvaw@==awSs)#MltXuz^-eP`%9a6A`$r{j z*SG&IvfyL@g`S0f*wM_%>)Ot`;=0CsFJEO0^q8W`E%K)zOM&}jN{X=S>$e7-i&?YTt2V36 z0v6up8rSCjJ@Nt1@Q3mzKQ}Nh12~gs06aH09DroMURhZ&;&;C!*Q#$?+J~4R6mebw zmA(qimj=ei$Cc*TRshF)xVN{r<%Qr;G8)=vp&1+)7$~(RaRnfZ$L;Oyr?+=!yb1%j zYoe0k;$n^&b1AOrX9!;RZmFD-xrN@YhI$!USy?Wg93LN_Y16unJQfxj8oKNJB@&4Q zy|CR3&a|;tv&D73va+C{Kxg8MafWk|mWMd@Vd`{Dqh`Jv3*h*UjE#+`=~1b9}@&OtZ<5vDmk@pG9XF11gzwh4VhKX>k29>1+S zpnf>PI&V+SNH=3$98IUw4X%mG%XvJW!l00_FbCKwY0HQc^Z?v9<7`)hBxUyt-!Bn~ zL{8Ai+O%$tqrM7f$imXn^7R7pEwn&+IMChW_uy(j^AEar{g11`4qCfKsW z<^bZ+A~shee<+0KO>+4g& zc})Wy4>AsByH*b^Leo>_Z!q5{tkM&mUCPVK$~X@mtOJt=8K;uAoKv4Z;g9CK#;w-+ z)xgwE5ak1*(#O?eEVupWQmhX8(z7tb8lo(wlwgqFE#-fF5x|{2OQBGvrW6?74Bul% zek&!Ixb-Kcu|$1Yfx$jLKCrjp`dqtyYHC+rdfamoT+hS}jxjypG%(hn)zWgBHb<|@ z{A1F{*uH;0%3M>XZ{8EBO3p*0Dk~}~sMiL5y#pNfLR@~gwKDMG8g#B(%TJ_m-v#`H z4zcb1*;EpnhNZ;NKtPN!Mn))%F$!~%U}S_fF~y$PxyNEK^w@EW{|rPhsUh@>|39!F zNlyj?!8;pRaSSY(#G;{MV?rSGkZ>9njYgkmM$phPx# literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..10ec880765059bec67a19156bc5df1bb57991b9e GIT binary patch literal 1597 zcmZ|PdpMJO902fl!!VcJ>d29HSWdUKVJ(_iQOaX!!U{e9o(`#j(G`#$gYeO{rrmzxIC00}{m zhKDh{!@LxioSba%d?kg&VrhN) zdPXD?6>#!8u^0?S$;i+AnCd`Z_5#sH9* z4Nm09G*V4XO&0~(i`!op6%`qw^gn;$KX|O&nANN2P~54US1uF^RZ({J)z#Ir)+!^c z)u)0nhu_X7+kYB!Lusj?MGJnFebIp6fUKdRL7f^|{&$R}0-Q%!1e!u5v%oIYuSCh-ip9? z=S|L1w}iMn*J0J&uc@giFezg22+Bat@7#PSDvATNC0RzQi>yaV*%Rn|`4t|M_jg8%gfIT?W{~^&%uE}4rv9hv4@E33d0zv&& zMUG8ewHI(Q(;B}W>=UNr;p5|@%b9EZa%W=gebooaF6NTQG#>iGvANUNpAv%i?c1l# zioaV`RRw1-@YdGWt<3Ze{p`+T8WZzZ3{7Y1Dd_l;oE#_i@^Cf|R-5N(nrlWEw7+E8 zK&M>h1nw$|smtbNWdtKpYvINLZXIQZ$O+0Kzm31)eV~7MczDhDICzmQ0RaI8(&8<3 zMFIH`J1He4#ZC?%A3uvY=^2UBS1(cDQ=-3N!v-ZI0;+k9OixqO708!v6b1xhPIhqUO2MbDRx&i|M;y5Dif!&^VIBi^lDlVY zPV1D%inD2b-EQvgP-E3BlBI=(g@SjU@7D9Cm;AY`I`lx9?{)PvPx09oRm7!W?1Vx> z0-7cs`+8JiP)8y$kvZ+KzRx#(?dfgY9aDW^*R`OKkdQ`4i?pj?KUL1D&HZW()ewG? zSJBM?Ame=rz^Je%F23Sd!`jSdl6Zg8;`~6}x)C{Hb-WFhTzo+oWv;G@GuSylfaIKBBL2JTPzk!XU5U6 zu{3;qd_0!Oj7W&19p-Yd5e#MmmCEEsFypYSgm6Z5MA%`>zl*fP7(X9ubX-^zjf1t^ W0d8%t + + + + + 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 0000000000000000000000000000000000000000..60c626b3edaa63de0fcc78c40dc4f4e840c95d5f GIT binary patch literal 1691 zcmZ{keN>Wn6vsjHt+I@)Ewv;{=2QY-=88zx&*KpYzKLCk5Ls zcUTUAKy3Gh;3+`iAI#1YJh!~L-UP&w85WFR`iKq9qy`=vLC9et(2$Q7)RpA_!Fg1$ zJ02+fqlxFPltCaCk$dsGsR_@95BH&2M?O7K(~&HDi>dv=7P%}h2!W70TnfRi$RTc} z<Pk! z+k0C!vTIz}w_|+1O>7!ptwR%j4|U)sQYVyK%ms%T_j^;V?12#->+Z4hEgbRMn^}Xq6hj3x(ISPe|z)IKL-Z~t)pW~ ziO98ItqM3ZGn12(V}`5T;OOXRe((7OKs;PTf0C5651=%Sr!=YFXBSunDldm@h2bhU zZrHE^Dv{o(si`>uh5D)%78d*r6P0&kF%XmK#2xKYT7eb9%?*h}TDqdj02VMrY5z+AVY7t*5w%1r zl};KmO{ONmBR|dG?SNcs_$ZTA35K}NaPli`S#Re?@;;ZSU|DHNNr~A^HW=Qrmm^)( zd@m59fbyT&uV263te##algY#Zi?vI0b8`-~7(SQFWh`X+KxMKQf|gs6F)=ZP>WNng z)l@eNqtO!Z{Rnb@R#w(dmbd`9>cJa8|Jxl-L6wiKX&&Iiq=g6(hT|(0w6CL38~~z0 zT1)gctF~wP`S~l9DKRt}E!HF}*J_UWZR+cPThar%*Hma5VHG!S^z`)XQw~4XYPBN; zB4vLu=~5trUk|$cGOd*)8{+wTGqC>t0RaK!$ND0n2i=ECqxI9HYPCB0`qx61BC=Mk zvN;=mqQSbkZEKb|DV)k=G7Uza4*9ODpqsU^8AWlDsHhj1OQC-xDjZxroIp=z)S6p>&bQjk z)AJn&<>(gX*(9~*;&!rL)uh+!SuZ_iMx37uVt?;?H1_J%E1d{JHlR$rw85n<{{6a1 z0^(w>rth^{rBbn;rlu|h$eS(mA)BkHZbfRxwAR9cf`adl5-$*u(uR49bGuH#w?`D7 z4gZl+O=Z~OZ1OgZIHd0qoufJVwXg7V&-QQCq>P9}cFx}saDh4W`T-$X+0|t*7%;fc zBAKZi4hNa#l8XnMDfu0P6t=&CuXz#zb#b_3=CMg z+OGo;Gk+uu$jI*j7gei=583S?Mmqc3t-GHQ)Ty^wW(K`>Q2Ow(stM2QxGyO(Opm^M z_s;j1+nS-FA)DxEyJPdz-x8n1!kytO&8&NSLte)Dq^%XlEXQi5rlx%MN3FznVt%5m zxlQVR5@73fI5joZ^BQ%rEpSTeC$e``Jk86?vpMQE-x}z;^)J$mDz>37|N3fV;8b-q z)d!2kF2@rH!NI|ID!-xq93gclvZ`h0eOop;6Tdo6huDpKoEvB$3JF;zdM6Vq&7( zWa%|mcX#*sEp_)7c?;7`?MqOn0}WO$%$q#Hb?cH&pryw#(%D#68XE}23*+gD!g!%D zUr;?gu|B?7?+@=-42F~OZ0COxlKF95&awYb_{5bX1_|^J6@*9Qu}p@Ljmk*lLO5I= z8w=)=z)xnQlh{6B;AlLbm66O&Nf)A7Jbp%896z1KPeuzem^?0vk%IcSlbwP(upiA$ cX2i3FXy0w%=;Kw}P@ocIFM))w3yjVA2blT~+5i9m literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7184e2c0d4ce100dcdb15970c4b9d002f7fc8f54 GIT binary patch literal 1567 zcmZ|Pdob+tVp6 zT1x4IdW&INQ`E?6b+%Te=}MJSlvqg2uKueSq$Z`3J%i$;6QSXU%EFEL-1s>3Q=x1m7=qOiW)#P;r%?6#_^ z(JEzPR?VulnbuP*(_;Bz5t3Vmt@N_UQrX1(@@)GTz4b4Zv_Vlm|LraRv2K1MIg&r8 z++UN{A?jI~+%@m6zIRObwrM-vO)=WCwzihpH5CyV8L9s2|Di>1fvTwN-Q?t?usgfIzn?0b zUR5X**W4)9mqA*xO#T79X@_xtO(zyYg6=n*VNBP^ww-ZJ%W}CK7Bwf8O3@i-%RO!G z0h=0Mip63V4+pHBogGyOE&b3OrUZma;S6Jffl~08))3-UA5q z%wGb6-rf^<w(_a9Z7g@@FcqeeY_|cbmKG>gnn2@>7Wwf3L}8 zGR(3(&9nCR59;jZTY$cv4ZhM-l)VFs{(g|zP)F&Tb9Z%h-GoNNg&u;_#lAri5fM58 z&u3<4*s9b{ep85pk)X^7g+d8cDzFLCd7gonpgm)~v%bC_+1ge=I=ei%b#Ecs+}s@2 zP&lp}4R0Bpy-04as;bgVS1yl_kE^BsRdfITeVtaZi<_HU-s_s6gXxV;mjd_~9_r7h zr>3Q)y|DD_PAn}cDPh|9l{az$!}&8g<~hhaZx+n}!ksBR?8eZG&kjS#`fke$FDjME8W|bP4_xQ0;D1-@muN@$J2NOg5XX)7t(D(2?t~-%v2bT09KiGGlU4qoTg4scBojuRVZtmzQhH z(n!Ta#%jL1or@NL0LIG7;_&cr;Pi}03u9OnWPj`v;*gb9huu|Br?XuJxOkvztho2> z!owv0Yt_N`MhKc1{mcCQFKivH3I3%pcIj#~9IvX2hWAZqWIxK^Pf@7AZaLhnisNuN z`swNO$~8Wy{?O1+YDuKnVq$NkQLXYYodvAUZY0G!vkco>6sn~C`u}(N3I2;W6>u3I43V9W0g~GbHggpp0T~9%N zRDU1XTyahZ+ZcwlKoVANB>al94099nIAB6|aD*ylh literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d951846e9fb50f4b4c703c3dadb9b9a67108d7eb GIT binary patch literal 1711 zcmZ|PeN>WH7y$4W3X{|YnrKebX{i|kT3Vxx(19OJiIt&s94-(973D*5Hb0!IZUkkWr=)FoP6@9Fc+?@-Bk95=d_+ zWukyMkX_!znb()fAPA8ZN(qSI>mDEJ!C(H|F^d+e=XGlYf?DjI?L-T)5Lt)xK~G># z6|Qx3)4sVA^piJss3GYT0_mDm_R#!XhQqb6u!4Nw!-p3Va$jNM=(^dNujBROrGMN^ zH ze|-wXxX1^ZZr{Fb`BU9tCX)%@v}tQzr}6lm7Bm_S-m)qv!eOyk$U0O2peD53sbB`K73NG)Y!QpY8zq zC%4{!`kH>LV%84G@84={Y}`T=pAMzbXmC>2Zin0;d9O!xbMx?n2M=JBAYV&0G^;l) zE-u2i_6`gT*b??DOG-+R4bgExN3RFQ&eqlz=1fA(+C2Hik`D_Go)RI8_fjRkA7Xci z&#Kjxm6aci^%R4X18#ln<>l}1U*u$p&RDJPhil$M@O|x3r1=di|E5YY|?bC3TrhRLz0=06Da4WMsr~x$4ZrJZBRiXX!N> z4Ky-(1dI7}$ry7fIWaMD>DF>o`)FPEAuBt}%M8!W;MbVj6R=*bt>xm5g0O+ma5h2PxM*ub!KmhnH5K?gP|aDD{2sB zZf#>@qcxq`P~7wQg~7D4FUMRfMgrr#z2;q*jDrwNeZSmzI<1ewNmC-IsCs*T^ga0c zrC&(!kZr^=dS?ry%Zl<0qtoe&1`q2iz>V46IHaBRwQLp%?zwqe$(VzCe>>2ISvbUR z>MZOoDk{Q|u{gl&YB8bY_44wvTDc#E-`|BwFIDz-cXv;aT*GMbplIuTckKfd7wijZ zSJ>04;WR+8veMexN@{0=Rx3efwqCIR{qnE*v8n)bGI{hoD+U0c9-lkGc6F)qKJHfW zeuQUyLPCOKY3T$oSUsPiNr}Q`-ws>|aU=&G%H>HUlKg#X3$+1m^xV_c9eH-)O3PDx z3NvaiXh<^(g#!AZ#Xo#MC97%R_rQbiSD~lRPo5|vdwK8NxpQ4gQz5XHN7X>zUf(%% zbnGUg0`;w*L#~V_x@0s9otERSN&i9Q<(Gr}C^%Zc1tb6=;8{@Ou zE)2Tm14Hyl)^}G2s;)CwbXsbqZUaLk+BM~@i{wl**+10R^KNP_M|4}kzkg#z5F4Vj z-m#lxPrH*P@_^}kEL*l90?aB$d};b<4y4OCiq48 z_z-vd6L-CRCK3p|RNcP+ED$Eg3V7-NzrfCucLpqAy*)uHizBj+Nx9ys5&^^$Byx#( zJf5E{^hOq@@69t@ON#6gS + + + + + 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 0000000000000000000000000000000000000000..5aef679758565810feadc633668822cf1476bc21 GIT binary patch literal 1696 zcmZ|Pc~DbF7y$4`2$5rg6fG!HK>>wI2muV3AO;G`5u(*_S%?IZ2$(}5ksu&}s2GA& zN=1%Hhze8`6gfmiD=_|cZ^#JJ6JM0^l0HW{LwzKn)$8zV< z!=490wEWsKKT9q^kj?==Z%=Z}(3`L>baaIIasR^pxC&x@404t9%m%p3=C`$a1{r?# zp`TVf&q8j%{te-Sjin-tJ%eg=s^gX~#U`6rekLpD=gK&I-B^S~J!TlR|K6qdw35IC zQun>LYIn6{cF|2DUD8UkgK1cT`>kIh(AdJ>zP>&!AvGl>#oP^7R9sxFty~Zah1xA_ zSFR$pIcj7JtJqOy}iA` zuLf?`*4DO{$h@fW@$pX6pLxm2$@u9H^uWMCBy`x#JjVj=wqrBg)btRLu29t1*Kb|W z-Erc^4W&}aBwR6Hvt|th&-e&zHWE;tip4xY&`zxhwcoubgHjkudc4vfWa_W1}G@KtxY5n=@B;C+1uOCy}F%=DCh#! z77G~7m6er`5=WwH_Ff^we0=r+Eq4=50YcEZPMQ-Yph%tvV)t-zYAQ(8`8>8psZyyt zGy~hW2+*fflKfv9&LlM7*u9wXrBgx-`D1(P)}h zz@A@Q1e6BTZvsL>LQEC;{ylN^MKgxxhUXu@fu*OXcu1GT=~|bEL!K)WXXB3u-w)?K zoJ{oL>o0$;RcC*B3bYxO51QYDHHN1XEF)i9S-GB^G2uQ4{h}H(N&dhsIGSkTar*Zt z%=ApOmzNhz(K{ttESnjXcU{Y6HR`rpY7)1sH>gmsZ}n@5=^PGcW#b(j9*@_~5Q>ak z*mobxGvr`1@hjn_d~1t?>-6-H0P)0_;anl1Jw^i1JRw($ULQzw!komkvbM%zu_n4J zyMe^r;g-HcA`vbjjbQJmPJu(7PdzT0V^bVp?%27x)z>LK;5XFH&7}iGiuA%D(3Snu z0S=SNgew=?+uMH_e#?_T_JME+Q~huCPiAZ%k;@GLBDV0ntCN${NYS+zmmZ*{@A`J2 zxqDHQ9#$6DfgCb&3;dxS-4n$6RTz>bkPWp~Gc zG`t3_UaBTCuik6`cdiZBCzMO0a_P9}csdA>lOqO$a&$sDZY5(dI2SC=dHEgZ=*Zv= z;r}y%#i7MAlKy{!sVyTDOrR`hNH}^B7e!5=qj>SL5F?gJ$Dz^a7!He$K16ppa^wiw zn-k4r(b?PtbTpI0qtQ6rXbuZ~m>0#2ji$0u|L&x-Q9=9Au`KFAdIEZz16caw{A~@$ O1o`=pysNz;GyVZev + + + + + 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 0000000000000000000000000000000000000000..79908d10d4ffd24e8c283d2d1c4f0de441eb0510 GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^tU$~rzyc&cCOI?%DW)WEcbEVFMOGW01@brxJR*yM zvQ&rUPlPUIt;;ZW|y+%+tj&gyVYhpa1{=*Rz=%IMTp+!AXGO{bUvn zoduCUfhtr>Tq8 + + + 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 0000000000000000000000000000000000000000..d9262efbf6297d4e3512c141b76bb471c9529181 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^tU$~rzyc&cCOI?%DW)WEcbEVFMOGW01@brxJR*yM zvQ&rUPlPUIt;;ZW|y+%+tj&gyVYhpa1{=*Rz=%IMTp+!AXGO{bUvn zoduCUfhtr>Tq8 + + + 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 0000000000000000000000000000000000000000..a2aad24b32996761bcb142b3d366b8ff1abbdff5 GIT binary patch literal 565 zcmV-50?Pe~P)2Q~Kqx`G3^T)W2OX?omx_ABPjS)~KA#-VxS- z0RcI4yJgiv4~YXtJG)r8rPJ>>Ht)Td>4K#{{J@EPAT9a*g%qD|i3c4%*nIi$Vfff| zdY-&)>6yZpPfcv-d|fZOJ;Kkt8vl4Z@rxg7GxhDKkTCs061YGO+8x;}{>v~i@02P#Uz1=Nb|2K4|2yGqbyM}}Zp;%s9Tu-Dqc@*E z4>v!_LBSS%D4M_<|^}`GT?dm+n|W4*WKCYZgb|@tLts6U@Gid$9iV@sE$8 z{N0E4uQiHUxD#z{W$PJtk?+3c=`F541DvLtN&Eb16;(gG_~C`;V72Qx3I6!8-EUS= zfg^Z-60NV;#52>mde^Udbm3}>Km4tBr`6ckFA?}32vOnn?6(vv00000NkvXXu0mjf DjiL)L literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..007f7b3578c9bec1a02a6c9d109eda3f82efdb3c GIT binary patch literal 4044 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5b67443c2cc7055daa19a0adc2b3b1df7dbc482f GIT binary patch literal 2260 zcmbVOdpOe#8{WpOXbs8njjR-*p;&7$#rm`Qu5oyKD)URF(vRKya%I zIENi=-l66$iJfeN*SozV;4lZvb0EgRA76J0i9f9^aiHygqV!euy&Y$F@CBE!o%WG` z2tKD-7`0=B-33Y)&&hi)lYUF4B{XL(CSn7KZ){|i)wPZ~FC z0?_;er5@z~T%_XND)VA)IS!HN!2_rEH&wzm&-5s;6e{ zg)BlDFjaewG136_qtA|yKh)#EuVxn_KQI6x+uw|KMCB72=S@gk@c_4iwP`G>;gQGb zGO-fDB`&v<<8=H0SIB^#)Hvu8sLJom-^4Cu^eFkALkZRfXVN`(=Oe8Eh`E>2cs0fu zH)-qYf+xNoBQf)Dg61IiXs|QgooKayA)DDgM(JQCGE__&~eo?Lg z61Al_^|h0u{V9)Rhyi}pcCd;lz1H+Yx76X*2%1-V&s`-!{&!3K&doK=|+@E-ZM zuT--U%-A5AF)vAy*b(4c!DV42O`T1lK6##9jC_p8#oyN-5A4+IG7Nk^wa>wX=joZ# zVuy-8EXvLZLU0=AQAslMHTVp=K6F0^pJvrMRKD?^c4P!@ozvc#P`Smn z`%ban9Bw!vMzzGgCMtTb$0MRXl2D)*g+jsNlj48v3|NR1&;EGZomLWIcv`$C5$?42 zS;PH)J1U|bmvB=$H<5j=R7!7nE%+$GtP$$$S371Y@BiC2x5W*Q)?i?KbjH*Pokj)P zA%%1LZ^xcuvQTY^s1M=W#V81@*|cA7@s%vpcbvQgU@;wGwT~n>$6ySk-{7O7i3z4 znOcwgdv%OD46~t6mCm|DJ0TzvD1>eiYspx@c+%Cg55P*Z|5bgP-+n1U#8;Kcj^sY%gL9#-qvAF5>Ield-)IY9`Khfx=e7)WX1;H zTzw)BaCG#*$H_H!k!&Ip_Y>$04K9QvArE{@iSh)v7I+l+n%HsizrnnR^T8@Zq}glb zVMo&OLc#5f^nUa;XkUcy7TGuT+Eq>}gJZ{$z`sh;?3hTOe>3A&`~CXst4)tEGLbYKN3fyM-68mAoqE z3shwa@(pT)K#a@~=B~DY%K*lSH!|W_9Ck%xeS}Q3H6C?{JEkmF7v}vd+(3ssf9hbP zExxP3TAx?Z=n=7X4Z&r%gyE8^)zf7X9 zigH-A+Ek;{4fG!;U9kOW0|Pw;$pXScU3qqa5W2>{f(HK&#Th6NO#MY%BgL$0=j8xd MSzN|3&Uq&M2h^-H!2kdN literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..969562b7bc7193a21a239fde1b78cabd32ca9b24 GIT binary patch literal 2318 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d04775d990599724a36e5cc0336deb6f091b4bb1 GIT binary patch literal 2086 zcmV+>2-)|EP)BfA`**JG(Q>vUGW|0;PZgOOZ*S)A`UM zv<8g`8a1RuV@*FaYGY|FHZ+KBtSzxLH8HkoOQkf5xCYzM7O1qAH#J;u8@v{lit@J0 z+wK6nJF_!$XYR}ChuJ&M&d$!xF1t+nPoCt=InO!g|DW^R^C}4;_ zz+|8ikSeSyfDYgsaL&-RbHnLh8qNrWBhfIh3ivuOeK;MLz;U1%c-_#omP#uPNkBLf zod!G)tSD8ks%ph;2_dj7YoOw0;QNNIogb{7iUout(eDBqfFM99RL7!4i&(s536rNx zVf^^<)YR5i#=aM+bc#!{7;UX>?BBbOci%fmI+gZ{^YY8#^T4A3O>^h6?#Ul<-F2TO;8O_t75s`^8RJ2abzD+eo2=u~+Iohc{p2Z5o;cwZ zZ!~mm?T`h8BhiO}7XcP5{31Vo`e{PJAY*G()Da?H4AXXqn-+;gg7rUKOH0d9ujoEQ z*R~b=4=5lUiQWKw0EFhvpU;M$|AN|@8X7|ZluF}dn6O>J<&;S>m1526)to%>2|yQc zlc8&83w_J21Dk{$VKEcwoBT|4ZY*$V!Bc&vV^mZj7M`~-YTzRuRNcdtZ}BQ9Etj&|2is2ek;F#9u<6A-Mc%kM06 z^L_OMq%8-ZEKwV(E6i?${vl*~2`g)3Ic~mzDn(Gf{~Eu7W!Z(<8R#z{<|VqiJ85jF z$8y}fkZK`q+sG0m;_<@l%g|rIB`=ZaPLQ!3GPX+X3CXNeEZ_?C7trA)VjUNl zK5G_!MXqZ6dvJvy*3s_$%#hn&_gx1JU5f+%1vq}J1;-UwuA6V5+IIZd5s#{F=$e4i z=YfO3oR5zl!4(keF$wq-l3BZi>$Sy4NB`p`4|s`E0uBJ*I@flFcy||))WFypwd!GX z@oX#ISFU(J^8!k3=Kc;?uIqAO&u(nTC6%>?bWj-$+rMYG$1efAGoS!N*V=(M0rv0N zg=O0$vm<+O8LFkzCWrRD?NR)Lp=-%HRK?G1vn~D?p;V3)4(fQ!}*N=iwlePVvUeFY&K;_IX(cft7}? zmE2JdCg3pSV)4S6Q%s*dcf^Pm!*Ogr)HQZ&-ArdJzbSqnSYhZ|dZ2oP31}g=aSEJk zJw2d+){~zg%M!uR7^Dhcm|R@qU7cKRzsUL4)945G67TB#v>1K~tT%KmTdtk50t{WV z!;$C_VByC{kMNbH%S!q+Z~7HyPo1oYcm+5NtTA+LZzax^Jo3E-EHt!tIdQConN9si zA>EVgU#oIhKpU_R_>G}!?+>MNB?2}8_X{DWHUI9{tljt=iqf~*q$yLl9BT*Afz=iE zEr5%_Swq)`ec@E;6Vr0wF95gQyNYEi@9R^(v-wr_{OJvVc3|?=5E?2fdS)?n?XSQe z0p5D^bzXb%Ijrob-`31I`LLPN~L?*a&CH@{$h)6lgoS4(g(3`+n&I1-%%+|_Hh0D&TxD?pQ>YaPXPM-syp zP>66OS_j-lPRufTul;~#L)TVabq8fIA_58#jzksU%jCq|2|U(2i;W8Y2M2%koZ&VU Q#Q*>R07*qoM6N<$f_2H*N&o-= literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..00850b21b2365bbdf445aad4c64fd0f1ba91a621 GIT binary patch literal 790 zcmV+x1L^#UP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOJ^ z1}hI87o~Xs00NdtL_t(I%e9q1NE=Zc$G`9Hyhrm#FUncmDz*^BxJaQ6iUbE8Ts;3x zHEl}h8XVnRN+}4XbO}hWTc`%Xp%E&jG|)jPT~0a*b%>-L^wPU{@m{WjISuhHRcar6 zdBffNydU59{k=z&6#mQLuDc*yO{8xWyp;GtB$j*$VD-kp5AMBa%VaVe(P;F^jaku! zRA_H+@6+(`@MJoj4qO#1wE7sb7H>0weI6SdyE8jGEAl*#e+Ek|c^3i-6B85i=;$b~ zX&MFx2SF(XtVE>+(=3Z>7x9Xl#FF;`e3+h|4##3K?%?16j4|}|^dJ(6_!2G4!t(O6 zT^7|g!6QzS;ITe8Hy7;f?S%^kfMT(TQmNz%?(6IGwnAdb#{v~z&CkyVWLd`H;o+sl z?j~NNTCH9Nhpff84SP*d6i`aBzrTMasN*;wga80KJ3B9ff77=gC6-*>-rjyXH8mA5 zO%un*$Jgr0?(S~y93Sy(OS-N<-`w0ZDW&M>=(rZxvMm3&l|^-hw~|NseEwNH9uKs) zw?o%;06;Jp^i2gJ1eMA~3W?wC7Oo~9@jU-}WMt%)AP6uF1F|e*Yip|pz-duORK7yTUb~ycXxN!W3gC3k|Y2? zHk&;UMO`%jj*R;0|Nsy0N&N1;X0Hx$ZnYJW{-)7H~>V`G%cUcE4FR_ayP7tYy8g@-#>Ig?H_{k z{p + + + 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 0000000000000000000000000000000000000000..cc2797a46868355d9d22fba90a09bd279e25b94d GIT binary patch literal 860 zcmV-i1Ec(jP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOJ^ z1}ZSJYPkgf00P`eL_t(I%e9qHNE}xj$3HXU?rdkHyKA;cum;*gFAB-6*FEIoMM^}x z#fH^gC>Y40Q0$>3kW)@Mst8pJrh*_STGw7e4ieCchKGkEsZ{D4UDw|wmF(x&29{FN*Vh;6>FN2}_x;VdOn=oV_S~9ot<587T-PiC;ZEw4Z*F!_8QAw)wfD*evR4(;vj3=R(7nw*@RkC)Qf zBW>c>x*of(i|2VrDeJ1X6^lip(I^8014c_r%V<)`{#Z9-+qSVR3(xcLeIHd->v?_Q z`tb0OWHL#Af4?y?G4Z06ps>pY0XV#H!G78VvxEz6p+mGSR8?$@zG2tiw08&XO%O}hj-IXU6@_!xlZ z=4NzVXK``y)N!0wwle-x-Ky|?-(6l_mY+ya>F(}U0SvRf=`=zJ z9LHg6Ys)E>N|~vtsn>wgo1xqgJU500mvjMcSr(>gI=j2O>0B=NJ755EZVU1C*>pn0000 + + + 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 0000000000000000000000000000000000000000..1ebf2799c35b8ecc33475a7582759c8cfd368bf6 GIT binary patch literal 753 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOJ^ z1}ZxxxL}O{00MDIL_t(I%dM0@Yg17eho6&sdvlvpV?td@N(Z||x(NoX+D^qxLW)b^ z6dIb+tl~FtQg9JL;}QyP$yDgzAfkh~bt)tuAt@-)wkJ2|HV#eNo0>FH`@#zs&U>Eo zyYD}d$pe7Y>ZcIG<_fIS>6jpBs#Gdn1(&t8HTo3ha=8{)W8ok;Zj2dq;STU^9P%0X z(B1xVS)kOa0K5jC9J<>tM}b4*ye_qReBWnvbu|L) zO08~>1WT>LLWmCw3k!){&>7vt>QQi>2z8GAEj2ehJvM5At6L%Zf@?@ z($Z3R7_?`#S`8^B%gf7Cz!$02&0&h)OixcgSXo(#*tShH8pUr z4Y(H^>9@eUpnPM@_f~80`Y^^|jIn?l1CEb_Bi$TONIcIQ2tGPGx^xu`Y`01gQ7K~e zlnt`u + + + 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 0000000000000000000000000000000000000000..3f0c190634325816b83bb05b20d55b1219cc9bde GIT binary patch literal 819 zcmV-31I+x1P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOJ^ z1{)5wR-+sM00Of~L_t(I%dJ(-OB+EPeKWiH*ck09DrqZNya}!iB<2sONUxsaK@0V; zH_?E(_HG3+XX(A*Ni6gtv^{uPZ!MlA#U<82Z1Z7sKeMyjiwQ9%n$$k{U1nz+542$9-8? zSO|@ek0Y1MVR3OW7>!0>0)XG|2gh+8Me!Y!J^}D;Zf;JDMx*5P^c0LSoS&Z~nM?*o zM@PXJ10kKAq-{t!p6B=C@%Z!E*;zi9%YiWl0MIlIs;WYgB%Ga{!SlTC74tm*VPaw; zF+V>aR8rcf-TO^78U>Up}8lsZ^>T zzEh6lpufK#gM))^Hk(Z*5{W%UQHpnn*VfkF2!illmgT;3xr~d83%IU(Z&fN4OioUc zfq{WwHk)0VnVH#F6y;BY_$I3#Wmy)&;V@24PC6=WF59+IEEX|6JxxNPP(W4HrC2QX z>FDU_H%X;ZlIM9p06-7~tgNiy`1ttVi)m>NNRou@?QPU*wfeHe>$?6k7z_>pfMFOV z(=<`5)f!272pq?ue#Y~>Apl^E+5FDVjt)S-@foIR!m=#5uG + + + 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 0000000000000000000000000000000000000000..f0b1d20c677dd272e28c0364d266701a8d6c33f0 GIT binary patch literal 585 zcmeAS@N?(olHy`uVBq!ia0vp^1wfo4zyc(f*e&1#QcOwS?k)@rt9q4dtR}|LviMU z3%16aPgw0|u1HRp(^$xMOj06!7&64w-?1E7a5er9FknVVQ@QZQxb}X-29Zxv`X9>R+)3%18T?u*-%`TZk3c+ zoT^(|l*y2mnUiXzudknxpPQ + + +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 0000000000000000000000000000000000000000..94b69d1ff1ffa4bb608adfa3a9103138afa948e9 GIT binary patch literal 1941 zcmV;G2Wt3`e|LAiAKtZhXXCVqkg9}K6t&on!a#0z~$>`0JOLQMOg+8~4? zLTH@`*QpxY+0U87!_4fiy|XhrxW|=b7E7KEK&j;b5f()UpeFJ+X#AzTN zq*DjvG5A^#5xxa%eRBIAQE~=|rxH>2?Rmm)pEVf5>*wC3RH^{vQ8G9^KK^GvCVUB4 zO@8deFqw3_Khmr4?}bGM5C1x_h?XaD_qOf3>&cHk0P+A2t?S_I@gZW-2tWc+V?F)- zPqo^v! zh-@Zl777TuZL0dL{??O#sttnqg(dbqe~LoU6k(wD&%SfzPk{yW^!GodM2!N8_IQ-h z+z{(Di#&oDdegS8L!m<9>fMKTO;1=N3I=MQn~0`!pq_j@7GX5^jsF7qMq6Fk6l1wz z67e>GcnBHo-nM;rv(}Ct=fnD|FM@J6U$curLm%u24QE|MqbO&D0 z(jBO_G)l!CY?P475?}zZPU~PSH$;2F98RL-%+|hvy^aEU`v!Iq;w+GeM#GGb9AJG{ zx{mzEAVrXJ(@RSy@q(7IL>f(O8AYqFIuXYY)*Go%#hep{<%6cb-=C+KY)u%bcvRWr&#}AOSMOZ=P3IR5r-Sb%g2c(P?KJY~zKufoI*2!c#%n947ZK)uI4^Z(>;k5cS z2)K7|8Oh%=CzMZU9bxY}nG{IL-^-B-lK&@*i+Nz>#;GPiAqd=={}_z>K4{mFO?d}E z*>nog3;th_l$pP~*zmZ)1A-tvhmMU*%Dax1PJxjR)Q7kZp=zo49{V=ZEqFl7q!431 zU?0{buI{&;Cb5V)$pS!2c<(K=&UREOj|Az%A#SS^pu|)d+yl`FBoi@~^F_zN#cbOjX1$^SnJ%Y`TGOcHLfR zK1|-9n@1(PQ4y_Wdw-cM@=`8eCBHfizhX-{HF5Qv61Bf7;#Vau&6a(=t)9mpX)2)m z@y#f7bBEP}tqW5nj^;{Kbc?)_!PRF74SV9LYggW|MU*S>;z)(JW}0UrR$ni@Fu=x# zvkl}QUZ3Gd-+K;J*xIVP+qpPh=7%|bC3%Omd(+%#eNwkA0hn2Pl-@Mrgx92*<(D&5xRjU@X0hF?Z4oC7O|+4e^5$QOYfl_Y_bk;tY_8gyE;( zDzLMsg=J91P{}Q*=myZ2k;1=_;+$)fOYcQ^F&DSVduFCv5&$bR)sZm#5Dx0I3rsv;>Sbx*wyPC_xr`=>rsxJ?4(pt;DbE)I3t@GAAb`igFwEb z!_iZnoS%*bq+G-0zpf;&#QRjH9=?xR>(lSy5cGb!-0EqPBW7<#R*-i(18_s2gYNoF zw(rKyC@6zxrY5eQ^V=|x05C;Z8SPqL)x5EDANKxF%*V9=$*`YUb(PL*LCBld|Nn25 bPZs|H#;b>oGr_WA00000NkvXXu0mjf4Fj}+ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..0ead5af8bb8848a33500be3d5124c19a424bb7c8 GIT binary patch literal 25365 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 z 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 JQLhG#_&=c>l)wN0 literal 0 HcmV?d00001 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);