├── .gitignore ├── Dockerfile ├── LICENSE ├── README.en.md ├── README.md ├── allinone ├── Dockerfile ├── docker-compose.yml ├── entrypoint.sh ├── webvirtcloud_rsa └── webvirtcloud_rsa.pub ├── docker-compose.yml ├── entrypoint.sh ├── init.sh ├── kvm_server.sh ├── settings.py ├── web ├── Dockerfile ├── nginx.conf └── webvirtcloud-nginx.conf ├── wvc_rsa └── wvc_rsa.pub /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | MAINTAINER Ken Lee "kenmlee@163.com" 3 | 4 | ENV REFRESHED_AT 2016-05-11 5 | 6 | RUN apt-get -qq update \ 7 | && apt-get upgrade -y \ 8 | && apt-get install -y \ 9 | git \ 10 | python-pip \ 11 | python-virtualenv \ 12 | python-dev \ 13 | postgresql-client \ 14 | libpq-dev \ 15 | libvirt-dev \ 16 | libxml2-dev \ 17 | zlib1g-dev \ 18 | supervisor \ 19 | libsasl2-modules \ 20 | && git clone https://github.com/retspen/webvirtcloud.git 21 | 22 | RUN mv /webvirtcloud /srv/webvirtcloud \ 23 | && cp /srv/webvirtcloud/conf/supervisor/webvirtcloud.conf /etc/supervisor/conf.d/ \ 24 | && chown -R www-data:www-data /srv/webvirtcloud 25 | 26 | COPY settings.py /srv/webvirtcloud/webvirtcloud/settings.py 27 | 28 | RUN cd /srv/webvirtcloud \ 29 | && virtualenv venv \ 30 | && . venv/bin/activate \ 31 | && pip install --upgrade pip \ 32 | && pip install -r conf/requirements.txt \ 33 | && pip install psycopg2 \ 34 | && sed -i 's/127.0.0.1/0.0.0.0/g' /srv/webvirtcloud/gunicorn.conf.py 35 | 36 | RUN mkdir /var/www \ 37 | && mkdir /var/www/.ssh \ 38 | && touch /var/www/.ssh/config \ 39 | && echo "StrictHostKeyChecking=no" >> /var/www/.ssh/config \ 40 | && echo "UserKnownHostsFile=/dev/null" >> /var/www/.ssh/config \ 41 | && chmod 0600 /var/www/.ssh/config 42 | 43 | COPY wvc_rsa /var/www/.ssh/id_rsa 44 | COPY wvc_rsa.pub /var/www/.ssh/id_rsa.pub 45 | 46 | RUN chmod -R 0600 /var/www/.ssh/id_rsa \ 47 | && chown -R www-data:www-data /var/www 48 | 49 | EXPOSE 8000 6080 50 | VOLUME /srv/webvirtcloud 51 | 52 | COPY entrypoint.sh /entrypoint.sh 53 | COPY init.sh /init.sh 54 | 55 | RUN chmod +x /entrypoint.sh \ 56 | && chmod +x /init.sh 57 | 58 | CMD "/entrypoint.sh" 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {Ken Lee} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | # webvirtcloud in Docker 2 | ## [webvirtcloud project](https://github.com/retspen/webvirtcloud) (Thanks to Anatoliy Guskov) 3 | 4 | [中文README](README.md) 5 | 6 | - There are two type of container: 7 | > 1. all-in-one type: all components (webvirtcloud, novncd, nginx, sqlite ) are running in one container 8 | > 2. standalone type: only webvirtcloud and novncd include in the container. You need run database container ( postgres recommend ) and web container ( nginx recommend ) separately. 9 | 10 | - Pay attention to two type of server: 11 | > 1. webvirtcloud server: managing server running webvirtcloud 12 | > 2. virsh server: virtualization server running virsh environment managed by webvirtcloud 13 | 14 | -------- 15 | ## how to use allinone 16 | 1. Install [docker](https://docs.docker.com/engine/installation/#installation) on webvirtcloud server 17 | 18 | 2. Start webvirtcloud-allinone container 19 | 20 | ``` 21 | $ docker run -d --name webvirtcloud -p 80:80 -p 6080:6080 kenlee/webvirtcloud-docker:allinone 22 | ``` 23 | Or use `docker-compose`,download docker-compose from allinon folder: 24 | ``` 25 | $ docker-compose up -d 26 | ``` 27 | 28 | 3. Go to http://yourip/ 29 | 30 | 4. Add one or more virsh servers. Check how to config virsh server connection below. 31 | 32 | -------- 33 | ## How to use standalone 34 | 1. Install [docker](https://docs.docker.com/engine/installation/#installation) on webvirtcloud server 35 | 36 | 2. Use one of following 37 | - 2a. download `docker-compose.yml` from root folder and run 38 | ``` 39 | $ docker-compose up -d 40 | ``` 41 | 42 | Don't forget run initialization script as: 43 | ``` 44 | $ docker exec -i wvc /init.sh 45 | ``` 46 | 47 | 2b. If not want to use docker-compose, you can start containers one by one, **the second command only need run once** 48 | ``` 49 | $ docker run -d --name postgres \ 50 | > -e POSTGRES_PASSWORD your_postgres_password \ 51 | > postgres 52 | 53 | $ docker run -it --rm --link postgres:db \ 54 | > -e DB_PASSWORD=your_wvc_db_password \ 55 | > kenlee/webvirtcloud-docker:latest /init.sh 56 | $ docker run -d --name wvc -p 6080:6080 --link postgres:db kenlee/webvirtcloud-docker:latest 57 | $ docker run -d --name web -p 80:80 --link wvc \ 58 | > --volumes-from wvc:ro \ 59 | > kenlee/webvirtcloud-docker:web 60 | ``` 61 | 62 | The last one `kenlee/webvirtcloud-docker:web` based on official Ngnix image with webvirtcloud configuration. If you want to use offical Nginx image, you need provide your `webvirtcloud.conf` and `nginx.conf`. As: 63 | 64 | ``` 65 | $ docker run -d --name web -p 80:80 --link wvc \ 66 | > --volumes-from wvc:ro \ 67 | > -v ${PWD}/nginx.conf:/etc/nginx/nginx.conf \ 68 | > -v ${PWD}/webvirtcloud.conf:/etc/nginx/conf.d/webvirtcloud.conf \ 69 | > nginx 70 | ``` 71 | in webvirtcloud.conf, you need keep the name same as "wvc" in --link parameter. 72 | ``` 73 | server { 74 | listen 80; 75 | 76 | #server_name webvirtcloud.example.com; 77 | #access_log /var/log/nginx/webvirtcloud-access_log; 78 | 79 | location /static/ { 80 | root /srv/webvirtcloud; 81 | expires max; 82 | } 83 | 84 | location / { 85 | proxy_pass http://wvc:8000; 86 | proxy_set_header X-Real-IP $remote_addr; 87 | proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; 88 | proxy_set_header Host $host:$server_port; 89 | proxy_set_header X-Forwarded-Proto $remote_addr; 90 | proxy_connect_timeout 600; 91 | proxy_read_timeout 600; 92 | proxy_send_timeout 600; 93 | client_max_body_size 1024M; 94 | } 95 | } 96 | ``` 97 | 98 | -------- 99 | ## virsh server configuration 100 | Simply run: 101 | ``` 102 | $ wget -O - https://clck.ru/9V9fH | sudo sh 103 | ``` 104 | 105 | ## Add virsh server by webvirtcloud GUI 106 | 107 | There are 4 types of connection. The last one only for virsh and webvirtcloud running on same server. 108 | 109 | 1. TCP 110 | 111 | Add user 112 | ``` 113 | $ sudo saslpasswd2 -a libvirt ken 114 | Password: xxxxxx 115 | Again (for verification): xxxxxx 116 | ``` 117 | 118 | List users 119 | ``` 120 | $ sudo saslpasswd2 -f /etc/libvirt/passwd.db 121 | ``` 122 | 123 | Remove user 124 | ``` 125 | $ sudo saslpasswd2 -a libvirt -d ken 126 | ``` 127 | 128 | Verify the connection 129 | ``` 130 | $ virsh -c qemu+tcp://IP_address/system nodeinfo 131 | ``` 132 | 133 | [More......](https://github.com/retspen/webvirtmgr/wiki/Setup-TCP-authorization) 134 | 135 | 2. SSH 136 | 137 | You need put your private key into .ssh folder of user www-data of webvirtclud server. Then put public key to authorized_keys file in .ssh of user who can run virsh command. 138 | 139 | I have put a private key file and a public key file in allinon image just for testing. You should replace them with yours. 140 | 141 | Print public key use: 142 | ``` 143 | $ docker exec -it webvirtcloud cat /var/www/.ssh/webvirtcloud_rsa.pub 144 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7zEEPi7AeG4Luk1nP7faf8KzWmyyMXQmNf7WMZOwJP08Zp9p6QJ727w6OFgTtMbL3miljXjjV7U9TC8mQBIJ9cRZFwFZZfsifFROSYE+OUjsw6IuzUaq3krPOqM71/iKm3jHIqd9JAu5M0MnwTGjd9aVs3aXPJ68PuVmaEXgsBql+4cSu0890GBY9BoOxE6i1Pdjxw6T6ZsxRnyAzx2Q9bBCXtVngjgQhS77vNhFENKlnqL170O17lAW+xHzr+ONULtFVqOveaqdVcZNGlb6KbN3otsUq00dE6ow2jZM9q4OhA7FSzoiQRVgPlr4JNj+soG3AR9fGHh7TwrkEdRad webvirtcloud 145 | ``` 146 | 147 | or using `docker cp` 148 | ``` 149 | $ docker cp /var/www/.ssh/id_rsa.pub ./webvirtcloud_rsa.pub 150 | ``` 151 | 152 | Add content of public key file into ~/.ssh/authorized_keys. 153 | 154 | [More......](https://github.com/retspen/webvirtmgr/wiki/Setup-SSH-Authorization) 155 | 156 | 3. TLS 157 | (TBD) 158 | 159 | 4. Unix Socket 160 | 161 | You need one more option to run container to enable using Unix Socket. 162 | 163 | - For allinone: 164 | ``` 165 | $ docker run -d --name webvirtcloud -p 80:80 -p 6080:6080 \ 166 | > -v /var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock \ 167 | > kenlee/webvirtcloud-docker:allinone 168 | ``` 169 | 170 | - For standalone: 171 | ``` 172 | $ docker run -d --name wvc -p 6080:6080 --link postgres:db \ 173 | > -v /var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock \ 174 | > kenlee/webvirtcloud-docker:latest 175 | ``` 176 | 177 | If you would like use `docker-compose`, you need update your `docker-compose.yml` file. 178 | 179 | [More......](https://github.com/retspen/webvirtmgr/wiki/Setup-Local-connection) 180 | 181 | -------- 182 | Still have questions, check [wiki](https://github.com/retspen/webvirtmgr/wiki) 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webvirtcloud in Docker 2 | ## [webvirtcloud project](https://github.com/retspen/webvirtcloud) (Thanks to Anatoliy Guskov) 3 | 4 | [English README](README.en.md) 5 | 6 | >[webvirtcloud](https://github.com/retspen/webvirtcloud)是一个用来管理KVM(实际上是通过libvirt)的基于浏览器的管理界面,但是安装配置步骤较多,不太方便,这里用Docker来简化安装配置。 7 | 8 | - 两个版本: 9 | > 1. allinone模式,所有webvirtcloud, nginx, sqlite都运行于一个容器中。以下提到此模式的镜像时,称为allinone镜像。 10 | > 2. standalone模式, 每个组件单独运行在自己的容器中,包括webvirtcloud, nginx, postgresql。以下提到吃模式的镜像时,仅指用于此模式的webvirtcloud镜像,不包括nginx和postgres镜像。 11 | 12 | - 配置中经常提到两种服务器,需要区分一下: 13 | > 1. webvirtcloud服务器,用于安装运行webvirtcloud管理平台的服务器 14 | > 2. virsh服务器,运行virsh的服务器,被webvirtcloud服务器所管理的服务器 15 | 16 | -------- 17 | ## 使用allinone版本的步骤 18 | 1. 在webvirtcloud服务器上安装配置docker(略) 19 | 20 | 2. 运行webvirtcloud-allinone容器 21 | 22 | ``` 23 | $ docker run -d --name webvirtcloud -p 80:80 -p 6080:6080 kenlee/webvirtcloud-docker:allinone 24 | ``` 25 | 或者使用docker-compose,下载allinon目录下的docker-compose.yml文件,然后在同一目录下运行 26 | ``` 27 | $ docker-compose up -d 28 | ``` 29 | 30 | 3. 使用浏览器访问 http://yourip/ 31 | 32 | 4. 添加被管理的virsh服务器,不同的virsh服务器连接方式配置不同,参见下面的virsh服务器配置步骤 33 | 34 | -------- 35 | ## 使用standalone版本的步骤 36 | 1. 在webvirtcloud服务器上安装配置docker(略) 37 | 38 | 2a. 下载docker-compose.yml文件,并在同一目录下运行 39 | ``` 40 | $ docker-compose up -d 41 | ``` 42 | 这个命令会拉起webvirtcloud, nginx和postgreSQL三个容器,nginx采用基于官方镜像的kenlee/webvirtcloud-docker:wvcweb及内置配置文件,postgreSQL则采用官方镜像。 43 | 44 | 在启动后还需要执行一次初始化操作: 45 | ``` 46 | $ docker exec -i wvc /init.sh 47 | ``` 48 | 49 | 2b. 如果不想用docker-compose,则需要运行以下命令,**其中第二行是进行初始化,仅需运行一次** 50 | ``` 51 | $ docker run -d --name postgres \ 52 | > -e POSTGRES_PASSWORD your_postgres_password \ 53 | > postgres 54 | 55 | $ docker run -it --rm --link postgres:db \ 56 | > -e DB_PASSWORD=your_wvc_db_password \ 57 | > kenlee/webvirtcloud-docker:latest /init.sh 58 | $ docker run -d --name wvc -p 6080:6080 --link postgres:db kenlee/webvirtcloud-docker:latest 59 | $ docker run -d --name web -p 80:80 --link wvc \ 60 | > --volumes-from wvc:ro \ 61 | > kenlee/webvirtcloud-docker:web 62 | ``` 63 | 64 | 对于最后nginx容器,如果需要指定不同的URL,则需要修改webvirtcloud.conf配置文件,如果还需要调整其他配置,则可以传入自己的nginx.conf文件,这时可以直接使用官方的nginx镜像而不是kenlee/webvirtcloud-docker:web镜像,命令如下: 65 | 66 | ``` 67 | $ docker run -d --name web -p 80:80 --link wvc \ 68 | > --volumes-from wvc:ro \ 69 | > -v ${PWD}/nginx.conf:/etc/nginx/nginx.conf \ 70 | > -v ${PWD}/webvirtcloud.conf:/etc/nginx/conf.d/webvirtcloud.conf \ 71 | > nginx 72 | ``` 73 | 其中配置文件webvirtcloud.conf中,注意保持LINK的名称“wvc”,如果你LINK的容器名称不是"wvc",则需要做相应修改 74 | ``` 75 | server { 76 | listen 80; 77 | 78 | #server_name webvirtcloud.example.com; 79 | #access_log /var/log/nginx/webvirtcloud-access_log; 80 | 81 | location /static/ { 82 | root /srv/webvirtcloud; 83 | expires max; 84 | } 85 | 86 | location / { 87 | proxy_pass http://wvc:8000; 88 | proxy_set_header X-Real-IP $remote_addr; 89 | proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; 90 | proxy_set_header Host $host:$server_port; 91 | proxy_set_header X-Forwarded-Proto $remote_addr; 92 | proxy_connect_timeout 600; 93 | proxy_read_timeout 600; 94 | proxy_send_timeout 600; 95 | client_max_body_size 1024M; 96 | } 97 | } 98 | ``` 99 | 100 | -------- 101 | ## virsh服务器的配置 102 | 简单处理,运行 103 | ``` 104 | $ wget -O - https://clck.ru/9V9fH | sudo sh 105 | ``` 106 | 这个自动化脚本里面大致做了三件事 107 | 1. 安装软件,包括KVM, libvirt, Linux Bridge, Guestfs, supervisor,以及必要的库 108 | 2. 配置软件,安装后修改了libvirt的配置来支持多种连接方式,修改了supervisor和配置 109 | 3. 运行软件,启动libvirt服务和supervisor服务 110 | 111 | ## 从webvirtcloud服务界面配置virsh服务器的连接方式 112 | 113 | 共有4种连接方式,前三种是网络连接,需要webvirtcloud容器和被管理的virsh服务器网络。最后一种只能运行于webvirtcloud容器和被管理virsh服务器在同一服务器上的场景。 114 | 115 | 1. TCP连接 116 | virsh服务器需要配置virsh的网络访问,如果你之前按运行了virsh服务器的脚本,此配置已经生效。用户授权需要使用`saslpasswd2 -a libvirt *username*`命令。 117 | 118 | 添加用户 119 | ``` 120 | $ sudo saslpasswd2 -a libvirt ken 121 | Password: xxxxxx 122 | Again (for verification): xxxxxx 123 | ``` 124 | 125 | 列出用户 126 | ``` 127 | $ sudo saslpasswd2 -f /etc/libvirt/passwd.db 128 | ``` 129 | 130 | 删除用户 131 | ``` 132 | $ sudo saslpasswd2 -a libvirt -d ken 133 | ``` 134 | 135 | 验证连接 136 | ``` 137 | $ virsh -c qemu+tcp://IP_address/system nodeinfo 138 | ``` 139 | 140 | [更多内容......](https://github.com/retspen/webvirtmgr/wiki/Setup-TCP-authorization) 141 | 142 | 2. SSH连接 143 | 144 | SSH连接方式使用virsh服务器上的用户和证书来访问virsh服务,那么首先是用`ssh-keygen`生成证书,然后将私有证书放入webvirtcloud服务器的www-data用户的.ssh目录中,将公有证书导入virsh服务器的用于连接的用户的.ssh目录的authorized_keys文件中。 145 | 146 | 在allinone和standalone镜像中,都内置了公钥和私钥文件,以方便快速使用和测试,从安全角度考虑,你应该用自己的公钥私钥文件来替换。 147 | 148 | - 在allinone和standalone镜像中,缺省用户是www-data,私钥文件为/var/www/.ssh/id_rsa,公钥文件为/var/www/.ssh/id_rsa.pub。webvirtcloud服务器无需配置,可以通过以下命令导出公钥: 149 | 150 | ``` 151 | $ docker exec -it webvirtcloud cat /var/www/.ssh/webvirtcloud_rsa.pub 152 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7zEEPi7AeG4Luk1nP7faf8KzWmyyMXQmNf7WMZOwJP08Zp9p6QJ727w6OFgTtMbL3miljXjjV7U9TC8mQBIJ9cRZFwFZZfsifFROSYE+OUjsw6IuzUaq3krPOqM71/iKm3jHIqd9JAu5M0MnwTGjd9aVs3aXPJ68PuVmaEXgsBql+4cSu0890GBY9BoOxE6i1Pdjxw6T6ZsxRnyAzx2Q9bBCXtVngjgQhS77vNhFENKlnqL170O17lAW+xHzr+ONULtFVqOveaqdVcZNGlb6KbN3otsUq00dE6ow2jZM9q4OhA7FSzoiQRVgPlr4JNj+soG3AR9fGHh7TwrkEdRad webvirtcloud 153 | ``` 154 | 155 | 或者用docker cp命令copy处理进行处理 156 | ``` 157 | $ docker cp /var/www/.ssh/id_rsa.pub ./webvirtcloud_rsa.pub 158 | ``` 159 | 160 | 将显示的内容拷贝并添加到被管理virsh服务器的用于SSH连接(并属于libvirt组)的用户的~/.ssh/authorized_keys文件中就可以了。 161 | 162 | [更多内容......](https://github.com/retspen/webvirtmgr/wiki/Setup-SSH-Authorization) 163 | 164 | 3. TLS连接 165 | (TBD) 166 | 167 | 4. Unix Socket连接 168 | 用于连接运行webvirtcloud服务器上的virsh服务,需要在运行webvirtcloud容器时指定/var/run/libvirt/libvirt-sock文件。由于这个文件是归属于root:libvirt的,而容器内没有libvirt组,并且运行用户是www-data而不是root,在容器内需要将www-data用户加入到libvirt组中。这个操作已经由entrypoint.sh脚本自动处理了。 169 | 170 | - 对allinone镜像来说,启动容器的命令为: 171 | ``` 172 | $ docker run -d --name webvirtcloud -p 80:80 -p 6080:6080 \ 173 | > -v /var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock \ 174 | > kenlee/webvirtcloud-docker:allinone 175 | ``` 176 | 177 | - 对standalone镜像来说,启动容器的命令为: 178 | ``` 179 | $ docker run -d --name wvc -p 6080:6080 --link postgres:db \ 180 | > -v /var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock \ 181 | > kenlee/webvirtcloud-docker:latest 182 | ``` 183 | 184 | 如果你用docker-compose的方式启动,则需要相应修改docker-compose.yml文件。 185 | 186 | [更多内容......](https://github.com/retspen/webvirtmgr/wiki/Setup-Local-connection) 187 | 188 | -------- 189 | 如果对以上步骤中还有疑问,请访问[wiki](https://github.com/retspen/webvirtmgr/wiki) 190 | -------------------------------------------------------------------------------- /allinone/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | MAINTAINER Ken Lee "kenmlee@163.com" 3 | 4 | ENV REFRESHED_AT 2016-05-11 5 | 6 | RUN apt-get -qq update \ 7 | && apt-get upgrade -y \ 8 | && apt-get install -y \ 9 | git \ 10 | python-pip \ 11 | python-virtualenv \ 12 | python-dev \ 13 | libxml2-dev \ 14 | libvirt-dev \ 15 | zlib1g-dev \ 16 | supervisor \ 17 | nginx \ 18 | libsasl2-modules \ 19 | && git clone https://github.com/retspen/webvirtcloud.git 20 | 21 | RUN cd webvirtcloud \ 22 | && cp conf/nginx/webvirtcloud.conf /etc/nginx/conf.d/ \ 23 | && cp conf/supervisor/webvirtcloud.conf /etc/supervisor/conf.d/ \ 24 | && cd .. \ 25 | && mv webvirtcloud /srv \ 26 | && cd /srv/webvirtcloud \ 27 | && virtualenv venv \ 28 | && . venv/bin/activate \ 29 | && pip install --upgrade pip \ 30 | && pip install -r conf/requirements.txt \ 31 | && python manage.py migrate \ 32 | && rm /etc/nginx/sites-enabled/default \ 33 | && chown -R www-data:www-data /srv/webvirtcloud 34 | 35 | RUN mkdir /var/www \ 36 | && mkdir /var/www/.ssh \ 37 | && touch /var/www/.ssh/config \ 38 | && echo "StrictHostKeyChecking=no" >> /var/www/.ssh/config \ 39 | && echo "UserKnownHostsFile=/dev/null" >> /var/www/.ssh/config \ 40 | && chmod 0600 /var/www/.ssh/config 41 | 42 | COPY webvirtcloud_rsa /var/www/.ssh/id_rsa 43 | COPY webvirtcloud_rsa.pub /var/www/.ssh/id_rsa.pub 44 | RUN chmod -R 0600 /var/www/.ssh/id_rsa \ 45 | && chown -R www-data:www-data /var/www 46 | 47 | EXPOSE 80 6080 48 | 49 | COPY entrypoint.sh /entrypoint.sh 50 | RUN chmod +x /entrypoint.sh 51 | ENTRYPOINT "/entrypoint.sh" 52 | -------------------------------------------------------------------------------- /allinone/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | webvirtcloud: 4 | ports: 5 | - "80:80" 6 | - "6080:6080" 7 | image: kenlee/webvirtcloud-docker:allinone 8 | -------------------------------------------------------------------------------- /allinone/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # check /var/run/libvirt/libvirt-sock 6 | if [ -a "/var/run/libvirt/libvirt-sock" ]; then 7 | GID=`ls -l /var/run/libvirt/libvirt-sock | awk '{print $4}'` 8 | if [ ${GID} != "libvirtd" ]; then 9 | addgroup --gid ${GID} libvirtd 10 | fi 11 | usermod -a -G libvirtd www-data 12 | fi 13 | 14 | /usr/bin/supervisord -c /etc/supervisor/supervisord.conf 15 | 16 | echo "daemon off;" >> /etc/nginx/nginx.conf 17 | 18 | /usr/bin/service nginx start 19 | -------------------------------------------------------------------------------- /allinone/webvirtcloud_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEAu8xBD4uwHhuC7pNZz+32n/Cs1pssjF0JjX+1jGTsCT9PGafa 3 | ekCe9u8OjhYE7TGy95opY1441e1PUwvJkASCfXEWRcBWWX7InxUTkmBPjlI7MOiL 4 | s1Gqt5KzzqjO9f4ipt4xyKnfSQLuTNDJ8Exo3fWlbN2lzyevD7lZmhF4LAapfuHE 5 | rtPPdBgWPQaDsROotT3Y8cOk+mbMUZ8gM8dkPWwQl7VZ4I4EIUu+7zYRRDSpZ6i9 6 | e9Dte5QFvsR86/jjVC7RVajr3mqnVXGTRpW+imzd6LbFKtNHROqMNo2TPauDoQOx 7 | Us6IkEVYD5a+CTY/rKBtwEfXxh4e08K5BHUWnQIDAQABAoIBAG+jUX3bTVvogOIw 8 | aDCKRpT3rtd4sXfTiu054QPPrt0kbHJU7TTFm3oxzFY80rrqU3iLhVUT2veZNhGp 9 | LS5W7/eANXxLhUl4a+zdy5+1bzWsvpEpfHqh7rloFUmh4j4r0A+ggLnH+fteKaky 10 | aQlXcvOXprpb3MiTz6aqSZCkF+sbGEtXupQTjEqLZaVZlFYLSWuJlpuhK1fSxkGK 11 | NYQY5czqBH6/NaMPA6MQ4XLjdnG+vu4WiQfaAbANoXZTqcoZbNOmvA9XPa0MjqLo 12 | 3xX/mvDabmS1s/8ob7+pdzdjz6hUPW6hNRA0ODbjBp1bEUwKR/CvexQ+6yALJM8r 13 | +y0XHMUCgYEA9lwdF8ZP4Lj4jhgSy3CixUesLg63QgybOWTK4Dtp19pk8Qxkxm46 14 | lCAA6zh6CdGvPsbqOthnLK0srRIW6PIOJGMo2a0yJksfa1CpjfIR/sgBn7HtN5hG 15 | wkvM12d6BgJTf0JXdoVuISJEvvIAo1VKr8/JDs8mIcy8au4hI3kjlW8CgYEAwyWA 16 | bEA0ZQWMaYZsx47eU1VeMHRUDNDbD6/TzXzuzs0f4vzAhhRSxp30dfkpUpDWq1Bk 17 | C+JtyMG9QJyccKibGw9bpGPExQIjg8cR05GYHp2UUsfE+0US513k66AN1agU4fOj 18 | 08/l4oEHyJNSPBApA6GForeVMaQMeklwjIqdBrMCgYEA3Wc3NjChhOJ3bqwv5+mY 19 | PxgEo3fSNmfB8LimoxKCMt0xLnjm8HYL6yc/7CVbeAucJRz7UFs/jiUsK3ZAZKV1 20 | FDqRcd93XHbTC8z4NHtCtOjmnLB48ifGH8OjmkqCnXfltk7W78tGiDyV78zpyeBT 21 | OOHSXZ7JNEMdajQMUCcEVb0CgYEAp648qEeO/dMDsNTx+ZNYlDCBa485fX2lDdie 22 | XS5hoM7+/DMEVvF1ovaszQYYrLqJytCb9t5MSTm4HaG0htVJ2bmbnCiiNko9LAlM 23 | 1wd+t6fdgDfpmaLjuGykvJZd7N2te+23MtSsCrGmd4GnIrccFuOeiY/Hocz9b8JU 24 | 9F5SySMCgYEA6LXLGDsWMmbVgnDE5jUpt0obbMRh+/gvX4EZYk9iBeHCK6xlCYBL 25 | DUGfzYfDPrLPewicnjqbi7/ow/rOzmH1oKLI1AXz28aHtupaberolJyy+qYdSDqL 26 | qkQsJ44v/ZseJTXfB+5SIuGPM9EVvDHhwo452NtSSDtU1AON4BTBBP0= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /allinone/webvirtcloud_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7zEEPi7AeG4Luk1nP7faf8KzWmyyMXQmNf7WMZOwJP08Zp9p6QJ727w6OFgTtMbL3miljXjjV7U9TC8mQBIJ9cRZFwFZZfsifFROSYE+OUjsw6IuzUaq3krPOqM71/iKm3jHIqd9JAu5M0MnwTGjd9aVs3aXPJ68PuVmaEXgsBql+4cSu0890GBY9BoOxE6i1Pdjxw6T6ZsxRnyAzx2Q9bBCXtVngjgQhS77vNhFENKlnqL170O17lAW+xHzr+ONULtFVqOveaqdVcZNGlb6KbN3otsUq00dE6ow2jZM9q4OhA7FSzoiQRVgPlr4JNj+soG3AR9fGHh7TwrkEdRad webvirtcloud 2 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | db: 4 | environment: 5 | POSTGRES_PASSWORD: 'wvcpasswd' 6 | image: postgres 7 | container_name: db 8 | wvc: 9 | depends_on: 10 | - db 11 | ports: 12 | - "6080:6080" 13 | volumes: 14 | - /srv/webvirtcloud-docker 15 | environment: 16 | DB_PASSWORD: 'wvcpasswd' 17 | links: 18 | - db 19 | image: kenlee/webvirtcloud-docker:latest 20 | container_name: wvc 21 | web: 22 | depends_on: 23 | - wvc 24 | ports: 25 | - "80:80" 26 | volumes_from: 27 | - wvc:ro 28 | links: 29 | - wvc 30 | image: kenlee/webvirtcloud-docker:web 31 | container_name: web 32 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # check /var/run/libvirt/libvirt-sock 6 | if [ -a "/var/run/libvirt/libvirt-sock" ]; then 7 | GID=`ls -l /var/run/libvirt/libvirt-sock | awk '{print $4}'` 8 | if [ ${GID} != "libvirtd" ]; then 9 | addgroup --gid ${GID} libvirtd 10 | fi 11 | usermod -a -G libvirtd www-data 12 | fi 13 | 14 | /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf 15 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | username=postgres 3 | 4 | if [ $DB_ENV_POSTGRES_USER ]; then 5 | username=$DB_ENV_POSTGRES_USER 6 | fi 7 | 8 | if [ $DB_ENV_POSTGRES_PASSWORD ]; then 9 | password=$DB_ENV_POSTGRES_PASSWORD 10 | elif [ $DB_PASSWORD ]; then 11 | password=$DB_PASSWORD 12 | else 13 | echo "You need set env DB_PASSWORD" 14 | exit 1 15 | fi 16 | 17 | # echo "username:"$username 18 | # echo "password:"$password 19 | 20 | # update password field in setttings.py 21 | set -i "s/wvcpasswd/$password/g" /srv/webvirtcloud/webvirtcloud/setttings.py 22 | 23 | # create database 24 | psql -v ON_ERROR_STOP=1 -d postgres://$username:$password@db <<-EOSQL 25 | CREATE USER wvc WITH PASSWORD '${password}'; 26 | CREATE DATABASE wvc; 27 | GRANT ALL PRIVILEGES ON DATABASE wvc TO wvc; 28 | EOSQL 29 | 30 | cd /srv/webvirtcloud 31 | source venv/bin/activate 32 | 33 | # A bug in migration "0002" of App logs. 34 | # I worked out a workaround 35 | sed -i 's/AddField/AlterField/g' logs/migrations/0002_auto_20150316_1420.py 36 | 37 | # due some bug in Django 1.8. We must run "migrate auth" first otherwise 38 | # contenttypes will failed sometime when try to migration. 39 | python manage.py migrate auth 40 | 41 | python manage.py migrate 42 | -------------------------------------------------------------------------------- /kvm_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh - 2 | #=============================================================================== 3 | # vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=81 4 | #=============================================================================== 5 | # 6 | # FILE: libvirt-bootstrap.sh 7 | # 8 | # DESCRIPTION: Bootstrap webvirtmgr installation for various distributions 9 | # 10 | # BUGS: https://github.com/retspen/webvirtmgr/issues 11 | # 12 | # COPYRIGHT: (c) 2015 by the WebVirtMgr Team 13 | # 14 | # LICENSE: Apache 2.0 15 | # ORGANIZATION: WebVirtMgr (webvirtmgr.net) 16 | # CREATED: 11/11/2013 11:00:00 EET 17 | #=============================================================================== 18 | 19 | #--- FUNCTION ---------------------------------------------------------------- 20 | # NAME: echoerr 21 | # DESCRIPTION: Echo errors to stderr. 22 | #------------------------------------------------------------------------------- 23 | echoerror() { 24 | printf "${RC} * ERROR${EC}: $@\n" 1>&2; 25 | } 26 | 27 | #--- FUNCTION ---------------------------------------------------------------- 28 | # NAME: echoinfo 29 | # DESCRIPTION: Echo information to stdout. 30 | #------------------------------------------------------------------------------- 31 | echoinfo() { 32 | printf "${GC} * INFO${EC}: %s\n" "$@"; 33 | } 34 | 35 | #--- FUNCTION ---------------------------------------------------------------- 36 | # NAME: echowarn 37 | # DESCRIPTION: Echo warning informations to stdout. 38 | #------------------------------------------------------------------------------- 39 | echowarn() { 40 | printf "${YC} * WARN${EC}: %s\n" "$@"; 41 | } 42 | 43 | #--- FUNCTION ---------------------------------------------------------------- 44 | # NAME: echodebug 45 | # DESCRIPTION: Echo debug information to stdout. 46 | #------------------------------------------------------------------------------- 47 | echodebug() { 48 | if [ $_ECHO_DEBUG -eq $BS_TRUE ]; then 49 | printf "${BC} * DEBUG${EC}: %s\n" "$@"; 50 | fi 51 | } 52 | 53 | #--- FUNCTION ---------------------------------------------------------------- 54 | # NAME: __test_distro_arch 55 | # DESCRIPTION: Echo errors to stderr. 56 | #------------------------------------------------------------------------------- 57 | __test_distro_arch() { 58 | ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/') 59 | if [ "$ARCH" = 32 ]; then 60 | echoerror "32-bit Arch kernel does not support" 61 | exit 1 62 | fi 63 | } 64 | __test_distro_arch 65 | 66 | #--- FUNCTION ---------------------------------------------------------------- 67 | # NAME: __strip_duplicates 68 | # DESCRIPTION: Strip duplicate strings 69 | #------------------------------------------------------------------------------- 70 | __strip_duplicates() { 71 | echo $@ | tr -s '[:space:]' '\n' | awk '!x[$0]++' 72 | } 73 | 74 | #--- FUNCTION ---------------------------------------------------------------- 75 | # NAME: __function_defined 76 | # DESCRIPTION: Checks if a function is defined within this scripts scope 77 | # PARAMETERS: function name 78 | # RETURNS: 0 or 1 as in defined or not defined 79 | #------------------------------------------------------------------------------- 80 | __function_defined() { 81 | FUNC_NAME=$1 82 | if [ "$(command -v $FUNC_NAME)x" != "x" ]; then 83 | echoinfo "Found function $FUNC_NAME" 84 | return 0 85 | fi 86 | echodebug "$FUNC_NAME not found...." 87 | return 1 88 | } 89 | 90 | #--- FUNCTION ---------------------------------------------------------------- 91 | # NAME: __parse_version_string 92 | # DESCRIPTION: Parse version strings ignoring the revision. 93 | # MAJOR.MINOR.REVISION becomes MAJOR.MINOR 94 | #------------------------------------------------------------------------------- 95 | __parse_version_string() { 96 | VERSION_STRING="$1" 97 | PARSED_VERSION=$( 98 | echo $VERSION_STRING | 99 | sed -e 's/^/#/' \ 100 | -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\).*$/\1/' \ 101 | -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \ 102 | -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \ 103 | -e 's/^#.*$//' 104 | ) 105 | echo $PARSED_VERSION 106 | } 107 | 108 | #--- FUNCTION ---------------------------------------------------------------- 109 | # NAME: __sort_release_files 110 | # DESCRIPTION: Custom sort function. Alphabetical or numerical sort is not 111 | # enough. 112 | #------------------------------------------------------------------------------- 113 | __sort_release_files() { 114 | KNOWN_RELEASE_FILES=$(echo "(arch|centos|debian|ubuntu|fedora|redhat|suse|\ 115 | mandrake|mandriva|gentoo|slackware|turbolinux|unitedlinux|lsb|system|\ 116 | os)(-|_)(release|version)" | sed -r 's:[[:space:]]::g') 117 | primary_release_files="" 118 | secondary_release_files="" 119 | # Sort know VS un-known files first 120 | for release_file in $(echo $@ | sed -r 's:[[:space:]]:\n:g' | sort --unique --ignore-case); do 121 | match=$(echo $release_file | egrep -i ${KNOWN_RELEASE_FILES}) 122 | if [ "x${match}" != "x" ]; then 123 | primary_release_files="${primary_release_files} ${release_file}" 124 | else 125 | secondary_release_files="${secondary_release_files} ${release_file}" 126 | fi 127 | done 128 | 129 | # Now let's sort by know files importance, max important goes last in the max_prio list 130 | max_prio="redhat-release centos-release" 131 | for entry in $max_prio; do 132 | if [ "x$(echo ${primary_release_files} | grep $entry)" != "x" ]; then 133 | primary_release_files=$(echo ${primary_release_files} | sed -e "s:\(.*\)\($entry\)\(.*\):\2 \1 \3:g") 134 | fi 135 | done 136 | # Now, least important goes last in the min_prio list 137 | min_prio="lsb-release" 138 | for entry in $max_prio; do 139 | if [ "x$(echo ${primary_release_files} | grep $entry)" != "x" ]; then 140 | primary_release_files=$(echo ${primary_release_files} | sed -e "s:\(.*\)\($entry\)\(.*\):\1 \3 \2:g") 141 | fi 142 | done 143 | 144 | # Echo the results collapsing multiple white-space into a single white-space 145 | echo "${primary_release_files} ${secondary_release_files}" | sed -r 's:[[:space:]]:\n:g' 146 | } 147 | 148 | #--- FUNCTION ---------------------------------------------------------------- 149 | # NAME: __gather_linux_system_info 150 | # DESCRIPTION: Discover Linux system information 151 | #------------------------------------------------------------------------------- 152 | __gather_linux_system_info() { 153 | DISTRO_NAME="" 154 | DISTRO_VERSION="" 155 | 156 | # Let's test if the lsb_release binary is available 157 | rv=$(lsb_release >/dev/null 2>&1) 158 | if [ $? -eq 0 ]; then 159 | DISTRO_NAME=$(lsb_release -si) 160 | if [ "x$(echo "$DISTRO_NAME" | grep RedHat)" != "x" ]; then 161 | # Let's convert CamelCase to Camel Case 162 | DISTRO_NAME=$(__camelcase_split "$DISTRO_NAME") 163 | fi 164 | if [ "${DISTRO_NAME}" = "openSUSE project" ]; then 165 | # lsb_release -si returns "openSUSE project" on openSUSE 12.3 166 | DISTRO_NAME="opensuse" 167 | fi 168 | if [ "${DISTRO_NAME}" = "SUSE LINUX" ]; then 169 | # lsb_release -si returns "SUSE LINUX" on SLES 11 SP3 170 | DISTRO_NAME="suse" 171 | fi 172 | rv=$(lsb_release -sr) 173 | [ "${rv}x" != "x" ] && DISTRO_VERSION=$(__parse_version_string "$rv") 174 | elif [ -f /etc/lsb-release ]; then 175 | # We don't have the lsb_release binary, though, we do have the file it parses 176 | DISTRO_NAME=$(grep DISTRIB_ID /etc/lsb-release | sed -e 's/.*=//') 177 | rv=$(grep DISTRIB_RELEASE /etc/lsb-release | sed -e 's/.*=//') 178 | [ "${rv}x" != "x" ] && DISTRO_VERSION=$(__parse_version_string "$rv") 179 | fi 180 | 181 | if [ "x$DISTRO_NAME" != "x" ] && [ "x$DISTRO_VERSION" != "x" ]; then 182 | # We already have the distribution name and version 183 | return 184 | fi 185 | 186 | for rsource in $(__sort_release_files $( 187 | cd /etc && /bin/ls *[_-]release *[_-]version 2>/dev/null | env -i sort | \ 188 | sed -e '/^redhat-release$/d' -e '/^lsb-release$/d'; \ 189 | echo redhat-release lsb-release 190 | )); do 191 | 192 | [ -L "/etc/${rsource}" ] && continue # Don't follow symlinks 193 | [ ! -f "/etc/${rsource}" ] && continue # Does not exist 194 | 195 | n=$(echo ${rsource} | sed -e 's/[_-]release$//' -e 's/[_-]version$//') 196 | rv=$( (grep VERSION /etc/${rsource}; cat /etc/${rsource}) | grep '[0-9]' | sed -e 'q' ) 197 | [ "${rv}x" = "x" ] && continue # There's no version information. Continue to next rsource 198 | v=$(__parse_version_string "$rv") 199 | case $(echo ${n} | tr '[:upper:]' '[:lower:]') in 200 | redhat ) 201 | if [ ".$(egrep 'CentOS' /etc/${rsource})" != . ]; then 202 | n="CentOS" 203 | elif [ ".$(egrep 'Red Hat Enterprise Linux' /etc/${rsource})" != . ]; then 204 | n="ed at nterprise inux" 205 | else 206 | n="ed at inux" 207 | fi 208 | ;; 209 | arch ) n="Arch Linux" ;; 210 | centos ) n="CentOS" ;; 211 | debian ) n="Debian" ;; 212 | ubuntu ) n="Ubuntu" ;; 213 | fedora ) n="Fedora" ;; 214 | suse ) n="SUSE" ;; 215 | system ) 216 | while read -r line; do 217 | [ "${n}x" != "systemx" ] && break 218 | case "$line" in 219 | *Amazon*Linux*AMI*) 220 | n="Amazon Linux AMI" 221 | break 222 | esac 223 | done < /etc/${rsource} 224 | ;; 225 | os ) 226 | nn=$(grep '^ID=' /etc/os-release | sed -e 's/^ID=\(.*\)$/\1/g') 227 | rv=$(grep '^VERSION_ID=' /etc/os-release | sed -e 's/^VERSION_ID=\(.*\)$/\1/g') 228 | [ "${rv}x" != "x" ] && v=$(__parse_version_string "$rv") || v="" 229 | case $(echo ${nn} | tr '[:upper:]' '[:lower:]') in 230 | arch ) 231 | n="Arch Linux" 232 | v="" # Arch Linux does not provide a version. 233 | ;; 234 | debian ) 235 | n="Debian" 236 | if [ "${v}x" = "x" ]; then 237 | if [ "$(cat /etc/debian_version)" = "wheezy/sid" ]; then 238 | # I've found an EC2 wheezy image which did not tell its version 239 | v=$(__parse_version_string "7.0") 240 | fi 241 | else 242 | echowarn "Unable to parse the Debian Version" 243 | fi 244 | ;; 245 | * ) 246 | n=${nn} 247 | ;; 248 | esac 249 | ;; 250 | * ) n="${n}" ; 251 | esac 252 | DISTRO_NAME=$n 253 | DISTRO_VERSION=$v 254 | break 255 | done 256 | } 257 | __gather_linux_system_info 258 | 259 | # Simplify distro name naming on functions 260 | DISTRO_NAME_L=$(echo $DISTRO_NAME | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9_ ]//g' | sed -re 's/([[:space:]])+/_/g') 261 | DISTRO_MAJOR_VERSION="$(echo $DISTRO_VERSION | sed 's/^\([0-9]*\).*/\1/g')" 262 | DISTRO_MINOR_VERSION="$(echo $DISTRO_VERSION | sed 's/^\([0-9]*\).\([0-9]*\).*/\2/g')" 263 | PREFIXED_DISTRO_MAJOR_VERSION="_${DISTRO_MAJOR_VERSION}" 264 | if [ "${PREFIXED_DISTRO_MAJOR_VERSION}" = "_" ]; then 265 | PREFIXED_DISTRO_MAJOR_VERSION="" 266 | fi 267 | PREFIXED_DISTRO_MINOR_VERSION="_${DISTRO_MINOR_VERSION}" 268 | if [ "${PREFIXED_DISTRO_MINOR_VERSION}" = "_" ]; then 269 | PREFIXED_DISTRO_MINOR_VERSION="" 270 | fi 271 | 272 | #--- FUNCTION ---------------------------------------------------------------- 273 | # NAME: __check_end_of_life_versions 274 | # DESCRIPTION: Check for end of life distribution versions 275 | #------------------------------------------------------------------------------- 276 | __check_end_of_life_versions() { 277 | 278 | case "${DISTRO_NAME_L}" in 279 | debian) 280 | # Debian versions bellow 6 are not supported 281 | if [ $DISTRO_MAJOR_VERSION -lt 6 ]; then 282 | echoerror "End of life distributions are not supported." 283 | echoerror "Please consider upgrading to the next stable. See:" 284 | echoerror " https://wiki.debian.org/DebianReleases" 285 | exit 1 286 | fi 287 | ;; 288 | 289 | ubuntu) 290 | # Ubuntu versions not supported 291 | # 292 | # < 10 293 | # = 10.10 294 | # = 11.04 295 | # = 11.10 296 | if ([ $DISTRO_MAJOR_VERSION -eq 10 ] && [ $DISTRO_MINOR_VERSION -eq 10 ]) || \ 297 | ([ $DISTRO_MAJOR_VERSION -eq 11 ] && [ $DISTRO_MINOR_VERSION -eq 04 ]) || \ 298 | ([ $DISTRO_MAJOR_VERSION -eq 11 ] && [ $DISTRO_MINOR_VERSION -eq 10 ]) || \ 299 | [ $DISTRO_MAJOR_VERSION -lt 10 ]; then 300 | echoerror "End of life distributions are not supported." 301 | echoerror "Please consider upgrading to the next stable. See:" 302 | echoerror " https://wiki.ubuntu.com/Releases" 303 | exit 1 304 | fi 305 | ;; 306 | 307 | opensuse) 308 | # openSUSE versions not supported 309 | # 310 | # <= 12.1 311 | if ([ $DISTRO_MAJOR_VERSION -eq 12 ] && [ $DISTRO_MINOR_VERSION -eq 1 ]) || [ $DISTRO_MAJOR_VERSION -lt 12 ]; then 312 | echoerror "End of life distributions are not supported." 313 | echoerror "Please consider upgrading to the next stable. See:" 314 | echoerror " http://en.opensuse.org/Lifetime" 315 | exit 1 316 | fi 317 | ;; 318 | 319 | suse) 320 | # SuSE versions not supported 321 | # 322 | # < 11 SP2 323 | SUSE_PATCHLEVEL=$(awk '/PATCHLEVEL/ {print $3}' /etc/SuSE-release ) 324 | if [ "x${SUSE_PATCHLEVEL}" = "x" ]; then 325 | SUSE_PATCHLEVEL="00" 326 | fi 327 | if ([ $DISTRO_MAJOR_VERSION -eq 11 ] && [ $SUSE_PATCHLEVEL -lt 02 ]) || [ $DISTRO_MAJOR_VERSION -lt 11 ]; then 328 | echoerror "Versions lower than SuSE 11 SP2 are not supported." 329 | echoerror "Please consider upgrading to the next stable" 330 | exit 1 331 | fi 332 | ;; 333 | 334 | fedora) 335 | # Fedora lower than 18 are no longer supported 336 | if [ $DISTRO_MAJOR_VERSION -lt 18 ]; then 337 | echoerror "End of life distributions are not supported." 338 | echoerror "Please consider upgrading to the next stable. See:" 339 | echoerror " https://fedoraproject.org/wiki/Releases" 340 | exit 1 341 | fi 342 | ;; 343 | 344 | centos) 345 | # CentOS versions lower than 5 are no longer supported 346 | if ([ $DISTRO_MAJOR_VERSION -eq 6 ] && [ $DISTRO_MINOR_VERSION -lt 3 ]) || [ $DISTRO_MAJOR_VERSION -lt 5 ]; then 347 | echoerror "End of life distributions are not supported." 348 | echoerror "Please consider upgrading to the next stable. See:" 349 | echoerror " http://wiki.centos.org/Download" 350 | exit 1 351 | fi 352 | ;; 353 | 354 | red_hat*linux) 355 | # Red Hat (Enterprise) Linux versions lower than 5 are no longer supported 356 | if ([ $DISTRO_MAJOR_VERSION -eq 6 ] && [ $DISTRO_MINOR_VERSION -lt 3 ]) || [ $DISTRO_MAJOR_VERSION -lt 5 ]; then 357 | echoerror "End of life distributions are not supported." 358 | echoerror "Please consider upgrading to the next stable. See:" 359 | echoerror " https://access.redhat.com/support/policy/updates/errata/" 360 | exit 1 361 | fi 362 | ;; 363 | 364 | *) 365 | ;; 366 | esac 367 | } 368 | # Fail soon for end of life versions 369 | __check_end_of_life_versions 370 | 371 | 372 | ############################################################################## 373 | # 374 | # CentOS Install Functions 375 | # 376 | install_centos() { 377 | if [ $DISTRO_MAJOR_VERSION -ge 6 ]; then 378 | yum -y install qemu-kvm libvirt bridge-utils python-libguestfs supervisor || return 1 379 | fi 380 | return 0 381 | } 382 | 383 | install_centos_post() { 384 | if [ -f /etc/sysconfig/libvirtd ]; then 385 | sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd 386 | else 387 | echoerror "/etc/sysconfig/libvirtd not found. Exiting..." 388 | exit 1 389 | fi 390 | if [ -f /etc/libvirt/libvirtd.conf ]; then 391 | sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf 392 | sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf 393 | sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf 394 | else 395 | echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..." 396 | exit 1 397 | fi 398 | if [ -f /etc/libvirt/qemu.conf ]; then 399 | sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf 400 | else 401 | echoerror "/etc/libvirt/qemu.conf not found. Exiting..." 402 | exit 1 403 | fi 404 | if [ $DISTRO_MAJOR_VERSION -lt 7 ]; then 405 | if [ -f /etc/supervisord.conf ]; then 406 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd 407 | chmod +x /usr/local/bin/gstfsd 408 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf >> /etc/supervisor.conf 409 | else 410 | echoerror "Supervisor not found. Exiting..." 411 | exit 1 412 | fi 413 | else 414 | if [ -f /etc/supervisord.conf ]; then 415 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd 416 | chmod +x /usr/local/bin/gstfsd 417 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf > /etc/supervisord.d/gstfsd.ini 418 | else 419 | echoerror "Supervisor not found. Exiting..." 420 | exit 1 421 | fi 422 | fi 423 | return 0 424 | } 425 | 426 | daemons_running_centos() { 427 | if [ -f /etc/init.d/libvirtd ]; then 428 | service libvirtd stop > /dev/null 2>&1 429 | service libvirtd start 430 | fi 431 | if [ -f /etc/init.d/libvirt-guests ]; then 432 | service libvirt-guests stop > /dev/null 2>&1 433 | service libvirt-guests start 434 | fi 435 | if [ -f /usr/lib/systemd/system/libvirtd.service ]; then 436 | systemctl stop libvirtd.service > /dev/null 2>&1 437 | systemctl start libvirtd.service 438 | fi 439 | if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then 440 | systemctl stop libvirt-guests.service > /dev/null 2>&1 441 | systemctl start libvirt-guests.service 442 | fi 443 | if [ -f /etc/init.d/supervisord ]; then 444 | service supervisord stop > /dev/null 2>&1 445 | service supervisord start 446 | fi 447 | if [ -f /usr/lib/systemd/system/supervisord.service ]; then 448 | systemctl stop supervisord.service > /dev/null 2>&1 449 | systemctl start supervisord.service 450 | fi 451 | return 0 452 | } 453 | # 454 | # Ended CentOS Install Functions 455 | # 456 | ############################################################################## 457 | 458 | ############################################################################## 459 | # 460 | # Fedora Install Functions 461 | # 462 | install_fedora() { 463 | yum -y install kvm libvirt bridge-utils python-libguestfs supervisor || return 1 464 | return 0 465 | } 466 | 467 | install_fedora_post() { 468 | if [ -f /etc/sysconfig/libvirtd ]; then 469 | sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd 470 | else 471 | echoerror "/etc/sysconfig/libvirtd not found. Exiting..." 472 | exit 1 473 | fi 474 | if [ -f /etc/libvirt/libvirtd.conf ]; then 475 | sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf 476 | sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf 477 | sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf 478 | else 479 | echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..." 480 | exit 1 481 | fi 482 | if [ -f /etc/libvirt/qemu.conf ]; then 483 | sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf 484 | else 485 | echoerror "/etc/libvirt/qemu.conf not found. Exiting..." 486 | exit 1 487 | fi 488 | if [ -f /etc/supervisord.conf ]; then 489 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd 490 | chmod +x /usr/local/bin/gstfsd 491 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf > /etc/supervisord.d/gstfsd.ini 492 | else 493 | echoerror "Supervisor not found. Exiting..." 494 | exit 1 495 | fi 496 | return 0 497 | } 498 | 499 | daemons_running_fedora() { 500 | if [ -f /usr/lib/systemd/system/libvirtd.service ]; then 501 | systemctl stop libvirtd.service > /dev/null 2>&1 502 | systemctl start libvirtd.service 503 | fi 504 | if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then 505 | systemctl stop libvirt-guests.service > /dev/null 2>&1 506 | systemctl start libvirt-guests.service 507 | fi 508 | if [ -f /usr/lib/systemd/system/supervisord.service ]; then 509 | systemctl stop supervisord.service > /dev/null 2>&1 510 | systemctl start supervisord.service 511 | fi 512 | return 0 513 | } 514 | # 515 | # Ended Fedora Install Functions 516 | # 517 | ############################################################################## 518 | 519 | ############################################################################## 520 | # 521 | # Opensuse Install Functions 522 | # 523 | install_opensuse() { 524 | zypper -n install -l kvm libvirt bridge-utils python-libguestfs supervisor || return 1 525 | return 0 526 | } 527 | 528 | install_opensuse_post() { 529 | if [ -f /etc/sysconfig/libvirtd ]; then 530 | sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd 531 | else 532 | echoerror "/etc/sysconfig/libvirtd not found. Exiting..." 533 | exit 1 534 | fi 535 | if [ -f /etc/libvirt/libvirtd.conf ]; then 536 | sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf 537 | sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf 538 | sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf 539 | else 540 | echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..." 541 | exit 1 542 | fi 543 | if [ -f /etc/libvirt/qemu.conf ]; then 544 | sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf 545 | else 546 | echoerror "/etc/libvirt/qemu.conf not found. Exiting..." 547 | exit 1 548 | fi 549 | if [ -f /etc/supervisord.conf ]; then 550 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd 551 | chmod +x /usr/local/bin/gstfsd 552 | curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf > /etc/supervisor.d/gstfsd.ini 553 | else 554 | echoerror "Supervisor not found. Exiting..." 555 | exit 1 556 | fi 557 | return 0 558 | } 559 | 560 | daemons_running_opensuse() { 561 | if [ -f /usr/lib/systemd/system/libvirtd.service ]; then 562 | systemctl stop libvirtd.service > /dev/null 2>&1 563 | systemctl start libvirtd.service 564 | fi 565 | if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then 566 | systemctl stop libvirt-guests.service > /dev/null 2>&1 567 | systemctl start libvirt-guests.service 568 | fi 569 | if [ -f /usr/lib/systemd/system/supervisord.service ]; then 570 | systemctl stop supervisord.service > /dev/null 2>&1 571 | systemctl start supervisord.service 572 | fi 573 | return 0 574 | } 575 | # 576 | # Ended openSUSE Install Functions 577 | # 578 | ############################################################################## 579 | 580 | ############################################################################## 581 | # 582 | # Ubuntu Install Functions 583 | # 584 | install_ubuntu() { 585 | apt-get update || return 1 586 | apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1 587 | return 0 588 | } 589 | 590 | install_ubuntu_post() { 591 | if [ -f /etc/default/libvirt-bin ]; then 592 | sed -i 's/libvirtd_opts="-d"/libvirtd_opts="-d -l"/g' /etc/default/libvirt-bin 593 | else 594 | echoerror "/etc/default/libvirt-bin not found. Exiting..." 595 | exit 1 596 | fi 597 | if [ -f /etc/libvirt/libvirtd.conf ]; then 598 | sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf 599 | sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf 600 | sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf 601 | else 602 | echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..." 603 | exit 1 604 | fi 605 | if [ -f /etc/libvirt/qemu.conf ]; then 606 | if ([ $DISTRO_MAJOR_VERSION -eq 12 ] && [ $DISTRO_MINOR_VERSION -eq 04 ]); then 607 | sed -i 's/# vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf 608 | else 609 | sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf 610 | fi 611 | else 612 | echoerror "/etc/libvirt/qemu.conf not found. Exiting..." 613 | exit 1 614 | fi 615 | if [ -f /etc/supervisor/supervisord.conf ]; then 616 | wget -O /usr/local/bin/gstfsd https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd 617 | chmod +x /usr/local/bin/gstfsd 618 | wget -O /etc/supervisor/conf.d/gstfsd.conf https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf 619 | else 620 | echoerror "Supervisor not found. Exiting..." 621 | exit 1 622 | fi 623 | return 0 624 | } 625 | 626 | daemons_running_ubuntu() { 627 | if [ -f /etc/init.d/libvirt-bin ]; then 628 | # Still in SysV init!? 629 | service libvirt-bin stop > /dev/null 2>&1 630 | service libvirt-bin start 631 | fi 632 | if [ -f /etc/init.d/supervisor ]; then 633 | # Still in SysV init!? 634 | service supervisor stop > /dev/null 2>&1 635 | service supervisor start 636 | fi 637 | return 0 638 | } 639 | # 640 | # Ended Ubuntu Install Functions 641 | # 642 | ############################################################################## 643 | 644 | ############################################################################## 645 | # 646 | # Debian Install Functions 647 | # 648 | install_debian() { 649 | apt-get update || return 1 650 | apt-get -y install qemu-kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1 651 | return 0 652 | } 653 | 654 | install_debian_post() { 655 | if [ $DISTRO_MAJOR_VERSION -ge 8 ]; then 656 | LIBVIRTSVC=libvirtd 657 | else 658 | LIBVIRTSVC=libvirt-bin 659 | fi 660 | if [ -f /etc/default/$LIBVIRTSVC ]; then 661 | if [ "$( grep -c '^libvirtd_opts *=' /etc/default/$LIBVIRTSVC )" -gt 0 ]; then 662 | if [ $( grep -c '^libvirtd_opts *=.*-l' /etc/default/$LIBVIRTSVC ) -eq 0 ]; then 663 | sed -i 's/^libvirtd_opts="\([^"]*\)"/libvirtd_opts="\1 -l"/g' /etc/default/$LIBVIRTSVC 664 | fi 665 | else 666 | sed -i 's/^#libvirtd_opts=.*$/libvirtd_opts="-l"/g' /etc/default/$LIBVIRTSVC 667 | fi 668 | else 669 | echoerror "/etc/default/$LIBVIRTSVC not found. Exiting..." 670 | exit 1 671 | fi 672 | if [ -f /etc/libvirt/libvirtd.conf ]; then 673 | sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf 674 | sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf 675 | sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf 676 | else 677 | echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..." 678 | exit 1 679 | fi 680 | if [ -f /etc/libvirt/qemu.conf ]; then 681 | sed -i 's/# vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf 682 | else 683 | echoerror "/etc/libvirt/qemu.conf not found. Exiting..." 684 | exit 1 685 | fi 686 | if [ -f /etc/supervisor/supervisord.conf ]; then 687 | wget -O /usr/local/bin/gstfsd https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd 688 | chmod +x /usr/local/bin/gstfsd 689 | wget -O /etc/supervisor/conf.d/gstfsd.conf https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf 690 | else 691 | echoerror "Supervisor not found. Exiting..." 692 | exit 1 693 | fi 694 | return 0 695 | } 696 | 697 | daemons_running_debian() { 698 | if [ $DISTRO_MAJOR_VERSION -ge 8 ]; then 699 | LIBVIRTSVC=libvirtd 700 | else 701 | LIBVIRTSVC=libvirt-bin 702 | fi 703 | if [ -f /etc/init.d/$LIBVIRTSVC ]; then 704 | /etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1 705 | /etc/init.d/$LIBVIRTSVC start 706 | fi 707 | if [ -f /etc/init.d/supervisor ]; then 708 | service supervisor stop > /dev/null 2>&1 709 | service supervisor start 710 | fi 711 | return 0 712 | } 713 | # 714 | # Ended Debian Install Functions 715 | # 716 | ############################################################################## 717 | 718 | #============================================================================= 719 | # INSTALLATION 720 | #============================================================================= 721 | # Let's get the install function 722 | INSTALL_FUNC_NAMES="install_${DISTRO_NAME_L}" 723 | 724 | INSTALL_FUNC="null" 725 | for FUNC_NAME in $(__strip_duplicates $INSTALL_FUNC_NAMES); do 726 | if __function_defined $FUNC_NAME; then 727 | INSTALL_FUNC=$FUNC_NAME 728 | break 729 | fi 730 | done 731 | echodebug "INSTALL_FUNC=${INSTALL_FUNC}" 732 | 733 | if [ $INSTALL_FUNC = "null" ]; then 734 | echoerror "No installation function found. Exiting..." 735 | exit 1 736 | else 737 | echoinfo "Running ${INSTALL_FUNC}()" 738 | $INSTALL_FUNC 739 | if [ $? -ne 0 ]; then 740 | echoerror "Failed to run ${INSTALL_FUNC}()!!!" 741 | exit 1 742 | fi 743 | fi 744 | 745 | # Let's get the post install function 746 | POST_FUNC_NAMES="install_${DISTRO_NAME_L}_post" 747 | 748 | POST_INSTALL_FUNC="null" 749 | for FUNC_NAME in $(__strip_duplicates $POST_FUNC_NAMES); do 750 | if __function_defined $FUNC_NAME; then 751 | POST_INSTALL_FUNC=$FUNC_NAME 752 | break 753 | fi 754 | done 755 | echodebug "POST_INSTALL_FUNC=${POST_INSTALL_FUNC}" 756 | 757 | if [ $POST_INSTALL_FUNC = "null" ]; then 758 | echoerror "No installation function found. Exiting..." 759 | exit 1 760 | else 761 | echoinfo "Running ${POST_INSTALL_FUNC}()" 762 | $POST_INSTALL_FUNC 763 | if [ $? -ne 0 ]; then 764 | echoerror "Failed to run ${POST_INSTALL_FUNC}()!!!" 765 | exit 1 766 | fi 767 | fi 768 | 769 | # Let's get the daemons running check function. 770 | DAEMONS_RUNNING_FUNC_NAMES="daemons_running_${DISTRO_NAME_L}" 771 | 772 | DAEMONS_RUNNING_FUNC="null" 773 | for FUNC_NAME in $(__strip_duplicates $DAEMONS_RUNNING_FUNC_NAMES); do 774 | if __function_defined $FUNC_NAME; then 775 | DAEMONS_RUNNING_FUNC=$FUNC_NAME 776 | break 777 | fi 778 | done 779 | echodebug "DAEMONS_RUNNING_FUNC=${DAEMONS_RUNNING_FUNC}" 780 | 781 | if [ $DAEMONS_RUNNING_FUNC = "null" ]; then 782 | echoerror "No installation function found. Exiting..." 783 | exit 1 784 | else 785 | echoinfo "Running ${DAEMONS_RUNNING_FUNC}()" 786 | $DAEMONS_RUNNING_FUNC 787 | if [ $? -ne 0 ]; then 788 | echoerror "Failed to run ${DAEMONS_RUNNING_FUNC}()!!!" 789 | exit 1 790 | fi 791 | fi 792 | 793 | exit 0 794 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for webvirtcloud project. 3 | 4 | """ 5 | 6 | import os 7 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 8 | 9 | SECRET_KEY = '4y(f4rfqc6f2!i8_vfuu)kav6tdv5#sc=n%o451dm+th0&3uci' 10 | 11 | DEBUG = False 12 | 13 | TEMPLATE_DEBUG = DEBUG 14 | 15 | ALLOWED_HOSTS = ['*'] 16 | 17 | INSTALLED_APPS = ( 18 | 'django.contrib.admin', 19 | 'django.contrib.auth', 20 | 'django.contrib.contenttypes', 21 | 'django.contrib.sessions', 22 | 'django.contrib.messages', 23 | 'django.contrib.staticfiles', 24 | 'computes', 25 | 'console', 26 | 'networks', 27 | 'storages', 28 | 'interfaces', 29 | 'instances', 30 | 'secrets', 31 | 'logs', 32 | 'accounts', 33 | 'create', 34 | ) 35 | 36 | MIDDLEWARE_CLASSES = ( 37 | 'django.contrib.sessions.middleware.SessionMiddleware', 38 | 'django.middleware.common.CommonMiddleware', 39 | 'django.middleware.csrf.CsrfViewMiddleware', 40 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 41 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 42 | 'django.contrib.messages.middleware.MessageMiddleware', 43 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 44 | ) 45 | 46 | ROOT_URLCONF = 'webvirtcloud.urls' 47 | 48 | WSGI_APPLICATION = 'webvirtcloud.wsgi.application' 49 | 50 | DATABASES = { 51 | 'default': { 52 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 53 | 'NAME': 'wvc', 54 | 'USER': 'wvc', 55 | 'PASSWORD': 'wvcpasswd', 56 | 'HOST': 'db', 57 | 'PORT': '5432', 58 | 'CONN_MAX_AGE': None, 59 | } 60 | } 61 | 62 | LANGUAGE_CODE = 'en-us' 63 | 64 | TIME_ZONE = 'UTC' 65 | 66 | USE_I18N = True 67 | 68 | USE_L10N = True 69 | 70 | USE_TZ = True 71 | 72 | STATIC_URL = '/static/' 73 | 74 | STATICFILES_DIRS = ( 75 | os.path.join(BASE_DIR, "static"), 76 | ) 77 | 78 | TEMPLATE_DIRS = ( 79 | os.path.join(BASE_DIR, 'templates'), 80 | ) 81 | 82 | ## WebVirtCloud settings 83 | 84 | # Wobsock port 85 | WS_PORT = 6080 86 | 87 | # Websock host 88 | WS_HOST = '0.0.0.0' 89 | 90 | # Websock public port 91 | WS_PUBLIC_HOST = None 92 | 93 | # Websock SSL connection 94 | WS_CERT = None 95 | 96 | # list of console types 97 | QEMU_CONSOLE_TYPES = ['vnc', 'spice'] 98 | 99 | # default console type 100 | QEMU_CONSOLE_DEFAULT_TYPE = 'vnc' 101 | 102 | # list taken from http://qemu.weilnetz.de/qemu-doc.html#sec_005finvocation 103 | QEMU_KEYMAPS = ['ar', 'da', 'de', 'de-ch', 'en-gb', 'en-us', 'es', 'et', 'fi', 104 | 'fo', 'fr', 'fr-be', 'fr-ca', 'fr-ch', 'hr', 'hu', 'is', 'it', 105 | 'ja', 'lt', 'lv', 'mk', 'nl', 'nl-be', 'no', 'pl', 'pt', 106 | 'pt-br', 'ru', 'sl', 'sv', 'th', 'tr'] 107 | 108 | # keepalive interval and count for libvirt connections 109 | LIBVIRT_KEEPALIVE_INTERVAL = 5 110 | LIBVIRT_KEEPALIVE_COUNT = 5 111 | -------------------------------------------------------------------------------- /web/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.10.0 2 | MAINTAINER Ken Lee "kenmlee@163.com" 3 | 4 | ENV REFRESHED_AT 2016-05-15 5 | 6 | COPY nginx.conf /etc/nginx/nginx.conf 7 | COPY webvirtcloud-nginx.conf /etc/nginx/conf.d/webvirtcloud.conf 8 | 9 | RUN rm /etc/nginx/conf.d/default.conf 10 | -------------------------------------------------------------------------------- /web/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes 4; 3 | #daemon off; 4 | 5 | error_log /var/log/nginx/error.log warn; 6 | pid /var/run/nginx.pid; 7 | 8 | 9 | events { 10 | worker_connections 1024; 11 | } 12 | 13 | 14 | http { 15 | include /etc/nginx/mime.types; 16 | default_type application/octet-stream; 17 | 18 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 19 | '$status $body_bytes_sent "$http_referer" ' 20 | '"$http_user_agent" "$http_x_forwarded_for"'; 21 | 22 | access_log /var/log/nginx/access.log main; 23 | 24 | sendfile on; 25 | #tcp_nopush on; 26 | tcp_nodelay on; 27 | types_hash_max_size 2048; 28 | #server_tokens off; 29 | 30 | keepalive_timeout 65; 31 | 32 | gzip on; 33 | gzip_disable "msie6"; 34 | 35 | include /etc/nginx/conf.d/*.conf; 36 | include /etc/nginx/sites-enabled/*; 37 | } 38 | -------------------------------------------------------------------------------- /web/webvirtcloud-nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | 4 | #server_name webvirtcloud.example.com; 5 | #access_log /var/log/nginx/webvirtcloud-access_log; 6 | 7 | location /static/ { 8 | root /srv/webvirtcloud; 9 | expires max; 10 | } 11 | 12 | location / { 13 | proxy_pass http://wvc:8000; 14 | proxy_set_header X-Real-IP $remote_addr; 15 | proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; 16 | proxy_set_header Host $host:$server_port; 17 | proxy_set_header X-Forwarded-Proto $remote_addr; 18 | proxy_connect_timeout 600; 19 | proxy_read_timeout 600; 20 | proxy_send_timeout 600; 21 | client_max_body_size 1024M; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /wvc_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAsIxAZgLzyvVoeMpyTVL8fGM/ubn06Rl4J40RKDcI1C+e2M4G 3 | gzCELwJXNQXNuCIlMU+O5FO3d9ezs+47/CK0AWeoghF3R+QKOfIPHKyklz2qN0sM 4 | Jf8fcCAUcFWevIj65zPO3BPXjkX2NjbSxm0g8Mv6anKJMbltIXc4FWufquoYChZP 5 | kCtiP0GA/up0vc1/fR9dLkGrorYcbFvH09WUxqES3Z89EA6jsoINbJLi/lwq+hub 6 | bO5mdxvEW3gsNaDBYIJPzaTNYCJXDIJhysKk3vB5q3ams07Rw5N7TxJZrPVh3ROS 7 | Dce3gUl9sDcupjEpva+1aQIQUfzt8zAgf7QiswIDAQABAoIBAGxVc8LlNuIo2vWc 8 | DK2kKajOYjE+ialr5o4mgwuxUaqamhehvN9Nqx8JiafQqt69nSL4Fc/IC0Hvy6ay 9 | nn5mcRyXlhBSVWZ46UmLXniS++COh1+snoTGW207Ui9oaqJ4T7YF1X64ckIsbhvw 10 | YkA+gMMh98TQCZ3Ikc3CUVjblLuUKojSDUeT4bHoAUExj0u8Y18diAovexxr+HDU 11 | a0FFkQBpOITvPI+dRIJdk6YPDgeVBSv1AWwABB6wOPBLQI0W7Ipi4cZNgTMK5M0L 12 | Ev5GQ9Jb7SHfrWdUmYhRQHSlxLGo2yD5Kl4s9GY9Y2/rROcnS5WVy1TW3QWZF9pb 13 | qKpc0pECgYEA5V0sj+5S4Uq5jxCAgBCcicQI/rv1p4fnJT/E3/325+zNTN9k1A/t 14 | DcLNV5DnZe9BK10koMFmbiOn7BLH99XjqZzlctSKxUBFyKI3BaT/JO+owspjQ+L/ 15 | Tr7GvNUV73Wrs8OGg1awzbSLRfPfVq+lOxZSeso+YSpaEe3tgIylaKsCgYEAxQzk 16 | g+eH6uO6LssVwJ8jOmm4KsVV1IcIWpvnB/wPLkR1haWRLDIL4KkGq3VuUBFlloOi 17 | WZv7rHrD8qkT6bA8wS5dP7YoRnEm6oDHdE2ujkKVmlycgNJsjAiBi+anpV02Ltrx 18 | D9B2IqhgbSLl1WN7pnXN2/0fh9Y5MoJz7xuavhkCgYAMIVNcAVSsyZDqugqxuy8s 19 | MgvvvO0PASb+V1MILZxDQ8jPyfjBJl55HdZSTT2PrImby39GaTQLmyMkXxHoT42M 20 | yNlxqz/zkqSeKcYTLFi6EVqxgpahXn32IizMi9BvK5/7D9orVAhhuKys9GrZYMyy 21 | RUnzaILIDL9at2SaKdYNpQKBgQC1uOEZQDHZjjCKrOGfpWMgoJSmZRx1hh5PKY3T 22 | kEITwjC7kugh4PmRM3AiOYcFMjYEq9rSVwavlvwUUpc5oT02TuLSOdREul9QTnki 23 | qe075u3+0D/IkcZnEgUelxWubBrm9STxF6eK6Mscet2IgFltNyElKvekFwzipunx 24 | 7fw0KQKBgAxJHVdJBjDb9zMq7V35/FxUjs5069MDKbQfe+DKEoLSBhD1WScMLNJP 25 | UL1P2ZIJLcH8aKHW7E0Z5XlApqL8ovA5fm8jh7QWGV90JGE3PywvearLGJ32ZfpX 26 | kjEJqHW+AFKofMwt4y/ioNBb/U7aL0f8RaMSfFdB4lQPW8/UfMQa 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /wvc_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwjEBmAvPK9Wh4ynJNUvx8Yz+5ufTpGXgnjREoNwjUL57YzgaDMIQvAlc1Bc24IiUxT47kU7d317Oz7jv8IrQBZ6iCEXdH5Ao58g8crKSXPao3Swwl/x9wIBRwVZ68iPrnM87cE9eORfY2NtLGbSDwy/pqcokxuW0hdzgVa5+q6hgKFk+QK2I/QYD+6nS9zX99H10uQauithxsW8fT1ZTGoRLdnz0QDqOygg1skuL+XCr6G5ts7mZ3G8RbeCw1oMFggk/NpM1gIlcMgmHKwqTe8HmrdqazTtHDk3tPElms9WHdE5INx7eBSX2wNy6mMSm9r7VpAhBR/O3zMCB/tCKz wvc 2 | --------------------------------------------------------------------------------